Start Interrupting
by Marian Lorenz and Allan Moose
The Display List Interrupt (DLI) is a capability built into the ATARI that will help you create some of the spectacular graphics effects for which it is famous. DLIs are machine language subroutines that can be called from BASIC. Learning to use DLIs also serves as a gentle introduction to Assembly Language programming. This article describes DLI routines that put more color onto the screen.
In order to understand what a DLI does, it is necessary to know how the ATARI handles screen displays. Unlike other microcomputers, the ATARI uses several microprocessors. One is the Central Processor Unit (CPU), the 6502, which is primarily responsible for implementing programs and performing computations. Another is ANTIC, the microprocessor that controls the screen display. The program for ANTIC is called a Display List. A Display List is either invoked by a BASIC Graphics command or can be defined by the programmer. The Display List tells ANTIC where screen data is located, which display model to use, and whether special display options are to be implemented.
A Display List Interrupt is exactly what the name implies--an interrupt instruction put into a Display List. It is an instruction to ANTIC to interrupt the CPU's normal program. Once stopped by ANTIC, the CPU will carry out your DLI service routine and then return to its normal business. This option is available in any of the ANTIC character, graphic or blank mode lines and may be used along with Player/Missile graphics, character sets or color. With a DLI you can make changes in the screen image at precisely timed intervals.
To understand this article better, type in Program 1 and run it. We used a DLI to change the background color in Graphics 0 from blue to yellow, half-way down the screen. This simple example illustrates one application of the DLI -using the sequential nature of the TV image. You can divide the screen into sections, each with its own set of colors, and thereby increase the number of available colors in each Graphics Mode.
Program 1
5 ? CHR$(125):GRAPHICS 0 10 DL=PEEK(560)+PEEK(561)*256:POKE DL+16,130 20 FOR J=0 TO 10:READ B:POKE 1536+J,B:NEXT J 25 DATA 72,169,42,141,10,212,141,24,208,104,64 30 POKE 512,0:POKE 513,6 35 POKE 54286,192 40 GOTO 40
The steps for composing a DLI routine in BASIC are:
(1) Plan your display.
(2) Insert the interrupt instruction into the Display List.
(3) Write the DLI service routine.
(4) Put in the instructions that will allow the routine to be carried out.
Now examine Program 1 in detail. The change in the display (step 1) is simple--we will alter the background color of a Graphics 0 display half-way down the screen. To better understand step 2, refer to Table 1, which is a Graphics 0 Display List. There are 24 Graphics 0 mode line instructions: byte 3 (which is also a load memory scan instruction), and bytes 6 through 28. (For more information on Display Lists, see our article in ANTIC #6). We will put our DLI instruction at byte 16, the twelfth Graphics 0 mode line. The interrupt instruction is the ANTIC mode number plus 128. The color change will occur at the next mode line. This is a general rule--the change you are making will occur at the mode line following the DLI instruction. Thus, line 5 of Program 1 clears the screen and calls for a Graphics 0 display. Line 10 finds the starting address of the Display List and then POKEs the value 130 into the proper memory location.
We are now ready to write the service routine (step 3). Before we get into the details of 6502 registers and instructions it is important to note that a Display List service subroutine for the CPU must be short. The reason is that the data for the color changes must be put in place during the horizontal blank. The horizontal blank is the time that the electron beam is turned off as it returns from the right side to the left side of the TV screen. In this relatively short interval, there is just enough time to make three color changes. In this program we make one color change. In Program 2 we illustrate how to make three color changes.
Recall that the function of the 6502 is to manipulate data in the form of 8-bit bytes. Three registers are used to hold this data: the accumulator, the X-register, and the Yregister. The accumulator is the primary register, because it has the greatest variety of commands available for data manipulation. The instructions to the accumulator, and the X and Y registers are also 8-bit binary numbers. As an example, 10101001 is the instruction to load the accumulator with the number immediately following. Since people have trouble remembering long binary numbers, instructions are given three-letter codes called mnemonics. For instance, the mnemonic for "load the accumulator" is LDA. When you write a program using mnemonics, it is called Assembly Language programming.
The nice part about learning the rudiments of Assembly Language programming through DLIs is that you need only to concern yourself with a simple form of addressing called the immediate mode.
In immediate mode, the mnemonic always precedes its data. Table 2 gives a list of Assembly Language commands useful in writing DLI routines and their corresponding numerical codes.
The following is the procedure for constructing the DLI routine used in Program 1:
STEP 1
Save the value that is in the accumulator. This value must be saved because it is part of the program that the CPU was executing before the interrupt. The place to store this value is the stack. The stack is a special area of memory that operates on a last-in-first-out basis. The mnemonic PHA stores the contents of the accumulator on the stack.
STEP 2
Load the accumulator with the numeric value corresponding to the color yellow. The command to do this is LDA followed by 42 (decimal).
STEP 3
Tell the 6502 to wait for the horizontal blank. This insures that the color change starts at the left side of the screen and will be clear and sharp. The command to do this is STA WSYNC. WSYNC stands for the address 54282. This address must be presented to the CPU in two bytes. The first byte is called the low byte and is the remainder (not quotient) of the address divided by 256. The high byte is the quotient. For example, the LO-byte Hl-byte form of WSYNC is 10, 212.
STEP 4
Take the color value (42), still in the accumulator, and store it in the GTIA register at memory location S3272. The instruction for this is STA 24, 208. (24 = LO-Byte; 208 = HlByte of 53272).
STEP 5
Recall the original accumulator contents from the stack. This command is PLA.
STEP 6
Return from the interrupt routine. The command is RTI.
In Assembly Language mnemonics this program can be written compactly as: | Since our BASIC program can't understand mnemonics they must be translated into decimal: |
PHA | 72 |
LDA | 169,42 |
STA WSYNC | 141,10,212 |
STA ADDR | 141,24,208 |
PLA | 104 |
RTI | 64 |
The decimal values of the Assembly Language program are put into the BASIC program as DATA in line 25. The previous line, line 20, writes this subroutine at the start of Page Six, i.e. memory location 1536 and following.
Finally, in order for the DLI routine to be executed, we must do two things. We must store the starting address (1536) of the DLI routine for the CPU in memory locations 512 (LO-Byte) and 513 (Hl-Byte). Then the Display List Interrupt must be "enabled". Line 30 takes care of the first task. Line 35 takes care of the second. It is important to know that when ANTIC encounters a DLI instruction in the Display List, it will check to see if the enabling value 192 has been stored at 54286. If not, the DLI instruction will be ignored. Furthermore, in the BASIC program, the enabling instruction POKE 54286,192 must come after the DLI routine is read into memory. Otherwise your program will crash.
Since we are using Display List Interrupts to make color changes, a little color information might be helpful. The ATARI has two sets of color registers: the hardware registers and their corresponding shadow registers. We have listed the registers and their addresses in Table 3. The hardware registers are used by GTIA to determine the colors to be put on the screen. During the vertical blank the OS reads the values in each shadow register and writes them into the appropriate hardware register. Now you can see why Program 1 splits the screen into two colors. We changed the hardware register from blue to yellow with the DLI. However, the value in the shadow register is still blue, so during the vertical blank the OS changes the color value of the hardware register back to blue.
Program 1 makes a single color change at a single location on the screen. There are two good ways to build on this simple program. One way is to cause up to three color changes in one interrupt routine. A second way is to use multiple DLI routines. Program 2 illustrates how to make three color changes with one interrupt routine by using the accumulator, the X-register, and the Y-register. In this program we change the foreground, background, and border colors half-way down the screen.
The Assembly Language program to accomplish these changes is:
STEP I: Save the accumulator, the X-register and the Y-register
onto the stack.
MNEMONIC | DECIMAL VALUE |
FUNCTION |
PHA | 72 | save accumulator |
TXA | 138 | transfer X to accumulator |
PHA | 72 | save accumulator |
TYA | 152 | transfer Y to accumulator |
PHA | 72 | save accumulator |
STEP II: load register.
LDA | 169, 42 | load accumulator with yellow |
LDX | 162,192 | load X with dark green |
LDY | 160, 92 | load Y with pink |
STEP III: Wait for horizontal blank. Store colors.
STA WYSNC | 141,10,212 | wait for horizontal blank |
STA COLOR1 | 141,24,208 | yellow to background register |
STX COLOR2 | 142,23,208 | dark green to foreground |
STY COLOR3 | 140,26,208 | pink to border register |
STEP IV: Restore the accumulator, X and Y registers.
PLA | 104 | recall top value on stack into accumulator |
TAY | 168 | transfer it to Y register |
PLA | 104 | recall next value on stack |
TAX | 170 | transfer it to X register |
PLA | 104 | recall original accumulator value |
STEP V: Return from interrupt.
RTI | 64 | return |
As in Program 1, the decimal code corresponding to this routine is entered in the program as DATA (lines 25 and 30) and is written into Page Six by line 20.
Programs 1 and 2 are simple examples that show how to set up DLI routines. Program 3 illustrates using a DLI routine in conjunction with a custom display list. This program sets up two sections of text (GR. 2, GR. 1) and draws a daisy in the Graphics 8 portion of the screen. After the display has been drawn, a DLI routine changes the colors of the display. There is a short pause for you to view the screen in its new colors. Then in line 350 the DLI is disabled by POKEing in 54286,64. We believe that this little program is an indication of the many possibilities awaiting you in using Display List Interrupts.
Program 2
Listing 1: DISASEM1.BAS Download
Listing 2: DISASEM2.BAS Download
Allan Moose is an associate professor (math/physics) at Southampton College, New York. Marian Lorenz is a special education teacherfor handicapped children.