Color Finetuner
By Stephen Malinowski
This article presents an assembly-language program, with a Basic loader, which lets you change the contents of the color registers - even when a program is running. The BASIC version requires BASIC, and the program requires 16K. To use with XL machines, run the Translator program first.Color Finetuner is a program that gives you direct control of the Atari's nine color registers, even when other programs are running. You can also use it to change GPRIOR, the register that selects the GTIA mode.
How To Install Color Finetuner
The simplest way to install this utility is to enter and RUN the program listing at the end of this article. The program is installed on Page Six (starting at decimal location 1536); it causes the deferred vertical-blank (VB) vector to point to the routine.If you need to use Page Six for your own purposes, add the lines in Listing 2. Modify line 100 to correspond to the graphics mode you'll be using in your own program. As a result, Color Finetuner will place the routine in high memory, just below the display list used by your application. It will also set HIMEM to protect the routine from BASIC. If you change graphics modes, however, the routine will no longer be protected, and it may be overwritten.
For Advanced Programmers
Color Finetuner also can be used along with your own vertical-blank-interrupt routines. If your routines use only the immediate vector, the program can be used as is. If, however, your routines use the deferred vector or replace the OS VBI service routine entirely, the end of your routine should perform a jump to ORIGIN, as calculated in line 210. (You shouldn't jump to INSTAL, which is used only by the BASIC USR function.) Color Finetuner concludes with a jump to XITVBV
How To Use The Routine
Once Color Finetuner is installed, type Listing 3 and RUN it. The program draws lines in Graphics 10 using all nine color registers (including the background), but you won't see some of the lines at first.To change any color register, first select the register by pressing the corresponding number key:
DECIMAL HEX KEY REGISTER LOCATION LOCATION 0 PCOLRO 704 2CO 1 PCOLRL 705 2Cl 2 PCOLR2 706 2C2 3 PCOLR3 707 2C3 4 COLORO 708 2C4 5 COLOR1 709 2C5 6 COLOR2 710 2C6 (background color in GR. 0) 7 COLOR3 711 2C7 8 COLOR4 712 2C8 (border color in GR. 0) 9 GPRIOR 623 26FThen use the three console keys to increase or decrease the contents of the register:
OPTION - increases the contents.
SELECT - Fast speed (hold with [START] or [OPTION]).
START - Decreases the contents.
You don't have to hold down the number key. Once you've selected a register, it will be affected by the console keys until you select another register.
Disassembly Of Color Finetuner
This section contains an assembly-language listing of the Color Finetuner routine. The listing is in Atari Assembler Editor syntax and is complete, but line numbers have been deleted for editorial purposes. If you wish to type in the assembly-language program, use the command NUM to provide line numbers.
OS And Hardware Locations Used By Color Finetuner
*=$0600 ; Sets origin to Page Six. CONSOL=$DOLF ; Contains the composite output of the console keys. The following three masks are used to isolate the bit that corresponds with the key: REVMSK=$OL ; Mask for [OPTION] key. FSTMSK=$02 ; Mask for [SELECT] key. FWDMSK=$04 ; Mask for [START] key. RTCLK3=$14 ; The byte of the real-time clock, which is incremented every sixtieth of a second (or one jiffy). KBCODE=$D209 ; The hardware register that contains the raw data for the last key pressed. It is con- verted to ATASCII form by the table ATASCI. ATASCI=$FEFE ; The table used to convert raw keyboard data into ATASCII form. RANGE=$0A ; This number, together with TOOHI, is used to convert ATASCII numbers to their actual numerical values, and to check for out-of-range values. TOOHI=$C6 ; See RANGE. PRIOR=$DOLB ; This register controls several aspects of the display. See De Re Atari (Atari Program Exchange, 1981) for further information. GPRIOR=$26F ; The OS shadow for PRIOR. Its contents are written to PRIOR every sixtieth of a second. COLPMO=$DO12 ; The first hardware color register. PCOLRO=$2CO ; The shadow register for COLPMO. SETVBV=$E45C ; An OS routine used to set the vectors that are used as access points to the VB service routine. XITVBV=$E462 ; The last part of the OS VB service routine. It restores the 6502's registers and returns the processor to whatever it was doing at the time the interrupt occurred.
The Color Finetuner Routine
Every sixtieth of a second, the ANTIC chip generates an interrupt that stops the main activities of the 6502 chip and directs it to the OS vertical-blank service routine. Most of this routine is in ROM, and is not alterable by the user. However, two vectors, or "signposts," are stored in RAM. Color Finetuner (CF) causes one of these vectors to "tie into" the service routine.The Operating System (OS) has a routine that changes these vectors. The first part of CF calls this routine:
INSTAL LDA #$7 7 equals deferred vector. LDX #CHECK1/$10 high byte of the main routine location. LDY #CHECK1&$FF low byte of the main routine location. JSR SETVBV sets the vertical-blank vectors. PLA pops the stack. RTS returns to BASIC.Once INSTAL is called from BASIC (with a USR call), the service routine includes CF as part of its "housekeeping" routine every sixtieth of a second.
The first part of the main routine performs a series of checks to determine if CF should change a register. CHECK1 checks for a pressed console key:
CHECK1 LDA CONSOL gets console-key-register data. CMP #$7 is a key pressed? BPL EXIT no? then exits. TAY yes.? then saves CONSOL value and continues.CHECK2 controls the speed of the changes. It does this by examining the real-time clock (lowest byte at $14) and checking to see if [SELECT] has been pressed for fast color changes. At fast speed, the registers change every two cycles (one cycle = one sixtieth of a second); the normal speed changes them every sixteen cycles.
CHECK2 LDA RTCLK3 gets the clock's fastest byte. TAX and saves it. AND #$l is it odd or even? BNE EXIT odd? then exits. TYA even? then gets CONSOL contents again. AND #FSTMSK is fast button pressed? BEQ CHECK3 yes? then checks keyboard keys. TXA no? then checks clock byte again. AND #$F is it a multiple of (decimal) 16? BNE no? then exits.CHECK3 determines if a valid keyboard key has been pressed (0 through 9 only). Since KBCODE contains the raw keyboard code, not ATASCII code, we need to convert the raw code using the ATASCI table.
CHECK3 LDX KBCODE gets-the last key pressed. LDA ATASCI,X looks it up in the table. CLC gets ready to add. ADC #TOOHI is it high enough to be a decimal digit? BCS EXIT yes? then exits. ADC #RANGE is it too low? BCC EXIT yes? then exits. TAX just right? saves the converted digit.Now we're ready to change the color registers. There are actually two registers involved: the hardware register and its shadow register. If we were to write only to the hardware register, the change would last just a sixtieth of a second, because the OS copies the shadow registers to the hardware registers as part of the VB service routine.
Normally, it would be feasible to change only the shadow registers, and let the OS copy the color data to the hardware registers. However, since CF may be used in situations in which that part of the service routine is bypassed, we must write the color data to both locations.
PRIOR, the priority register, immediately follows the last hardware color register, so it can be treated as a tenth register. Its shadow GPRIOR does not immediately follow the color shadow registers, however, so it must be handled separately.
FORWRD TYA gets CONSOL contents again. AND #FWDMSK is the FORWARD button pressed? BNE REVERSE no? then checks reverse. TXA yes? gets keyboard digit. CMP #$9 is it equal to 9 (i.e., PRIOR)? BNE FCOLOR no? then it must be a col- or register. INC GPRIOR yes? then increments GPRIOR. LDA GPRIOR gets the incremented value, BCS HARD and writes it to hardware register. FCOLOR INC PCOLRO,X increments the color register. LDA PCOLORO,X gets incremented value BCC.HARD and writes it to hardware register. REVRSE TYA gets CONSOL contents again. AND #REVMSK is REVERSE button pressed? BNE EXIT no? then exits. TXA yes? then gets keyboard digit. CMP #$9 is it equal to 9 (i.e., PRIOR)? BNE RCOLOR no? then it must be a color register. DEC GPRIOR yes? then decrements GPRIOR. LDA GPRIOR gets decremented value, BCS HARD and writes to hardware register. RCOLOR DEC PCOLRO,X decrements color register, LDA PCOLRO,X and writes it to hardware register. HARD STA COLPMO,X writes new value to hardware register. EXIT JMP XITVBV exits through vertical- blank vector.Stephen Malinowski is a free-lance musician and composer who lives in the San Francisco Bay Area. He is currently using his Atari to develop a music-animation machine that will provide visual counterparts to musical sounds.
Listing 1 95 REM * COLOR FINETUNER * 96 REM * BY STEPHEN MALINOWSKI * 97 REM * ANTIC MAGAZINE * 100 INSTAL=1536 200 ? "Takes a couple of seconds to in stal.." 210 ORIGIN=INSTAL+ll 220 F0R X=0 T0 107 230 READ A:POKE INSTAL+X,A 240 NEXT X 300 A=USR(INSTAL):END 1000 DATA 169,7,162,6,160,11 1010 DATA 32,92,228,104,96,173 1020 DATA 31,208,201,7,16,87 1030 DATA 168,165,20,170,41,1 1040 DATA 208,79,152,41,2,240 1050 DATA 5,138,41,15,208,69 1060 DATA 174,9,210,189,254,254 1070 DATA 24,105,198,176,58,105 1080 DATA 10,144,54,170,152,41 1090 DATA 4,208,21,138,201,9 1100 DATA 208,8,238,111,2,173 1110 DATA 111,2,176,32,254,192 1120 DATA 2,189,192,2,144,24 1130 DATA 152,41,1,208,22,138 1140 DATA 201,9,208,8,206,111 1150 DATA 2,173,111,2,176,6 1160 DATA 222,192,2,189,192,2 1170 DATA 157,18,208,76,98,228 Listing 2 100 GRAPHICS 10 110 HIMEM=PEEK(741)+256*PEEK(742) 120 INSTAL=HIMEM-110 130 HI=INT(INSTAL/256) 140 LO=INSTAL-(HI*256) 150 GRAPHICS 0 160 POKE 741,LO:POKE 742,HI 250 HI=INT(ORIGIN/256) 260 LO=ORIGIN-(HI*256) 270 POKE INSTAL+3,HI 280 POKE INSTAL+5,LO Listing 3 10 GRAPHICS 10 20 FOR X=l TO 32 STEP 4 30 COLOR (X-1)/4+1 40 PL0T X,0 50 DRAWTO X,190 60 PLOT X+1,0 70 DRAWTO X+1,190 80 FOR I=2 TO 3:COLOR 0:PLOT X+I,0:DRAWTO X+I,190:NEXT I 90 NEXT X 95 GOTO 95Listing 1: FINETUN1.BAS Download
Listing 2: FINETUN2.BAS Download
Listing 3: FINETUN3.BAS Download