Classic Computer Magazine Archive ANTIC VOL. 2, NO. 9 / DECEMBER 1983


A smooth move, if you can make it.


You are no doubt aware of the graphics power inherent in the Atari Player/Missile system. It is frustrating, however, to know that its full potential can only be demonstraten via machine language. It is also confusing to have to keep track of all the various registers needed. Locating the P/M data into safe areas is another recurring chore each time you program.

I have always felt that the answer to these problems should be furnished by the computer itself. So, I've written a utility program (Listing 1) that automatically writes a complete subroutine for moving one or two players via machine language. Movement of the players is independent of your BASIC program. No matter how bogged down BASIC becomes, player movement remains smooth. Player zero is controlled by the joystick in Port 1 and player one by Port 2. The utility requires 24K for disk and 16K for cassette.

The utility will create a subroutine that can be merged with your BASIC program. The VBI program can be stored either as a string or in Page Six. The option of string storage is provided to allow you to store your own machine-language routines in Page Six. The VBI routine uses memory locations 1000-1015 (decimal) to store data. These locations are tucked between the printer and cassette buffers and are free. Page Zero locations 203-208 are also used.

How does Player/Missile movement stay independent of the "plodding" BASIC program? The routine is written to be executed during the TV vertical blank period. For those not familiar with this concept, a short description follows.

Every sixtieth of a second, the electron beam of a TV does a complete scan of the screen. It is then turned off and brought back to the top of the screen in preparation for another scan. The time interval during which the electron gun is off, is called vertical blank. During vertical blank, the microprocessor is diverted (via an interrupt) from the main program to perform housekeeping chores. After completing its chores, the microprocessor still has some time available before the electron gun is turned back on. The folks at Atari provided a means for machine-language programmers to tie into the processor during the vertical blank interrupt (VBI). Any graphics changes made during the VB1 are made while the screen is blank. Thus, everything changes cleanly. For further information, see pages 8-16 through 8-19 in De Re Atari.

I tried to write this utility so that it would be complete within itself. The program is self-prompting and you don't have to remember or look up any details each time you use the utility. Although this lengthens the program and increases your typing time, these features will pay for themselves each time you run the program.

The program does have limitations. The primary one is that it has no provision for missiles. Thus, without further effort, you can't simulate your favorite shoot-em-up with this utility. There are, however, numerous games requiring only player movement. In later installments I'll add missile movement and also the ability to change the player image based on the direction of movement.

The routine as written is usable for small players only. If you want to devise a screen-high player and move it around, you'll have to write your own code. The progmm limits player size to a maximum of 10 bytes. This should be sufficient for the majority of applications. The program written by this utility is not the most efficient code due to the need for generality. However, it works and does the job.

After a short introduction the program will ask for general parameters that your host BASIC program will be using. These include the graphics mode, installed RAM in your machine, etc. Then it will proceed to determine the settings of the various registers. Some comments are in order here:

1. You can set limits on the motion of each player independently. For example, you can restrict player zero to the left or top half of the screen and player one to the other half. With these limits, "never the twain shall meet." Note that you will get horizontal screen "wrap-around" if you choose the extreme limits for horizontal motion. You can also allow the players to go off-screen, while not wrapping around by a choice of suitable limits. This routine does not allow vertical wrap-around.

2. Since setting motion limits incorrectly could foul up the VBT routine, the utility checks and warns you if this has occurred.

3. The utility takes care of the always confusing fact that players move in memory opposite to the way they move on the screen. To move up on the screen, the player moves down in memory.

4. You obviously must design your player prior to using this utility. The player data is stored, within the program, as strings (P0$,P1$) in the interest of saving memory. This does make it difficult to check and edit your player data. Note that the listed representation of the string on your screen will not be correct if the string contains any keyboard editing codes. To check the data in the string, convert each character to its ATASCII value and print the number. Use a routine such as:

L = LEN(String Name):FOR X = 1 TO L:? ASC(String Name(X,X)); " , "; :NEXT X

One other problem with string representation of data is that values of 155 (ATASCII for [RETURN] and 34 (quotes) will cause errors in the string. Thus the utility checks for these and inserts a splice in the string. It then corrects the string internally by using the CHR$ function to insert the correct code. Everything will then be fine as long as you don't attempt to list the corrected string to the screen via the editor. The utility can handle up to five of each of these problem codes and will warn you if you try too many. If you need more, change lines 20, 650, 980, 1005, 1060 and 1090.

5. The utility writes three other strings to the created subroutine. The first is ZERO$ which is a machine language routine to quickly zero-out your player memory. It was taken from Bob Stewart's article in ANTIC (April, 1983). The large string, PM$, is the VBI player-mover routine. SET$ is used to enable the VBI routine.

6. You can choose to store your player data in either of two ways: beneath the display list or above a lowered RAM-TOP. In either case, the utility automatically adjusts for the RAM requirements of the various graphics modes. If you plan to change graphics modes in your program, give the utility the graphics mode with the highest RAM requirement. Otherwise you could foul up your player data. Note that, if you store your player data above RAMTOP, certain BASIC operations can erase your player. These include scrolling a text window or clearing the screen.

7. You will have a choice of two player speeds, "normal" and half-speed. You can't assign different speeds for each player. Whichever speed you choose will be used for both players.

When you have entered all your data, the utility will write your subroutine to disk under the file name "PM.LST." Delete the utility with NEW and LOAD your BASIC program. Note that your BASIC program should not have line numbers in the range of 31000-32000. Now merge your player-movernent subroutine into your BASIC program with ENTER "D:PM.LST." Finally, put a line near the start of your BASIC to GOSUB 31000. That's it! Your players will be created and can be moved to your heart's desire. Note that the subroutine establishes the graphics mode for your program. One further caution, be sure your strings and arrays are DIMensioned prior to calling this subroutine. Otherwise, an error message and computer lockup could occur.

You don't have a disk drive? No problem. Simply make the changes below and you will have a cassette-based utility.

Conversion of Program for Cassette

Change line 790 and add line 791 shown below:

790 OPEN #1,8,0,"C:"? #1;"1 DATA";:FOR I-0 TO 50:? #1;"0,";:NEXT I:? #1;"0";:? #1
791 RMTP=(8+(RAM*8))*4:IF PMST THEN 850

Note that in line 790, a "dummy" line of DATA is written. This is needed because of a bug in the Operating System. After the cassette handler is OPENed, the cassette motor will not stop running until a record is written to it. Thus the procedure for cassette is a little more tedious than with disk. Run the cassette-based utility and record the subroutine on tape. Erase the utility via NEW. Now ENTER the subroutine into the computer. Delete line 1 and then LIST the subroutine back to the cassette via LIST "C." Now LOAD your BASIC program and merge the two command.

If you wish to test the subroutine before merging it with your program, do the following:

1) ENTER it into the computer
2)Change line 32000 to: 32000 GOTO 32000

This transforms the subroutine into a stand-alone program and prevents an error message. Now RUN the program to test your player-movement routine.

The VBI routine will remain in place at all times even if you [BREAK] your program. Pressing [RESET] will disable the routine. If you wish to disable the routine under program control, use the line shown below:

POKE 54286,0: POKE 548,62:POKE 549,233:POKE 54286,64

This will disable the VBI. However, the Player/Missile system will still be enabled and the images will remain. You can disable the P/M system via BASIC in the standard manner. While debugging a program, do not RUN the program again without using [RESET] first to disable the VBI. Otherwise you could lock up the computer.

The source code for the VBI routine is given in Listing 2. As an aid to understanding the routine, I've also provided Table I. This table gives the assembly and BASIC labels for each fixed memory location used by the VBI routine. It also gives the function of each location. If you wish to change some variables in the created subroutine, without rerunning the utility, this table is for you. It will enable you to determine which POKE statement to change.

From my experience, the main problem in typing this utility will be entering the machine-language routines contained in PM$, SETS and ZEROS. Any other error in the program will generate an error message which can be used to find the problem. However, making any error in any of these strings will, with high probability, cause the computer to go "bye-bye." The resultant lockup will force you to turn the computer off and on gain to regain control. There will be no error message to help you locate the problem.

So, SAVE your program periodically as you type it in, and run TYPO on it till you get it right. Make sure you have a backup for any program with which you intend to use the routine produced by this program, because that's where any hidden problem is most likely to cause lockup.

If you've gotten this far, the toughest part is over. Find and correct any other errors in your typing and then simply RUN the utility. It is self-prompting and will guide you throughout. Prior to running the utility, you should have drawn your players and converted each byte into its corresponding decimal equivalent.

The Take-Apart on page 68 gives a line-by-line analysis of the subroutine that you will create with the main program. You can use this to customize the subroutine to your specific needs.


1. If you wish to change the initial vertical position or limits in your subroutine, you can change the values POKEd into registers 1000-1001 and 1006-1009. Since the screen motion is opposite to the movement of data in memory, use the formula below to calculate the value to POKE.

Double Line Resolution
Value to POKE=(Screen Vertical Position-127)*(-1)

Single Line Resolution
Value to POKE=(Screen Vertical Position-255)*(-1)

2. Screen position is expressed as follows:


Line Numbers
31000 Sets graphic mode, reserves areas for PM data and POKEs PMBASE
31010-31020 Specifies ZERO$ and zeroes PM area.
31030 Sets Player/Missle and color registers
31040-31070 Stores player data in strings (P0$, P1$) and loads into PM area. Also corrects strings when data values of 34 (quotes) or 155 (return) occur.
31080-31110 Loads data registers used by the VBI routine. See Listing 3.
31115-31142 The VBI routine stored as PM$. Routine is for half-speed.
31147-31149 Modifications to PM$ to allow normal speed motion.
31150 Loads VBI routine into Page Six.
31155-31160 Defines SET$ and executes routine to enable VBI.
31190 Activates the player-missle system.

Fred Pinho is a biochemical research engineer and self-taught programmer interested in BASIC and assembly language. The Atari 800 is his first computer.

Listing 1: AUTOPM.BAS Download

Listing 2: AUTOPM.ASM Download / View