Exploring the ATARIĀ® Frontier

ANTIC and the Display List: Part 3 by Alan J. Zett

Editor's Note: This is the third part of a series. To avoid confusion, we advise that you read the first two installments (SoftSide, May, 1982 and Issue #31) before reading this one. A solid background in BASIC, as well as some knowledge of assembly language, are also recommended.

The Beat Goes On

In the last two installments, we took our first giant step into the realm of Atari graphics. The way was made clear for us to explore the staggering potential and versatility that goes unnoticed by the BASIC programmer. We learned about the basics of the Display List and tried them out with a sample title display. We have barely scratched the surface, however. As we dig deeper and deeper into the Atari, we find a veritable gold mine of capabilities just waiting to be refined and used by intrepid programmers. This month, we are going to conclude the discussion of mixing display modes with a difficult example which will utilize all the tricks you may ever need. Take lots of notes, and forge ahead.

Beating The Odds

The true heart of Atari BASIC is not in the BASIC cartridge. The Operating System (OS) is the true software work horse of the Atari computer. It contains all of the routines to set up and use the video display and just about every other function performed by the system. Atari BASIC is nothing more than a set of systematic calls into the OS. The OS is actually a set of instructions for the microprocessor to follow. All work done by the Atari must sooner or later pass through the OS. By design, the Atari's 6502 Central Processing Unit (CPU) requires the use of the first five pages (a page is 256 bytes) of computer memory for storage. As long as OS is in the computer, important information pertaining to every aspect of the computer is constantly being updated in the lower five pages of memory. Since we are in BASIC, we can take a look at these locations to find out what any part of the computer is doing. In fact, we can also modify these locations from BASIC and fool the OS into changing its operation. Figure 1 contains a list of all the locations we will need to handle a modified Display List. Each of these locations will be explained in more detail a little later.

Figure 1: Table Of Important Memory Locations


00087$0057DINDEXCurrent GRAPHICS mode of screen.
00088$0058SAVMSCLSB of top of screen memory.
00089$0059SAVMSCMSB of top of screen memory.
00560$0230SDLSTLLSB of Display List in memory.
00561$0231SDLSTHMSB of Display List in memory.
00656$0290TXTROWCursor row in split screen text window.
00657$0291TXTCOLLSB of cursor column in split screen text window.
00658$0292TXTCOLMSB of cursor column in split screen text window.

Figure 2: Modified Display List Generated By Listing 1


466GRAPHICS 0 w/LMS option
5nnLSB of screen memory
6nnMSB of screen memory
7865Jump w/WVB option
79nnLSB of Display List
80nnMSB of Display List

The Longest Day

Take a look at Listing 1. Type it in and RUN it. For a short program, there are many complicated techniques being used. Although the display isn't very dramatic, the methods used are the tools with which masterpieces are made. At the top, there are six lines of text followed by 64 lines of GRAPHICS 7 and two more lines of text. If you look at Figure 2, you can see our custom display. The first three bytes are Blank Mode Line instructions to bring the top of the video display down 24 scan lines. Then there is a GRAPHICS 0 character mode line with the Load Memory Scan (LMS) option. Bytes five and six are the location of screen memory in LSB/ MSB order. Following that are five more lines of GRAPHICS 0, 64 lines of GRAPHICS 7, and two more bytes of GRAPHICS 0. At location byte number 78, there is a Jump instruction with the Wait Vertical Blank (WVB) option and two more bytes pointing to the start of the Display List. Pretty standard stuff. Why did I say it was difficult? Not because it has several mixed modes, but because of their type and positions!

Listing 1 : Sample program listing
10 GRAPHICS 23:DL=PEEK(560)+PEEK(561)*256+4:POKE DL-1,66:FOR X=2 TO 6:POKE DL+X,2:NEXT X:POKE 709,2
20 POKE DL+71,2:POKE DL+72,2:POKE DL+73,65:POKE DL+74,PEEK(560):POKE DL+75,PEEK(561):POKE 710,10:POKE 712,148
30 FOR Y=6 TO 69:COlOR INT((Y+5)/5):PLOT 0,Y:DRAWTO 159,Y:NEXT Y:COLOR 32:PLOT 0,0:POKE 87,0
40 ZERO1=PEEK(88)+PEEK(89)*256
50 SEVEN1=ZERO1+(6*40)
60 ZERO2=ZERO1+(70*40)
70 POKE 752,1
100 X=ZERO2:GOSUB 1000
200 X=SEVEN1:GOSUB 1000:POKE 87,7
210 COLOR 3:PLOT 79,0:DRAWTO 79,63
300 X=ZERO1:GOSUB 1000:POKE 87,0
400 END
1000 POKE 89,X/256:PLOT 0,0
1010 POKE 88,X-(256*PEEK(89))

Memory Recall

Last time I said that if a mode line is positioned where its Y coordinate is greater than what is allowed for a standard Display List of that type, certain problems arise. Also, when mixing graphics with text, a few normal procedures must be followed. The best way to cover all the reasons is to dissect the BASIC program step-by-step in conjunction with the Display List listing and the important memory locations. We'll start at the obvious place - line 10.

Anatomy Of A Program

Line 10: When making a custom Display List, we follow certain guidelines. One is to always use the graphics mode that requires the most memory as a base. We use more GRAPHICS 7 than any other, so the first statement in line 10 will be GRAPHICS 23 which is GRAPHICS 7 plus 16. This sets up a standard Display List of full screen (no text window) GRAPHICS 7. Now all we have to do is modify the existing Display List. DL will contain the calculated memory location of the Display List which is found within memory locations 560 and 561. We add four to point us to a convenient position in the Display List. (This is a matter of personal preference.) The first visible mode line will be at DL-1 and all following it will be from DL+2 on up. When we POKE DL-1,66 we are setting up a GRAPHICS 0 mode line with the LMS option. DL and DL+1 contain the location of screen memory in LSB/ MSB order. The FOR/ NEXT loop then POKEs in 5 more lines of GRAPHICS 0 at DL+2 to DL+6. The POKE to 709 simply sets a color register. It works faster than a SETCOLOR statement and takes fewer bytes of memory. (All numbers in a program require 6 bytes regardless of the number of digits.)

Line 20: POKEing DL+71 and DL+72 with 2 sets the two bottom lines of GRAPHICS 0. Since we haven't used all of the bytes of the original Display List, we have to add our own ending. POKE DL+73,65 sets the Jump mode with WVB option and PEEKs to 560 and 561 locate the start of the Display List. POKEs to 710 and 712 also set color registers.

Line 30: The modifications to the Display List are completed . All that remains is to demonstrate how to use it. Location 87 still contains a 7 from when we first built the Display List with a GRAPHICS 23 statement in line 10. As long as location 87 contains the graphics mode in which we currently wish to PLOT, and the Y coordinates are all less than or equal to the normal screen limit when used from BASIC, all we have to do is skip over the non-graphic lines at the begining. Since there are six lines of text at the top, numbered from zero to five, the GRAPHICS 7 lines start at 6 and continue for 64 lines. All the FOR/NEXT loop does is PLOT graphics in four colors onto the GRAPHICS 7 screen. The remainder of the line exists to fix a problem associated with mixed text and graphics. If we were to go back to the text line and print something, the byte at the last location of the cursor in the graphics lines would be set to the background color. This puts an annoying blue bar on our graphics display. To get around that, we first set the color to 32 (a space character). A little known feature is that you can PLOT text in the text modes. If you set the COLOR to the ASCII character you wish to use and then PLOT X, Y, the character will appear at that location. When we set the COLOR to a space and PLOT 0,0 we will, in effect, position and PLOT on the graphics screen. But since the first line is a text line, a space is printed instead. Memory location 87 contains the current screen graphics mode which was set at 7 when the GRAPHICS 23 command was executed. By POKEing it with 0, we fool the OS into thinking we are now in GRAPHICS 0. It is now safe to simply PRINT on the top lines of text. The problem that causes the discoloration on the screen has been eliminated because OS thinks that the background color is an ASCII space which is invisible to the text display. Now comes the tricky part.

Lines 40-60: If we POKE 87,0 to make it think we are in GRAPHICS 0, we find that the X and Y locations of the bottom text lines start at 0,70. In GRAPHICS 0, POSITION 0,70 would generate a cursor out of range error. (The Y coordinate maximum for GRAPHICS 0 is 23.) To get around this, we have to fool the OS into thinking that the bottom two lines of text are actually the first two lines of the screen. Lines 40-60 calculate the actual top left memory location for each of the three mode line divisions. They are calculated by adding the start of screen memory in locations 88 and 89 to the number of mode lines down to the start of the division multiplied by the number of bytes required for each mode line. In this case, every mode line requires 40 bytes, both text and graphics. ZERO1 is set to the top of the screen. (We'll need this for later.) SEVEN1 is set to the top of the GRAPHICS 7 segment and ZERO2 is set to the top of the second set of GRAPHICS 0 text lines.

Line 70: Disables the text cursor block.

Line 100: Call a routine to set the top of screen memory to the top of the second GRAPHICS 0 text lines. POKEing 87,0 tell OS to function as in GRAPHICS 0.

Line 110: POSITION to new top of screen and PRINT hello. Remember, OS now thinks that the two lines at the bottom are the FIRST two lines in a screen of 24. DO NOT PRINT anything past Y location 1 or OS will overwrite the screen.

Line 200: Set top of screen to top of GRAPHICS 7 window. POKE 87,7 to make OS work in GRAPHICS 7.

Line 210: Select a COLOR and PLOT.

Line 300: Restore top of screen memory to its original position.

Line 310-400: PRINT hello and stop while still in GRAPHICS 0 mode.

Line 1000: POKE the MSB of the new top of screen memory into the pointer at location 89. Put the cursor at the top left corner.

Line 1010-1020: POKE the LSB of the new top of screen mem into pointer at location 88 and RETURN.

Time Out!

Whew! That certainly was a lot of material! Note that we didn't really have to set a new top of screen for the line we drew in lines 200-210. This is merely a different technique for doing the same thing we did in line 30. All you need to do, if you find yourself trying to write to a line beyond its normal Y coordinate range, is to use the routines presented here to set the top of screen. Note that these POKEs must be done each time you wish to write there. Also note that in our case, the number of screen bytes per mode line is always 40. If you must mix modes of different byte lengths, remember to use the technique described in the last column and adjust your memory position calculations accordingly (e.g. lines 40-60 in our demo). There is much you can do now by just experimenting. Since the program ENDs in GRAPHICS 0, you can type or do anything to the screen you like. An interesting effect can be achieved by playing with the cursor editing keys. Experiment! Modify the program however you please. If you come up with anything interesting, let us know so we can share it with a ll of our readers. Next time, we will get down to the nitty-gritty world of Display List Interrupts. BASIC programmers take note: this area requires an understanding of 6502 Machine Language (albeit only the basics). Now is a good time to buy that book you've been eyeing at your local computer store! That's it for this time. I'm anxious to hear from SoftSide readers who have comments or advice they would like to share.