Classic Computer Magazine Archive COMPUTE! ISSUE 29 / OCTOBER 1982 / PAGE 159

Atari Rainbow: Colors By Page Flipping

Robert W. Myers
Charlotte, NC

Have you ever wanted more colors than are provided on your Atari? Here's how you can mix colors to produce new colors. The demonstration program uses four colors in Graphics mode 2, which are mixed two at a time to produce a total of ten different colors.

Blending Colors

All this color, like most everything on the TV screen, is really an illusion. The blending of colors takes place because the displays are changed back and forth so fast that our eyes cannot keep up with the changes. Therefore, we see only one color, which is a mixture of the colors in all the different displays. You can mix more than two colors at a time, but as the number of displays increases, the amount of flicker on the screen increases too. The practical limit is four displays mixing at once. But the ten colors that my program produces seem like a rainbow compared to the four colors normally allowed by the CTIA chip.

This mixing is done by using multiple screen RAM areas and changing the Load Memory Scan (LMS) bytes in the display list during the Vertical Blank Interrupt. I realize that this sounds like a very complicated thing to do, but it's not.

Understanding The Display List

The Display List is a program for the ANTIC chip, which is a microprocessor that controls the TV screen so that the 6502 can be free to spend more of its time doing computational chores. The Display List is in RAM, and the first byte of the Display List can be found at PEEK(560) + 256*PEEK(561).

Usually you will find that the first three bytes are the code that causes the black area at the top of the screen (to insure that nothing is lost due to overscan of the TV). The next byte is the LMS byte which sets the D6 bit (64 decimal). Added to this 64 is the ANTIC Graphics mode number, which is given in Table 1.

The LMS is a three-byte instruction. The 64 + mode# is the first byte; the second and third bytes are the address of the beginning of screen RAM.

This address is what we are interested in here. Rapidly changing it allows us to switch from one picture to another and back. We cannot do this address swapping from BASIC; it is far too slow. The LMS bytes are changed by a short machine language routine that is run 60 times a second while the picture is blanked out as it returns to the top of the screen to begin the next frame. This is Vertical Blank Interrupt.

The routine loads the LMS bytes with the address of the first (normal) screen RAM, then it does an exclusive-or with one of the memory locations. This causes the memory location to toggle between 0 and 1. This 0 or 1 is used to determine whether a branch will be taken or not. If the branch is taken, the next instruction is JMP $E462, which puts the interrupt back in normal operation. If the branch is not taken, then the LMS bytes are changed to the address of the other (alternate) screen RAM. Then comes the JMP $E462.

Using VBI

The VBI is amazingly easy to use. All you do is write your routine that is to run during the interrupt. Then write a machine language program that puts the high byte of your routine's address into the X-register, the low byte into the Y-register, and the number seven into the accumulator. Finally you JSR $E45C. This second machine language program is at lines 160, 170, and 180 of my program.

After setting up your VBI to change the LMS, you print or plot and move one set of your screen RAM to the other (alternate) location that you have specified to the LMS. This technique should be usable with any multicolor display mode or any combination of display modes not only to mix colors, but also to mix text and graphics, to display mixed resolutions, etc.

ANTIC Graphics Mode Numbers
BASIC mode# 0 1 2 3 4 5 6 7 8
ANTIC mode# 2 6 7 8 9 10 11 13 15
1 REM ***************************
2 REM * {25 SPACES}*
3 REM *	MIXING COLORS TO MAKE *
4 REM * {4 SPACES} AN ATARI RAINBOW {5 SPACES} *
5 REM * {10 SPACES} by {13 SPACES} *
6 REM * {4 SPACES} ROBERT W. MYERS {6 SPACES} *
7 REM *{25 SPACES}*
8 REM ***************************
9 REM
10 GRAPHICS 2 + 16 : BREAK = 1000
15 REM MACHINE LANGUAGE TO BE RUN DURING VERTICAL BLANK {9 SPACES} INTERRUPT
20 FOR I = O TO 36 : READ A : POKE 1536 + I, A : NEXT I
30 DATA 173,39,6,141,49,6,173,40,6,141,50,6,173,51,6,73,1,141,51
40 DATA 6,240,12,173,41,6,141,49,6,173,42,6,141,50,6,76,98,228
45 REM FIND DISPLAY LIST IN RAM
50 DLIST = PEEK(560) + 256 * PEEK (561)
55 REM MODIFY MACHINE LANGUAGE PROGRAM BY POKEING IN ADDRESSES FROM DISPLAY LIST
60 BYTE = DLIST + 4 : GOSUB BREAK : REM LOAD MEMORY SCAN LOW BYTE
70 POKE 1540,L0W : POKE 1562,LOW
80 POKE 1541,HIGH : POKE 1563, HIGH
90 BYTE = DLIST + 5 : GOSUB BREAK : REM LOAD MEMORY SCAN HIGH BYTE
100 POKE 1546,LOW:POKE 1568,LOW
110 POKE 1547, HIGH:POKE 1569, HIGH
120 BYTE = DLIST + 20:GOSUB BREAK : REM NORMAL SCREEN RAM
130 POKE 1576,HIGH : POKE 1575,LOW
140 BYTE = DLIST - 250 : GOSUB BREAK : REM ALTERNATE SCREEN RAM
150 POKE 1578,HIGH : POKE 1577,LOW
155 REM MACHINE LAN6UAGE PROGRAM TO INITIALIZE VERTICAL BANK{4 SPACES}INTERRUPT
160 FOR I = 0 TO 10 : READ A : POKE 1600 + I, A : NEXT I
170 DATA 104,162,6,160,0,169,7,32,92,228,96
180 X = USR(1600)
220 REM DRAW FIRST SCREEN
240 POSITION 0,4
250 PRINT #6; "ATARi coTER Club"
260 PRINT #6
270 PRINT #6; "{4 SPACES}  HARLott"
275 REM MOVE FIRST SCREEN TO ALTERNATE SCREEN RAM
280 FOR I=0 TO 240
290 POKE DLIST - 250 + I, PEEK(DLIST + 20 + I)
3OO NEXT I
305 REM SETCOLORS AND DRAW SECOND SCREEN
312 SETCOLOR 0,12,6
313 SETCOLOR 1,4,6
314 SETCOLOR 2,15,8
315 SETCOLOR 3,8,6
320 POSITION 0,4
330 PRINT #6;"Ati OTE "
340 PRINT #6
350 PRINT #6;"{4 SPACES}  Art"
359 REM HOLD IMAGE ON SCREEN
360 GOTO 360
999 REM SUBROUTINE TO BREAK DOWN NUMBER INTO HIGH AND LOW BYTES
1000 HISH = INT(BYTE/256)
1010 L0W = BYTE - HIGH*256
1020 RETURN