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.
|
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