To understand the graphics capabilities of the ATARI Home Computer, one must first understand the rudiments of how a television set works. Television sets use what is called a raster scan display system. An electron beam is generated at the rear of the television tube and shot toward the television screen. Along the way, it passes between sets of horizontal and vertical coils which, if energized, can deflect the beam. In this way the beam can be made to strike any point on the screen. The electronics inside the television set cause the beam to sweep across the television screen in a regular fashion. The beam's intensity can also be controlled. If you make the beam more intense, the spot in the screen that it strikes will glow brightly; if you make it less intense, the spot will glow dimly or not at all.
The beam starts at the top-left corner of the screen and traces horizontally across the screen. As it sweeps across the screen, its changes in intensity paint an image on the screen. When it reaches the right edge of the screen, it is turned off and brought back to the left side of the screen. At the same time it is moved down just a notch. It then turns back on and sweeps across the screen again. This process is repeated for a total of 262 sweeps across the screen. (There are actually 525 sweeps across the screen in an alternating system known as “interlace.” We will ignore interlace and act as if the television has only 262 lines.) These 262 lines fill the screen from top to bottom. At the bottom of the screen (after the 262nd line is drawn), the electron beam is turned off and returned to the upper left corner of the screen. Then it starts the cycle all over again. This entire cycle happens 60 times every second.
Now for some jargon: a single trace of the beam across the screen is called a horizontal scan line. A horizontal scan line is the fundamental unit of measurement of vertical distance on the screen. You state the height of an image by specifying the number of horizontal scan lines it spans. The period during which the beam returns from the right edge to the left edge is called the horizontal blank. The period during which the beam returns to the top of the screen is called the vertical blank. The entire process of drawing a screen takes 16,684 microseconds. The vertical blank period is about 1400 microseconds. The horizontal blank takes 14 microseconds. A single horizontal line takes 64 microseconds.
Most television sets are designed with “overscan”; that means they spread the image out so the picture edges are off the edge of the television tube. This guarantees that you have no unsightly borders in your television picture. It is very bad for computers, though, because screen information that is off the edge of the picture does you no good. For this reason the picture that the computer puts out must be somewhat smaller than the television can theoretically display. Therefore, only 192 horizontal scan lines are normally used by the ATARI display. Thus, the normal limit of resolution of a television set used with this computer is 192 pixels vertically.
The standard unit of horizontal distance is the color clock. You specify the width of an image by stating how many color clocks wide it is. There are 228 color clocks in a single horizontal scan line, of which a maximum of 176 are actually visible. Thus, the ultimate limit for full-color horizontal resolution with a standard color television is 176 pixels. It is possible with the ATARI Home Computer System to go even finer and control individual half-clocks. This gives a horizontal resolution of 352 pixels. However, use of this feature will produce interesting color effects known as color artifacts. Color artifacts can be a nuisance if they are not desired; they can be a boon to the programmer who desires additional color and is not fazed by their restrictions.
The fundamental problem any microcomputer has in using a raster scan television for display purposes is that the television display is a dynamic process; because of this, the television does not remember the image. Consequently, the computer must remember the screen image and constantly send a signal to the television telling it what to display. This process of sending information to the television is a continuous process and it requires full-time attention. For this reason most microcomputers have special hardware circuits that handle the television. The basic arrangement is the same on virtually all systems:
microprocessor ⇒ screen RAM ⇒ video hardware ⇒ TV screen
The microprocessor writes information to the screen RAM area that holds the screen data. The video hardware is constantly dipping into this RAM area, getting screen data that it converts into television signals. These signals go to the television which then displays the information. The screen memory is mapped onto the screen in the same order that it follows in RAM. That is, the first byte in the screen memory maps to the top-left corner of the screen, the second byte maps one position to the right, then the third, the fourth, and so on to the last byte which is mapped to the lower right corner of the screen.
The quality of the image that gets to the screen depends on two factors: the quality of the video hardware, and the quantity of screen RAM used for the display.
The simplest arrangement is that used by TRS-80 and PET. (IRS-80 is a trademark of Radio Shack Co; PET is a trademark of Commodore Business Machines.) Both of these machines allocate a specific 1K of RAM as screen memory. The video hardware circuits simply pull data out of this area, interpret it as characters (using a character set in ROM), and put the resulting characters onto the screen. Each byte represents one character, allowing a choice of 256 different characters in the character set. With 1K of screen RAM, one thousand characters can be displayed on the screen. There isn't much that can be done with this arrangement.
The Apple uses more advanced video hardware. (Apple is a trademark of Apple Computers.) Three graphics modes are provided: text, lo-resolution graphics, and hi-resolution graphics. The text graphics mode operates in much the same way that the PET and TRS-80 displays operate. In the low-resolution graphics mode, the video hardware reaches into screen memory and interprets it differently. Instead of interpreting each byte as a character, each byte is interpreted as a pair of color nybbles. The value of each nybble specifies the color of a single pixel. In the high-resolution graphics mode each bit in screen memory is mapped to a single pixel. If the bit is on, the pixel gets color in it; if the bit is off, the pixel stays dark. The situation is complicated by a variety of design nuances in the Apple, but that is the basic idea. The important idea is that the Apple has three display modes; three completely different ways of interpreting the data in screen memory. The Apple video hardware is smart enough to interpret a screen memory byte as either an 8-bit character (text mode), two 4-bit color nybbles (lo-resolution mode), or 7 individual bits for a bitmap (hi-resolution mode).
The ATARI 400/800 display list system represents a generalization of these systems. Where PET and TRS-80 have one mode and Apple has three modes, the ATARI 400/800 has 14 modes. The second important difference is that display modes can be mixed on the screen. That is, the user is not restricted to a choice between a screenful of text or a screenful of graphics. Any collection of the 14 graphics modes can be displayed on the screen. The third important difference is that the screen RAM can be located anywhere in the address space of the computer and moved around while the program is running, while the other machines use fixed-screen RAM areas.
All of this generality is made possible by a video microprocessor called ANTIC. Where the earlier systems used rather simple video circuitry, Atari designed a full-scale microprocessor just to handle the intricacies of the television display. ANTIC is a true microprocessor; it has an instruction set, a program, and data. The program for ANTIC is called the display list.
The display list specifies three things:
When using the display list, it is importcnt to shed the old view of a screen as a homogeneous image in a single mode and see it instead as a stack of modelines. A modeline is a collection of horizontal scan lines. It streches horizontally all the way across the screen. A BASIC Graphics 2 mode line is 16 horizontal scan lines high, while a BASIC Graphics 7 mode line is only two scan lines high.
Many graphics modes available from BASIC are homogeneous; an entire screen of a single mode is set up. Do not limit your imagination to this pattern; with the display list you can create any sequence of mode lines down the screen. The display list is a collection of code bytes that specify that sequence.
ANTIC'S instruction set is rather simple. There are four classes of instructions:
There are also four special options that can sometimes be specified by setting a designated bit in the ANTIC instruction. These options are:
Map mode instructions cause ANTIC to display a mode line containing pixels with solid color in them. The color displayed comes from a color register. The choice of color register is specified by the value of the screen data. In four-color map modes (BASIC modes 3, 5, and 7, and ANTIC modes 8, A, D, and E), a pair of bits is required to specify a color:
|Value of Bit Pair||Color Register Used|
Since only two bits are needed to specify one pixel, 4 pixels are encoded in each screen data byte. For example, a byte of screen data containing the value $1B would display 4 pixels; the first would be the background, the second would be color register 0, the third would be color register 1, and the fourth would be color register 2:
$1B = 00011011 = 00 01 10 11
In two-color map modes (BASIC modes 4, 6, and 8, and ANTIC modes 9, B, C, and F) each bit specifies one of two color registers. A bit value of 0 selects background color for the pixel and a bit value of 1 selects color register 0 for the pixel. Eight pixels can be stored in one screen data byte.
There are eight different map display modes. They differ in the number of colors they display (2 vs 4), the vertical size one modeline occupies (1 scan line, 2, 4, or 8), and the number of pixels that fit horizontally into one mode line (40, 80, 160, or 320). Thus, some map modes give better resolution; these will of course require more screen RAM. Figure 2-1 presents this information for all modes.
| Scan Lines|
Figure 2-1 ANTIC Mode Line Requirements
Character mode instructions cause ANTIC to display a mode line with characters in it. Each byte in screen RAM specifIes one character. There are six character display modes. Character displays are discussed in Section 3.
Blank line instructions produce blank lines with solid background color. There are eight blank line instructions; they specify skipping one through eight blank lines.
There are two jump instructIons. The first (JMP) is a direct jump; it reloads ANTIC's program counter with a new address that follows the JMP instruction as an operand. Its only function is to provide a solution to a tricky problem: ANTIC's program counter has only 10 bits of counter and 6 bits of latch and so the display list cannot cross a 1K boundary. If the display list must cross a 1K boundary then it must use a JMP instruction to hop over the boundary. Note that this means that display lists are not fully relocatable.
The second jump instruction (JVB) is more commonly used. It reloads the program counter with the value in the operand and waits for the television to perform a vertical blank. This instruction is normally used to terminate a display list by jumping back up to the top of the display list. Jumping up to the top of the display list turns it into an infinite loop; waiting for vertical blank ensures that the infinite loop is synchronized to the display cycle of the television.
Both JMP and JVB are 3-byte instructions; the first byte is the opcode, the second and third bytes are the address to jump to (low then high).
The four special options mentioned previously will be discussed in Sections 5 and 6.
The load memory scan (LMS) option must have a preliminary explanation. This option is selected by setting bit 6 of a map mode or a character mode instruction byte. When ANTIC encounters such an instruction, it loads its memory scan counter with the following two bytes. This memory scan counter tells ANTIC where the screen RAM is. It will begin fetching display data from this area.
The LMS instruction is a 3-byte instruction: 1 byte opcode followed by 2 bytes of operand. In simple display lists the LMS instruction is used only once, at the beginning of the display list. It may sometimes be necessary to use a second LMS instruction. The need arises when the screen RAM area crosses a 4K boundary. The memory scan counter has only 12 bits of counter and 4 bits of latch; thus, the display data cannot cross a 4K boundary. In this case an LMS instruction must be used to jump the memory scan counter over the boundary. Note that this means that display data is not fully relocatable. LMS instructions have wider uses which will be discussed later.
Every display list should start off with three “blank 8 lines” instructions. This is to defeat vertical overscan by bringing the beginning of the display 24 scanlines down. After this is done, the first display line should be specified. Simultaneously, the LMS should be used to tell ANTIC where it should find the screen RAM. Then follows the display list, which lists the display bytes for the mode lines on the screen. The total number of horizontal scan lines produced by the display list should always be 192 or less; ANTIC does not maintain the screen timing requirements of the television. If you give ANTIC too many scanlines to display it will do so, but the television screen will probably roll. Displaying fewer than 192 scan lines will cause no problems; indeed, it will decrease 6502 execution time by reducing the number of cycles stolen by ANTIC. The programmer must calculate the sum of the horizontal scan lines produced by the display list and verify it. The display list terminates with a JVB instruction.
Here is a typical display list for a standard BASIC Graphics mode 0 display (all values are in hexadecimal):
70 Blank 8 lines 70 Blank 8 lines 70 Blank 8 lines 42 Display ANTIC mode 2 (BASIC mode 0) 20 also, screen memory starts at 7C20 7C 02 Display ANTIC mode 2 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 41 Jump and wait for vertical blank E0 to display list which starts at 7B $7BE0
As you can see, this display list is short - only 32 bytes. Most display lists are less than 100 bytes long. Furthermore, they are quite simple in structure and easy to set up.
To implement your own display list, you must first design the display format. This is best done on paper. Layout the screen image and translate it into a sequence of mode lines. Keep track of the scan line count of your display by looking up the scan line requirements of the various modes in Figure 2-1. Translate the sequence of mode lines into a sequence of ANTIC mode bytes. Put three “blank 8 lines” bytes ($70) at the top of the list. Set bit 6 of the first display byte (that is, make the upper nybble a 4). This makes a load memory scan command. Follow with 2 bytes which specify the address of the screen RAM (low then high). Then follow with the rest of the display bytes.
At the end of your display list put in the JVB instruction ($41) and the address of the top of the display list.
Now, store all of these bytes into RAM. They can be anywhere you want; just make sure they don't overlay something else and your JVB points to the top of the display list.
The display list must not cross a 1K address boundary. If you absolutely have to cross such a boundary, insert a JMP instruction just in front of the boundary. The JMP instruction's operand is the address of the first byte on the other side of the boundary.
Next, you must turn off ANTIC for a fraction of a second while you rewrite its display list pointer. Do this by writing 0 into SDMCTL at location $22F. Then store the address of the new display list into $230 and $231 (low then high). Lastly, turn ANTIC back on with a $22 into SDMCTL. During the vertical blank, while ANTIC is quiet, the operating system (OS) will reload ANTIC's program counter with these values.
Screen memory can be placed anywhere in the address space of the computer. Normally the display list specifies the beginning of the screen memory with the first display instruction - the initial LMS instruction. However, ANTIC can execute a new LMS instruction with each display line of the display list if this is desired. In this way information from all over the address space of the computer can be displayed on a single screen. This can be of value in setting up independent text windows.
There are several restrictions in your placement of the screen memory. First, screen memory cannot cross a 4K address boundary. lf you cannot avoid crossing a 4K boundary (as would be the case in BASIC mode 8, which uses 8K of RAM) you must reload the memory scan counter with a new LMS instruction. Second, if you wish to use any of the operating system screen routines you must abide by the conventions the OS uses. This can be particularly difficult when using a modified display list in a BASIC program. If you alter a standard display list from a BASIC program and then attempt to PRINT or PLOT to the screen, the OS will do so under the assumption that the display list is unchanged. This will probably result in a garbled display.
There are three ways the display can fail when you attempt this. First, BASIC may refuse to carry out a screen operation because it is impossible to do in the graphics mode that the OS thinks it is in. The OS stores the value of the graphics mode that it thinks is on the screen in address $57. You can fool the OS into cooperating by poking a different value there. Poke the BASIC mode number, not the ANTIC mode number.
The second failure you might get arises when you mix mode lines with different screen memory byte requirements. Some mode lines require 40 bytes per line, some require 20 bytes per line, and some require only 10 bytes per line. Let's say that you insert one 20-byte mode line into a display list with 40 byte mode lines . Then you PRINT text to the display. Everything above the interloper line is fine, but below it the characters are shifted 20 spaces to the right. This is because the OS assumed that each line would require 40 bytes and positioned the characters accordingly. But ANTIC, when it encountered the interloper line, took only 20 bytes of what the OS thought should be a 40-byte line. ANTIC interpreted the other 20 bytes as belonging to the next line, and displayed them there. This resulted in the next line and all later lines being shifted 20 spaces to the right.
The only absolute way around this problem is to refrain from using BASIC PRINTs and PLOTs to output to a custom display list screen. The quick-and-dirty solution is to organize the screen into line groups that contain integer multiples of the standard byte requirement. That is, do not insert a 20-byte mode line into a 40-byte display; instead insert two 20-byte lines or one 20-byte line and two 10-byte lines . So long as you retain the proper integer multiples, the horizontal shift will be avoided.
This solution accentuates the third problem with mixed display lists and BASIC: vertical shifts. The OS positions screen material vertically by calculating the number of bytes to skip down from the top of the screen. In a standard 40-byte line display, BASIC would position the characters onto the 10th line by skipping 360 bytes from the beginning. If you have inserted four 10-byte lines, BASIC will end up three lines further down the screen than you would otherwise expect. Furthermore, different mode lines consume different numbers of scan lines, so the position on the screen will not be quite what you expected if you do not take scan line costs into account.
As you can see, mixed mode displays can be difficult to use in conjunction with the OS. Often you must fool the OS to make such displays work. To PRINT or PLOT to a mode window, POKE the BASIC mode number of that window to address $57, then POKE the address of the top-left pixel of the mode window into locations $58 and $59 (low then high). In character modes, execute a POSITION 0,0 to home the cursor to the top-left corner of the mode window. In map modes, all PLOTs and DRAWTOs will be made using the top-left corner of the mode window as the origin of the coordinate system.
The display list system can be used to produce appealing screen displays. Its most obvious use is for mixing text and graphics. For example, you could prepare a screen with a bold BASIC mode 2 title, a medium size BASIC mode 1 subtitle, and small BASIC mode 0 fine print. You could then throw in a BASIC mode 8 picture in the middle with some more text at the bottom. A good example of this technique is provided by the display in the ATARI States and Capitals program.
The aforementioned problems will discourage the extensive use of such techniques from BASIC. With assembly language routines, modified display lists are best used by organizing the screen into a series of windows, each window having its own LMS instruction and its own independent RAM area.
One simple application of display list modifications is to vertically space lines on the screen by inserting blank line bytes. This will add some vertical spacing which will highlight critical messages and enhance the readability of some displays.
Another important use of display list manipulations is in providing access to features not available from BASIC. There are three text modes supported by ANTIC that BASIC does not support. Only display list manipulations gain the user access to these modes. There are also display list interrupt and fine scrolling capabilities that are only available after the display list is modified. These features are the subjects of Sections 5 and 6.
Manipulations with the LMS instruction and its operand offer many possibilities to the creative programmer. For example, by changing the LMS during vertical blank, the programmer can alternate screen images. This can be done at slow speed to change between predrawn displays without having to redraw each one. Each display would continue to reside in (and consume) RAM even while it is not in use, but it would be available almost instantly. This technique can also be used for animation. By flipping through a sequence of displays, cyclic animation can be achieved. The program to do this would manipulate only two address bytes to display many thousands of bytes of RAM.
It is also possible to superimpose images by flipping screens at high speed. The human eye has a time resolution of about 1/16 of a second, so a program can cycle between four images, one every 1/60 of a second, so that each repeats every 1/15 of a second. In this way, up to four images can appear to reside simultaneously on the screen. Of course, there are some drawbacks to this method. First, four separate displays may well cost a lot of RAM. Second, each display image will be washed out because it only shows up one quarter of the time. This means that the background of all displays must be black, and each image must be bright. Furthermore, there will be some unpleasant screen flicker when this technique is used. A conservative programmer might consider cycling between only three or even only two images.
This technique can also be used to extend the color and luminosity resolution of the computer. By cycling between four versions of the same image, each version stressing one color or luminosity range, a wider range of colors and luminosities is available. For example, suppose you wish to display a bar of many different luminances. First set your four color registers to the values:
Now, put the following images into each of the screen RAM areas:
In this way, much finer luminance resolution is possible.
A final suggestion concerns a subject that is laden with opportunities but little understood as yet: the dynamic display list. This is a display list which the 6502 changes during vertical blank periods. It should be possible to produce interesting effects with such lists. For example, a text editing program dynamically inserts blank lines above and below the screen line being edited set it apart from the other lines of text. As the cursor is moved vertically, the display list is changed. The technique is odd but very effective.