A.N.A.L.O.G. ISSUE 11 / MAY 1983 / PAGE 98
Hidden deep inside the ATARI 400/800 computer systems are several capabilities that ATARI apparently chose to keep a deep, dark secret. Player-missile graphics, an incredibly powerful graphics tool, are barely hinted at in most ATARI documentation. Optimized Systems Software’s BASIC A+ was a step in the right direction as far as P/M graphics are concerned, allowing easy manipulation in BASIC.
Unknown to many ATARI users, the 400/800 computers actually have 14 graphics modes (17 if you count GTIA), not just the nine BASIC modes 0-8. These additional modes are available in the hardware, but the Operating System (OS) doesn’t support them directly. Shown below is a table of the ANTIC (hardware) modes and their corresponding BASIC modes.
ANTIC BASIC DESCRIPTION MODE MODE 02 0 40 x 24, 2 COLOR, TEXT 03 - 40 x 15, 2 COLOR, TEXT 04 - 40 x 24, 4 COLOR, TEXT 05 - 40 x 12, 4 COLOR, TEXT 06 1 20 x 24, 5 COLOR, TEXT 07 2 20 x 12, 5 COLOR, TEXT 08 3 40 x 24, 4 COLOR, GRAPHIC 03 4 80 x 48, 2 COLOR, GRAPHIC 16 5 80 x 48, 4 COLOR, GRAPHIC 11 6 160 x 96, 2 COLOR, GRAPHIC 12 - 160 x192, 2 COLOR, GRAPHIC 13 7 160 x 96, 4 COLOR, GRAPHIC 14 - 160 x192, 4 COLOR, GRAPHIC 15 8 320 x192, 2 COLOR, GRAPHIC
ANTIC mode 3 is a nifty text mode similar to GRAPHICS 0 which will allow true descenders on lower-case letters. ANTIC 4 and 5 are very powerful text modes allowing 5 colors WITHIN EACH CHARACTER! Mode 4 was used for ATARI’s adaptation of PAC-MAN, for the maze and bonus nuggets. ANTIC 12, which we call GRAPHICS 6+, is identical to BASIC GRAPHICS 6, but each plotted block (or pixel) is only one scan line tall, giving a higher resolution display of 160 by 192.
The mode this article is concerned with is ANTIC 14, or GRAPHICS 7+. It is identical to GRAPHICS 7, but has a resolution of 160 by 192. Using this mode will allow the generation of high-resolution displays in four colors. The best example of this mode is Datasoft’s graphics package, “Micropainter.” This article will present a machine-language subroutine which will allow you to use GRAPHICS 7+ from BASIC. It also has some nice enhancements which make plotting and drawing much faster.
Listing 1 is the BASIC code necessary to use GRAPHICS 7+. As written, it will run a continuous demonstration, plotting rectangles in 3 colors at random points on the screen. Type this listing into your computer and SAVE it before running it.
After SAVEing the program, RUN it. If the listing was entered correctly, you will see rectangles plotted continuously on your screen. The program has some error-checking that will catch some errors in the DATA. A “CALC DATA ERROR” indicates an error in the plot calculator data in lines 460-500. A “MAIN DATA ERROR” indicates an error in the main routine data in lines 540-680.
Listings 2 and 3 are the machine-language source listings of the handler, for those interested in the assembler side of the routine.
Once you have an operating copy of the GRAPHICS 7+ handler, you are ready to use it in your own programs.
As noted earlier, the program presented here will plot random rectangles on your screen. The code that performs this function is in lines 230-420. Lines 50-220 and 440-680 MUST be left as is (of course, you can delete the REMarks if you wish).
Line 50 – READs the DATA in lines 460-500 and places it in the user memory. This DATA, the machine-language form of listing #2, actually performs the calculations needed to PLOT in GRAPHICS 7+.
Lines 110-115 – READs the DATA in lines 540-680 and places it in the string variable G7P$. This DATA is the machine-language form of listing #3, and handles GRAPHICS 7+ initialization, PLOTting and DRAWing. Note that a simple checksum routine is used to check for DATA errors.
Line 170 – This line sets entry points into the machine-language program located in G7P$. INIT is the address of the initialization routine, PL is the address of the PLOT routine, and DR is the address of the DRAWTO routine.
Line 220 – This line initializes the GRAPHICS 7+ screen. First, the user must set up a GRAPHICS 8 screen, either a full-screen or split-screen mode. In this case, we want a full-screen GRAPHICS 7+ screen so we use GRAPHICS 8+16. Using only GRAPHICS 8 will allow the use of a text window at the bottom of the screen. We use a GRAPHICS 8 call because it reserves the same amount of memory that GRAPHICS 7+ needs. Next, we do a USR call to the INIT routine to actually set up the GRAPHICS 7+ screen. It’s that simple!
Line 230 – This line sets COLOR 0 to red.
Line 280 – This line randomizes the X and Y coordinates of the rectangle’s upper-left corner. It also sets a random COLOR of 1, 2, or 3. We don’t allow the color value to be zero, as this would be the same color as the background, and wouldn’t show up.
Line 330 – This line PLOTs the first point of a rectangle. It does the same thing as the BASIC statement:
PLOT 10+X,10+Y
One interesting function incorporated into the GRAPHICS 7+ handler is the ability to plot multiple points with one PLOT statement. For example, examine the following BASIC statements:
PLOT X,Y PLOT X+2,Y+2 PLOT X,Y+2 PLOT X+2,Y
These four commands could be done in GRAPHICS 7+ with ONE command, as shown below:
A=USR(PL,X,Y,X+2,Y+2,X,Y+2,X+2,Y)
Using one command for such multiple PLOTs can speed up program execution and makes life a little easier when keying in programs. Just remember to always give the routine an EVEN number of arguments (X and Y coordinates). If the GRAPHICS 7+ handler receives an odd number of arguments, it will not plot, but will simply return to BASIC. If the X or Y values exceed the screen limits (X = 0-159, Y = 0-191), the PLOT will be ignored.
To summarize, whenever a PLOT is desired in GRAPHICS 7+, use the command:
A=USR(PL,X,Y)
Line 380 – This line DRAWs the four sides of the rectangle. As with the GRAPHICS 7+ PLOT handler, the DRAW handler will accept multiple DRAWTOs! As you can see, we can draw a rectangle in GRAPHICS 7+ with only TWO commands, where normally FIVE BASIC commands would be necessary. This line is the same as the four BASIC commands:
DRAWTO 10+X,Y DRAWTO X,Y DRAWTO X,10+Y DRAWTO 10+X,10+Y
This multiple-argument DRAWTO capability can be very powerful, allowing many lines to be drawn with one statement.
Whenever a DRAWTO is desired with GRAPHICS 7+, use the command:
A=USR(DR,X,Y)
Line 420 – This line simply transfers control back to line 280, where the plotting of another rectangle begins.
You can easily create programs that use GRAPHICS 7+. Simply remove lines 230-420 and place your program code after line 220. You may change the “GRAPHICS 8+16” command in line 220 if a split-screen graphics mode is desired. I think you will find that GRAPHICS 7+ is a happy medium between the somewhat “chunky” GRAPHICS 7 and the one-color hi-res GRAPHICS 8. Its added resolution in the Y-axis brings it close to mode 8, and the four-color capability gives spectacular displays.
Interestingly enough, the new ATARI 1200XL computer supports ANTIC modes 4, 5, 12 (or 6+) and 14 (or 7+)! Therefore, this program is unnecessary for those future 1200XL owners. Of course, any program written with this GRAPHICS 7+ handler will work on a 1200XL, without modification.
Whichever ATARI computer you own, the GRAPHICS 7+ handler will let those hidden graphics capabilities shine through.
1 REM ******************************* 2 REM * * 3 REM * GRAPHICS 7+ HANDLER * 4 REM * * 5 REM * BY TOM HUDSON * 6 REM * * 7 REM * A.N.A.L.O.G. COMPUTING #11 * 8 REM * * 9 REM ******************************* 10 REM 20 REM *** PLACE PLOT CALCULATOR *** 30 REM *** ON PAGE 6 *** 40 REM 50 FOR X=0 TO 116:READ N:POKE 1536+X,N:CK=CK+N:NEXT X:IF CK<>15155 THEN ? "C ALC DATA ERROR!":END 60 REM 70 REM *** PLACE GRAPHICS 7+ *** 80 REM *** MACHINE-LANGUAGE *** 90 REM *** IN STRING G7P$ *** 100 REM 110 DIM G7P$(371):FOR X=1 TO 371:READ N:G7P$(X,X)=CHR$(N):CK=CK+N:NEXT X 115 IF CK<>63809 THEN ? "MAIN DATA ERR OR!":END 120 REM 130 REM *** SET INITIALIZATION, *** 140 REM *** PLOT AND DRAWTO *** 150 REM *** VARIABLES *** 160 REM 170 INIT=ADR(G7P$):PL=INIT+77:DR=INIT+ 129 180 REM 190 REM *** SET UP GRAPHICS 7+ *** 200 REM *** GRAPHICS MODE *** 210 REM 220 GRAPHICS 8+16:A=USR(INIT) 230 SETCOLOR 0,3,2 240 REM 250 REM *** GET RANDOM X,Y, AND *** 260 REM *** COLOR VALUES *** 270 REM 280 X=RND(0)*140:Y=RND(0)*180:COLOR IN T(RND(0)*3+1) 290 REM 300 REM *** PLOT THE FIRST POINT *** 310 REM *** IN THE RECTANGLE *** 320 REM 330 A=USR(PL,10+X,10+Y) 340 REM 350 REM *** DRAW THE 4 SIDES OF *** 360 REM *** THE RECTANGLE *** 370 REM 380 A=USR(DR,10+X,Y,X,Y,X,10+Y,10+X,10 +Y) 390 REM 400 REM *** DO ANOTHER RECTANGLE *** 410 REM 420 GOTO 280 430 REM 440 REM *** PLOT CALCULATOR DATA *** 450 REM 460 DATA 173,241,6,10,133,203,169,0,42 ,133,204,6,203,38,204,6,203,165,203,13 3,207,38,204,165,204 470 DATA 133,208,6,203,38,204,6,203,38 ,204,165,203,24,101,207,133,203,165,20 4,101,208,133,204,165,88 480 DATA 24,101,203,133,203,165,89,101 ,204,133,204,173,240,6,41,3,170,173,24 0,6,74,74,24,101,203 490 DATA 133,203,165,204,105,0,133,204 ,164,200,189,113,6,57,105,6,133,206,18 9,109,6,160,0,49,203 500 DATA 5,206,145,203,96,0,85,170,255 ,63,207,243,252,192,48,12,3 510 REM 520 REM *** GR. 7+ MACHINE CODE *** 530 REM 540 DATA 104,173,48,2,24,105,3,133,203 ,173,49,2,105,0,133,204,160,0,177,203, 201,79,208,21,169 550 DATA 78,145,203,165,203,24,105,2,1 33,203,165,204,105,0,133,204,169,0,240 ,15,201,15,208,6,169 560 DATA 14,145,203,208,5,201,65,208,1 ,96,165,203,24,105,1,133,203,165,204,1 05,0,133,204,169,0 570 DATA 240,197,216,104,240,13,133,20 5,41,1,240,8,166,205,104,104,202,208,2 51,96,104,104,201,160,176 580 DATA 22,141,240,6,104,104,201,192, 176,6,141,241,6,32,0,6,198,205,198,205 ,208,229,96,104,104 590 DATA 169,0,240,243,216,104,240,217 ,133,205,41,1,240,6,166,205,169,0,240, 200,104,104,201,160,176 600 DATA 14,141,242,6,104,104,201,192, 176,7,141,243,6,144,9,104,104,198,205, 198,205,208,228,96,205 610 DATA 241,6,144,14,56,237,241,6,141 ,247,6,169,1,141,249,6,208,15,173,241, 6,56,237,243,6 620 DATA 141,247,6,169,255,141,249,6,1 73,242,6,205,240,6,144,14,56,237,240,6 ,141,246,6,169,1 630 DATA 141,248,6,208,15,173,240,6,56 ,237,242,6,141,246,6,169,255,141,248,6 ,169,0,141,245,6 640 DATA 141,244,6,173,246,6,205,247,6 ,144,15,141,250,6,133,209,74,141,245,6 ,169,0,240,14,240 650 DATA 147,173,247,6,141,250,6,133,2 09,74,141,244,6,173,250,6,240,237,173, 245,6,24,109,247,6 660 DATA 141,245,6,197,209,144,19,173, 245,6,56,229,209,141,245,6,173,241,6,2 4,109,249,6,141,241 670 DATA 6,173,244,6,24,109,246,6,141, 244,6,197,209,144,19,173,244,6,56,229, 209,141,244,6,173 680 DATA 240,6,24,109,248,6,141,240,6, 32,0,6,206,250,6,208,182,169,0,240,159
; =========================== ; GRAPHICS 7+ HANDLER ; =========================== ; =========================== ; WRITTEN BY: TOM HUDSON ; A.N.A.L.O.G. COMPUTING #11 ; =========================== ; ------------------------ ; OPERATING SYSTEM EQUATES ; ------------------------ SAVMSC = $58 ;SCREEN ADDRESS COLOR = $C8 ;COLOR REGISTER ; -------------------- ; MY WORKING VARIABLES ; -------------------- LO = $CB HI = $CC HOLD = $CE LOHLD = $CF HIHLD = $D0 ; -------------- ; PLOT WORK DATA ; -------------- PLOTX = $6FB PLOTY = $6F1 ORG $0600 ;PAGE 6 ; ---------------------- ; GR. 7+ PLOTTER ROUTINE ; ---------------------- PLOTCL LDA PLOTY ;MULT. Y BY 40: ASL A STA LO LDA #0 ROL A STA HI ;*2 ASL LO ROL HI ;*4 ASL LO STA LOHLD ROL HI LDA HI STA HIHLD ;*8 ASL LO ROL HI ;*16 ASL LO ROL HI ;*32 LDA LO CLC ADC LOHLD STA LO LDA HI ADC HIHLD STA HI ;+*8=*48 LDA SAVMSC ;ADD THE DISPWY CLC ;ADDRESS TO GET ADC LO ;THE ACTUAL STA LO ;ADDRESS OF THE LDA SAVMSC+1 ;BYTE THAT WILL ADC HI ;BE ALTERED FOR STA HI ;THE PLOT. LDA PLOTX ;MASK PLOTX FOR AND #3 ;PLOT INDEX, TAX ;PLACE IN X. LDA PLOTX ;GET PLOTX AND LSR A ;DIVIDE LSR A ;BY 4, CLC ;ADD TO ADC LO ;PLOT ADDRESS STA LO ;FOR FINAL PLOT LDA HI ;ADDRESS. ADC #0 STA HI LDY COLOR ;GET COLOR LDA BMASK2,X ;AND MASK OFF AND COLORS,Y ;PIXEL POSITION STA HOLD ;SAVE IT, LDA BMASK1,X ;MASK OFF PIXEL LDY #0 ;OF THE ADDRESS AND (LO),Y ;TO BE ALTERED ORA HOLD ;SET THE PLOT STA (LO),Y ;BITS AND STORE! RTS ;FINIS! ; ---------------- ; PLOT MASK TABLES ; ---------------- COLORS DB $00,$55,$AA,$FF BMASK1 DB $3F,$CF,$F3,$FC BMASK2 DB $C0,$30,$0C,$03 END
; =========================== ; GRAPHICS 7+ HANDLER ; =========================== ; =========================== ; WRITTEN BY: TOM HUDSON ; A.N.A.L.O.G. COMPUTING #11 ; =========================== ; ------------------------ ; OPERATING SYSTEM EQUATES ; ------------------------ DLISTL = $230 ;DISPLAY LIST LOW DLISTH = $231 ;DISPLAY LIST HIGH COLOR = $C8 ;BASIC COLOR ; -------------------- ; MY WORKING VARIABLES ; -------------------- LO = $CB HI = $CC ARGNUM = $CD LOHLD = $CF HIHLD = $D0 ENDPT = $D1 ; ----------------------- ; PLOT ADDRESS CALCULATOR ; ----------------------- PLOTCL = $0600 ; ------------- ; PLOT WORK DATA ; -------------- PLOTX = $6F0 ;PLOT X LOC. PLOTY = $6F1 ;PLOT Y LOC. DRAWX = $6F2 ;DRAWTO X LOC. DRAWY = $6F3 ;DRAWTO Y LOC. ACCX = $6F4 ;X ACCUMULATOR ACCY = $6F5 ;Y ACCUMULATOR DELTAX = $6F6 ;DRAWTO WORK AREA DELTAY = $6F7 ;DRAWTO WORK AREA INCX = $6F8 ;DRAW X INCREMENT INCY = $6F9 ;DRAW Y INCREMENT COUNTR = $6FA ;DRAWTO COUNTER ; -------------------- ; RELOCATABLE ROUTINES ; -------------------- ORG $6000 ;ANYWHERE ; --------------------------- ; DISPLAY LIST INITIALIZATION ; --------------------------- SETUP PLA ;(DISCARD) LDA DLISTL ;FIND THE CLC ;ADDRESS OF ADC #3 ;THE BASIC STA LO ;DISPLAY LIST LDA DLISTH ;AND PLACE ADC #0 ;IN A PAGE 0 STA HI ;WORKING AREA LDY #0 ;NO Y OFFSET SCANDL LDA (LO),Y ;SCAN THE DISPLAY LIST CMP #$4F ;CHANGE BNE NOMLD ;$4F (GR. 8) LDA #$4E ;TO STA (LO),Y ;$4E (6R. 7+) LDA LO ;SINCE THIS WAS CLC ;A 'LOAD MEMORY' ADC #2 ;INSTRUCTION (3 BYTES) STA LO ;WE WILL SKIP LDA HI ;THE NEXT 2 BYTES ADC #0 ;TO GET THE NEXT STA HI ;DISPLAY LIST LDA #0 ;INSTRUCTION BEQ NXTDLB ;ADDRESS. NOMLD CMP #$0F ;CHANGE $0F (GR. 8) BNE NOREGL ;TO LDA #$0E ;$0E (GR. 7+) STA (LO),Y ;AND GO TO BNE NXTDLB ;NEXT D.L. INSTRUCTION NOREGL CMP #$41 ;END OF DISP. LIST? BNE NXTDLB ;NO: GET NEXT BYTE RTS ;YES, EXIT! NXTDLB LDA LO ;INCREMENT THE CLC ;MEMORY POINTER ADC #1 ;TO GET THE STA LO ;NEXT BYTE LDA HI ;OF THE ADC #1 ;DISPLAY LIST STA HI ;AND LDA #0 ;FORCE BRANCH BEQ SCANDL ;BACK TO LOOP! ; ------------------------ ; GRAPHICS 7+ PLOT HANDLER ; ------------------------ PLOT CLD ;CLEAR DECIMAL MODE PLA ;PULL # OF ARGUMENTS BEQ PULLED ;OOPS-NONE!! STA ARGNUM AND #1 ;NEED EVENS BEQ GOODPL ;OK! LDX ARGNUM ;NOT EVEN, PULLEM PLA ;CLEAR STACK PLA DEX BNE PULLEM PULLED RTS ;EXIT TO BASIC GOODPL PLA ;(DISCARD) PLA ;GET PLOT X CMP #160 ;ONSCREEN? BCS NOPLOT ;NO! STA PLOTX ;YES, SAVE PLA ;(DISCARD) PLA ;GET PLOT Y CMP #192 ;ONSCREEN? BCS DECARG ;NO! STA PLOTY ;YES, SAVE JSR PLOTCL ;PLOT IT!!! DECARG DEC ARGNUM ;HEY, WE HAVE DEC ARGNUM ;2 LESS ARGS! BNE GOODPL ;ANOTHER PLOT RTS ;FINIS! NOPLOT PLA ;PULL Y-COORD PLA ;OFF STACK LDA #0 ;FORCE BRANCH BEQ DECARG ;TO NEXT PLOT ; ------------------------ ; GRAPHICS 7+ DRAW HANDLER ; ------------------------ DRAW CLD ;CLEAR DECIMAL MODE PLA ;PULL # OF ARGUMENTS BEQ PULLED ;NONE!! STA ARGNUM AND #1 ;NEED EVEN II BEQ GOODDR ;OK! LDX ARGNUM ;NOT EVEN, LDA #0 ;FORCE BRANCH BEQ PULLEM ;TO ABORT. GOODDR PLA ;(DISCARD) PLA ;GET DRAWTO X CMP #160 ;ONSCREEN? BCS NODRAW ;NO! STA DRAWX ;YES, SAVE IT PLA ;(DISCARD) PLA ;GET DRAWTO Y CMP #192 ;ONSCREEN? BCS DECPLA ;NO! STA DRAWY ;YES, SAVE IT BCC DRWCAL ;DRAW LINE! NODRAW PLA ;DISCARD Y PLA ;COORDINATES DECPLA DEC ARGNUM ;2 LESS DEC ARGNUM ;ARGUMENTS BNE GOODDR ;NOT DONE YET! RTS ;FINISHED! ; --------------------- ; CALCULATE DRAW VECTOR ; --------------------- DRWCAL CMP PLOTY ;IS DRAWY>PLOTY? BCC YMINUS ;NO! SEC ;SUBTRACT SBC PLOTY ;PLOTY FROM DRAWY STA DELTAY ;SAVE DIFFERENCE. LDA #1 ;Y INCREMENT STA INCY ;= 1 (DOWN) BNE XVEC ;BRANCH! YMINUS LDA PLOTY ;SUBTRACT SEC ;DRAWY SBC DRAWY ;FROM PLOTY STA DELTAY ;AND SAVE DIFFERENCE. LDA #255 ;Y INCREMENT STA INCY ;= -1 (UP) XVEC LDA DRAWX ;IS DRAUX CMP PLOTX ;> PLOTX? BCC XMINUS ;NO! SEC ;SUBTRACT SBC PLOTX ;PLOTX FROM DRAUX STA DELTAX ;AND SAVE DIFFERENCE. LDA #1 ;X INCREMENT STA INCX ;IS 1 (RIGHT) BNE VECSET ;BRANCH! XMINUS LDA PLOTX ;SUBTRACT SEC ;DRAWX FROM SBC DRAWX ;PLOTX STA DELTAX ;AND SAVE DIFFERENCE. LDA #255 ;X INCREMENT STA INCX ;IS -1 (LEFT) VECSET LDA #0 ;ZERO OUT: STA ACCY ;Y ACCUMULATOR STA ACCX ;X ACCUMULATOR LDA DELTAX ;IS DELTAX> CMP DELTAY ;DELTAY? BCC YMAX ;NO! STA COUNTR ;SAVE DELTAX STA ENDPT ;IN COUNTR, ENDPT. LSR A ;DIVIDE BY 2 AND STA ACCY ;STORE IN Y ACCUM. LDA #0 ;FORCE BRANCH BEQ DRAWGO ;TO DRAWGO. JDPLA BEQ DECPLA ;LEAPFROG JUMP YMAX LDA DELTAY ;DELTAY LARGER, STA COUNTR ;STORE IT IN STA ENDPT ;COUNTR, ENDPT. LSR A ;DIVIDE BY 2 AND STA ACCX ;STORE IN X ACCUM. ; ------------------------------ ; NOW WE START THE ACTUAL DRAWTO ; FUNCTION! ; ------------------------------ DRAWGO LDA COUNTR ;IF COUNTR=0... BEQ JDPLA ;NO DRAW! BEGIN LDA ACCY ;ADD DELTAY CLC ;TO Y ACCUMULATOR ADC DELTAY STA ACCY CMP ENDPT ;AT ENDPOINT YET? BCC BEGIN2 ;NO, GO DO X. LDA ACCY ;SUBTRACT ENDPT SEC ;FROM Y ACCUMULATOR SBC ENDPT STA ACCY LDA PLOTY ;AND INCREMENT CLC ;THE Y POSITION! ADC INCY STA PLOTY BEGIN2 LDA ACCX ;ADD DELTAX TO CLC ;X ACCUMULATOR ADC DELTAX STA ACCX CMP ENDPT ;AT ENDPOINT YET? BCC PLOTIT ;NO, GO PLOT. LDA ACCX ;SUBTRACT ENDPT SEC ;FROM X ACCUMULATOR SBC ENDPT STA ACCX LDA PLOTX ;AND INCREMENT CLC ;PLOT X ADC INCX STA PLOTX PLOTIT JSR PLOTCL ;PLOT THE POINT! DEC COUNTR ;MORE TO DRAW? BNE BEGIN ;YES! LDA #0 ;NO MORE, BEQ JDPLA ;FORCE BRANCH. END