A.N.A.L.O.G. ISSUE 8 / NOVEMBER 1982 / PAGE 57

GRAPHIC VIOLENCE!

16K CASSETTE OR DISK

by Tom Hudson

When writing game programs, many programmers automatically choose assembly language over BASIC because of the obvious speed advantage. This can sometimes be a mistake, since BASIC offers some functions (such as sine, square root, etc.) not easily written in assembler. One way to take advantage of the convenience of BASIC and the speed of assembler is to combine the two languages. ATARI BASIC allows the user to “call” machine-language subroutines, which can be many times faster than the same routine in BASIC. A.N.A.L.O.G. Software’s shooting gallery game “Carnival” uses this technique. Fine screen scrolling, music generation and other functions which must be performed quickly are done in assembler, while simpler operations are handled by BASIC.

In order to assist those game programmers who would like to have dramatic explosion effects in their BASIC programs, I have developed Graphic Violence, a group of assembly-language subroutines. These routines allow BASIC to generate up to 20 simultaneous explosions in GRAPHICS 7. They can optionally generate sound effects as well as “cycle” the colors of the explosions for an interesting “radioactive glow” effect.

The first half of this article is a non-technical explanation of how to use Graphic Violence. The second half is an in-depth discussion of the actual assembly language code for those interested in the inner workings of the subroutines.

USING GRAPHIC VIOLENCE

Listing 1 is the BASIC language code necessary to set up the Graphic Violence subroutine. This code should be placed in any program that is to use the explosion generator. After typing this program in, SAVE it immediately, BEFORE RUNNING IT! The routine has some safeguards against typing errors in the DATA statements, but if it is executed with bad DATA, the system may crash and it will be necessary to re-type the program.

After the program is typed and SAVEd, RUN it. If it is typed correctly, the program will run for several seconds before anything happens. The screen colors will begin cycling quickly. If not, an error was made somewhere, and you should re-boot your system, load the SAVEd program, find the mistake, SAVE it and try again.

If a message such as “COORD1 ERR” occurs, you have made a mistake typing in the DATA statements. “COORD1 ERR” indicates that an error was made in the COORD1 DATA, “INIT ERR” is an error in the INITIALIZATION CODE, etc. Find the error, fix it and re-RUN the program.

Once the computer starts cycling colors, press SYSTEM RESET before doing anything else. Whenever operating any program using the Graphic Violence subroutine, you MUST use the SYSTEM RESET key to terminate the program. The subroutine automatically disables the BREAK key since typing commands in immediate mode while the subroutine is in operation will usually cause a system crash. Pressing SYSTEM RESET will correctly terminate the subroutine and avoid any problems.

At this point, you should have a correctly operating Graphic Violence initialization subroutine SAVEd on tape or disk.

PROGRAM 1 FLOW

Line 80
GOSUBs to line 10000 to initialize the subroutine.
Line 10010
Dimensions the strings needed by Graphic Violence and RESTOREs the DATA pointer.
Line 10020-10060
READs DATA statements into the strings used by the routine.
Line 10080
POKEs graphics PLOT values into Graphic Violence.
Line 10100
Calls the machine-language initialization routine. It is of the form:
A=USR(ADR(INIT$),ADR(MAIN$),ADR(COORD1$),ADR,(COORD2$),COLOR,SOUND)

The COLOR value tells whether or not you want the color of the explosions to cycle. In the program listing, this value is set to 1, indicating that cycling is desired. If you do not want cycling, place a here.

The SOUND value tells whether or not you want the routine to generate sounds with the explosions. In the listing it is a 1, indicating that we want sound. If sound is not desired, place a here.

Line 10110
This line simply returns from the subroutine to the main program.

A SHORT DEMONSTRATION OF GRAPHIC VIOLENCE

With listing #1 in your computer, add listing #2 to the original program and RUN it. This is a short demonstration routine which simply places an explosion at the center of the screen, then repeats.

By looking at this short routine, you will notice the USR call in line 220. This is the command which starts an explosion. Once the Graphic Violence machine-code subroutine is set up, this short operation is all you need to generate explosions.

Remember to stop the program by pressing SYSTEM RESET.

PROGRAM 2 FLOW

Line 190
Set up a full-screen graphics mode 7.
Line 220
Call the explosion-starting machine language routine. This line actually starts the explosion. It is of the form:
A=USR(ADR(EXPLS$),X,Y)

X and Y are the screen coordinates of the center of the explosion. In the listing, X=80 an-d Y=48, placing the explosion at the center of the screen. This statement is the heart of the Graphic Violence routine. Once this statement is executed, it starts off an explosion while BASIC continues with whatever it is doing. In addition, the explosion handler can operate up to 20 explosions simultaneously, while BASIC does its own processing!

Line 240
This line is a simple delay loop which allows an explosion to dissipate before generating another.
Line 260
This line goes to start a new explosion after the wait.

A LONGER DEMONSTRATION

In the previous example, we generated one explosion at the center of the screen, just to keep things simple. In this example, we will see how the Graphic Violence routine will handle up to 20 simultaneous explosions without the programmer having to worry about what’s going on inside the explosion handler! All the programmer needs to do is send the explosion coordinates to the routine via the USR command and let the computer do the rest. (What could be simpler?)

With listing #1 in your computer, add listing #3 to the original program and RUN it. The program will fill up most of the screen with graphics, then start dropping “bombs” from the top of the screen. As they hit the graphics area, they will explode violently, “eating” away the graphics. As soon as one of the bombs falls off the bottom of the screen, an end message will be displayed and subsequently destroyed by a number of explosions. The program will run continuously and MUST be stopped by pressing SYSTEM RESET.

PROGRAM 3 FLOW

Line 190
Sets up graphics mode 7 and sets COLOR #2 (the explosion color) to maximum brightness.
Line 210
Fills up the bottom section of the screen with COLOR 1 graphics.
Line 230
Makes sure any error will cause the program to continue at line 320 (the “THE END” routine). This TRAP statement will take effect when a bomb falls off the bottom of the screen.
Line 250
Gets the X and Y coordinates where the bomb will start its drop.
Line 270
Erases old bomb position (using COLOR 0) and increments Y position so that bomb will “fall” toward bottom of screen.
Line 290
Uses the LOCATE command to see if the bomb has hit anything. If the bomb hits color 1, an explosion is started at the X and Y coordinates and a new bomb is randomized.
Line 310
If no hit is detected, the bomb is plotted in color 2 , the program waits a fraction of a second, then continues at line 270.
Line 330
When a bomb falls off the bottom of the screen, the error is TRAPped here. At this time, the computer sets up a new graphics 7 screen, sets the explosion brightness, aivd selects COLOR 1.
Line 350
This line RESTORES the DATA pointer to line 400 (THE END shape data), then reads from and to plot data and draws the THE END message on the screen.
Line 370
This line sets off 200 explosions, which destroy the THE END message. Note that the explosion USR call has random number functions for X and Y coordinates of the explosion center. There is also a 40 count delay after each explosion is started for a more interesting display.
Line 390
After all explosions are generated, wait a few seconds and GOTO line 190 to re-run the demonstration continuously.
Line 410-430
These lines contain PLOT data for the words “THE END”. Each line in the letters is represented by 4 values, made up of 2 sets of X and Y coordinates, the line endpoints.

SUMMARY

The Graphic Violence explosion generator subroutine will operate in almost any game using graphics 7. Explosions overlapping the edges of the screen are automatically “clipped,” but the program has minimal error-trapping. The user should take care to make sure that the coordinates supplied to the routine do not exceed the graphics 7 screen limits. The routine uses sound channel 1 when the sound generation option is requested. The Explosions use COLOR 3 (SETCOLOR 2), and will cycle the color only (not brightness) if color cycling is requested. Any program using the Graphic Violence roudne must be terminated with SYSTEM RESET to avoid a system crash.

The following section contains a discussion of the assembly-language routines that make up Graphic Violence. This information is not necessary to use the subroutine, but may assist those interested in assembly language and the inner workings of the ATARI computers.

GENERAL BACKGROUND INFORMATION

The Graphic Violence subroutine is made up of three program segments and two data tables. These five modules work together to provide a machine-language explosion generator for BASIC.

The first assembly program (listing #4) is the Graphic Violence initialization subroutine. It is stored in the BASIC string variable INIT$. Its function is to accept the locations of the main program module and the explosion plot coordinates, start up the main module, and accept the color cycling and sound generation options.

Remember that this is the routine called in the BASIC statement:

A=USR(ADR(INIT$),ADR(MAIN$),ADR(COORD1$),ADR(COORD2$),COLOR,SOUND)

PROGRAM 4 FLOW

Line 230
This line arbitrarily sets the location counter to $6000. Since this routine will be fully relocatable and stored in a BASIC string, this address does not matter.
Line 240
This PLA instruction pulls the first argument off of the stack. In a BASIC USR call, this argument is always the number of arguments passed to the machine language routine. We do not use it in this case, and it is discarded.
Line 250-270
This section zeroes out the explosion ready flag and the explosion counter.
Line 280-330
This section pulls the low and high bytes of the address of the main routine (ADR MAIN$), transfers them to the X and Y registers, then puts a 7 in the accumulator and jumps to the SETVBV subroutine. This tells the system that we are using a vertical blank interrupt. The 7 indicates that it is a “deferred” vertical blank routine, that is, it operates after the system’s vertical blank operation.
Line 340-410
This section pulls the low and high bytes of the two sets of plot coordinates (COORD1$ and COORD2$, 4 PLA’s total) and stores them on page zero ($CB-$CE) for later use by the main module.
Line 420-440
This section pulls the color cycle indicator (COLOR) from the stack. Since this is a one-byte indicator and the system sends a two-byte argument, the first byte (high byte) is discarded and the second is stored in CYCFLG.
Line 450-470
This section is the same as lines 420-440, except that it stores the sound indicator (SOUND) in SNDFLG.
Line 480
This RTS (Return from Subroutine) returns control to your BASIC program after the initialization is complete.

The second assembly language program (Listing #5) is the explosion start routine. It is called by the BASIC statement:

A=USR(ADR(EXPL$),X,Y)

This routine simply accepts the coordinates of the explosion from BASIC. If there are 20 explosions active, it will ignore the request, otherwise it will send the coordinates to the main module, which is executing in the deferred vertical blank.

PROGRAM 5 FLOW

Line 200
Once again, this listing has its location counter set to $6000. It makes no difference, since this routine is fully relocatable.
Line 210
As in the previous listing, this line discards the first item on the stack (the number of arguments passed to the assembly routine).
Line 220-240
These lines check the variable EXPCNT to make sure the new explosion can be started. If there are less than 20, control is passed to EXPOK (explosion OK).
Line 250-290
These lines are used if there are already 20 explosions. The remaining 4 bytes are pulled from the stack and discarded, and the program returns to BASIC. No explosion is generated.
Line 300-350
In a manner similar to the COLOR and SOUND parameters in listing #4, this routine pulls the X and Y coordinates off of the stack and places the values in NEWX and NEWY for use by the main module.
Line 360-370
This section places a 1 in the READY flag, which tells the main interrupt routine that a new explosion is ready to start.
Line 380
This RTS instruction simply returns control to BASIC. In this way, the interrupt can start the explosion graphics while BASIC keeps running normally.

The third assembly language listing (LISTING #6) is the vertical blank interrupt routine, stored in MAIN$. It does all the color cycling, sound, and graphics for the explosions. Since it is an interrupt-driven program, it operates independently of BASIC, allowing BASIC to continue processing normally while the vertical blank does all the explosion work.

Since this program is stored in a BASIC string, any program editing or immediate mode operations in BASIC while the vertical blank routine is running will cause a system crash. This is due to the fact that BASIC moves its variables around in memory during editing of programs, and such movement of the interrupt routine will confuse the system. To help avoid such a problem, the Graphic Violence interrupt routine disables the break key, making it necessary to press SYSTEM RESET to stop program execution. This is only a partial solution, however, since if the programmer allows his program to end with the READY prompt, then enters a program line, the crash will still occur.

The interrupt routine performs several functions. First, it disables the BREAK key and cycles the color of playfield type 2 if necessary. Next it processes sound, if required, using sound channel 1. The last major function it performs is that of explosion graphics generation.

Each explosion graphic is made up of 89 separate pixels. The routine uses the specified centerpoint of each explosion and adds X and Y offset values, which are stored in the BASIC string variables COORD 1$ and COORD2$. Each of the 89 pixels are first turned on, one pixel at a time, resulting in a “growing” appearance. After all 89 pixels are on, the routine turns off one pixel at a time, causing the explosion to dissipate. Each active explosion has a pixel either turned on or off each time the interrupt is performed. Since this happens 60 times a second, each explosion takes roughly 3 seconds to expand and dissipate ((89*2)/60). Explosions are independent of each other because of three tables. The X and Y coordinates of each explosion are stored in the XPOS and YPOS tables. The third table, CNT, holds the number of the pixel which will be turned on or off next for each explosion. This value ranges from 0 to 88 for “on” pixels, and 89 to 177 for “off” pixels. If the CNT value for an explosion exceeds 177, the explosion has dissipated completely and its values are removed from the explosion tables by a “repack” operation. That is, if explosion number 2 is finished, explosion 3 will move back to 2, 4 to 3, etc.

PROGRAM 6 FLOW

Line 500
Clears decimal mode. This instruction is vital when writing subroutines for BASIC that do any binary arithmetic.
Line 510-540
Disables the BREAK key by altering POKMSK and IRQEN, the interrupt request enable. This prevents the BREAK key from generating an interrupt.
Line 550-640
Cycles colors if CYCFLG is not zero.
Line 650-770
Processes explosion sound if SNDFLG is not zero.
Line 780-940
Monitors the READY flag to see if there is a new explosion. If not, the program checks for any old explosions at MAIN. If there is a new explosion, the routine sets up the XPOS, YPOS and CNT tables with the new information.
Line 950
Zeroes out COUNTR, the variable indicating which explosion is being processed.
Line 960-1000
Increments the explosion counter. If the counter is greater than the current number of explosions active (EXPCNT), the routine jumps to XITVBV, the vertical blank exit vector. Otherwise control is passed to INDEX.
Line 1130-1350
This section repacks the XPOS, YPOS and CNT tables to eliminate a “dead” explosion. It then branches back to RUNLP to handle the next explosion.
Line 1360-2350
This routine turns explosion pixels on or off, depending on the PLOTCLR setting. If the pixel is off the screen, the plot is abandoned by a branch to RUNLP.

By expanding the XPOS, YPOS and CNT tables and altering the explosion call routine (Listing #5), advanced users can enable the Graphic Violence routine to handle many more explosions than it can now. However, 20 explosions are more than enough for most applications, and the routine should serve well as is.

I hope that ATARI programmers will see by this example that it is not always necessary to write game programs completely in assembly language. Just use BASIC for complicated functions difficult to write in assembler, and use assembler for things BASIC is too slow to do.

And by the way, have fun causing graphic havoc on your computer!

LISTING 1

10 REM **************************
20 REM * GRAPHIC VIOLENCE DEMO  *
30 REM * A.N.A.L.O.G. COMPUTING *
40 REM * BY TOM HUDSON          *
50 REM **************************
60 REM
70 REM *** INITIALIZE THE GRAPHIC VIOLENCE SUBROUTINE ***
80 GOSUB 10010
90 REM
100 REM *****************************
110 REM ** YOUR PROGRAM GOES HERE! **
120 REM *****************************
130 GOTO 130
10000 REM *** INITIALIZATION SUBROUTINE ***
10010 DIM INIT$(41),EXPL$(29),MAIN$(355),COORD1$(89),COORD2$(89):RESTORE 11000
10020 TOT=0:FOR X=1 TO 89:READ A:TOT=TOT+A:COORD1$(X,X)=CHR$(A):NEXT X:IF TOT<>9984 THEN ? "COORD1 ERR":END
10030 TOT=0:FOR X=1 TO 89:READ A:TOT=TOT+A:COORD2$(X,X)=CHR$(A):NEXT X:IF TOT<>9984 THEN ? "COORD2 ERR":END
10040 TOT=0:FOR X=1 TO 41:READ A:TOT=TOT+A:INIT$(X,X)=CHR$(A):NEXT X:IF TOT<>4237 THEN ? "INIT ERR":END
10050 TOT=0:FOR X=1 TO 29:READ A:TOT=TOT+A:EXPL$(X,X)=CHR$(A):NEXT X:IF TOT<>2198 THEN ? "EXPL ERR":END
10060 TOT=0:FOR X=1 TO 355:READ A:TOT=TOT+A:MAIN$(X,X)=CHR$(A):NEXT X:IF TOT<>36691 THEN ? "MAIN ERR":END
10070 REM *** SET UP PLOT BITS ***
10080 POKE 1568,192:POKE 1569,48:POKE 1570,12:POKE 1571,3
10090 REM *** INITIALIZE GRAPHIC VIOLENCE ROUTINE AND RETURN ***
10100 A=USR(ADR(INIT$),ADR(MAIN$),ADR(COORD1$),ADR(COORD2$),1,1)
10110 RETURN
11000 REM *** COORD1 DATA ***
11010 DATA 0,1,255,0,255,0,255,2,1,1,0,254,255,1,0,1,254,254,2,0,1,255,2,2,2,255,254,1,253,3,3,4,252,253,254
11020 DATA 255,254,2,3,3,253,0,0,0,4,4,252,255,2,0,3,2,1,253,254,254,252,253,3,253,252,251,251,252,4,3,4,255
11030 DATA 5,5,5,253,1,254,0,255,252,253,251,253,252,3,4,3,1,255,1,2,4
12000 REM *** COORD2 DATA ***
12010 DATA 0,255,1,2,254,255,0,1,254,0,1,0,255,1,253,253,2,255,255,254,2,3,2,0,254,2,1,3,254,1,254,255,0,1,253
12020 DATA 253,254,3,2,0,3,252,4,3,0,2,2,4,4,5,3,253,252,0,3,4,254,252,252,2,1,1,0,255,254,255,1,251
12030 DATA 0,255,1,4,4,252,251,252,253,253,255,255,3,253,253,4,251,5,5,252,3
13000 REM *** INITIALIZATION CODE ***
13010 DATA 104,169,0,141,0,6,141,1,6,104,170,104,168,169,7
13020 DATA 32,92,228,104,133,204,104,133,203,104,133,206,104,133,205
13030 DATA 104,104,141,11,6,104,104,141,12,6,96
14000 REM *** EXPLOSION CALL CODE ***
14010 DATA 104,173,1,6,201,20,48,5,104,104,104,104,96,104,104
14020 DATA 141,2,6,104,104,141,3,6,169,1,141,0,6,96
14990 REM *** MAIN INTERRUPT CODE ***
15000 DATA 216,165,16,41,127,133,16,141,14,210,173,11,6,240,20
15010 DATA 173,14,6,24,105,16,141,14,6,173,198,2,41,15,13
15020 DATA 14,6,141,198,2,173,12,6,240,22,173,13,6,240,17
15030 DATA 56,233,1,141,13,6,74,74,74,141,1,210,169,40,141
15040 DATA 0,210,173,0,6,240,31,238,1,6,174,1,6,173,2
15050 DATA 6,157,64,6,173,3,6,157,85,6,169,127,141,13,6
15060 DATA 169,0,157,106,6,141,0,6,141,5,6,238,5,6,173
15070 DATA 1,6,205,5,6,16,3,76,98,228,174,5,6,169,0
15080 DATA 141,4,6,189,106,6,201,89,48,51,238,4,6,56,233
15090 DATA 89,201,89,48,41,138,168,232,236,1,6,240,2,16,21
15100 DATA 189,64,6,153,64,6,189,85,6,153,85,6,189,106,6
15110 DATA 153,106,6,200,208,227,206,1,6,206,5,6,169,0,240
15120 DATA 176,254,106,6,168,189,64,6,24,113,203,141,6,6,201
15130 DATA 160,176,159,189,85,6,24,113,205,141,7,6,201,96,176
15140 DATA 146,10,133,207,169,0,240,2,240,137,133,208,165,207,10
15150 DATA 133,207,165,208,42,133,208,165,207,10,133,207,141,9,6
15160 DATA 165,208,42,133,208,141,8,6,165,207,10,133,207,165,208
15170 DATA 42,133,208,165,207,10,133,207,165,208,42,133,208,165,207
15180 DATA 24,109,9,6,133,207,165,208,109,8,6,133,208,165,88
15190 DATA 24,101,207,133,207,165,89,101,208,133,208,173,6,6,41
15200 DATA 3,168,190,32,6,142,10,6,173,6,6,74,74,24,101
15210 DATA 207,133,207,165,208,105,0,133,208,160,0,173,4,6,208
15220 DATA 11,173,10,6,81,207,145,207,169,0,240,132,173,10,6
15230 DATA 73,255,49,207,145,207,169,0,240,241

D:CHECK DATA

10 DATA 280,584,117,872,443,39,803,938,42,503,948,583,773,754,453,8132
10820 DATA 663,814,280,321,554,442,562,706,821,779,332,901,124,164,556,8019
12010 DATA 151,34,36,734,44,907,884,831,254,592,785,494,178,812,217,6945
15040 DATA 696,834,922,296,863,301,996,27,550,398,634,887,664,954,378,9392
15190 DATA 817,737,589,518,917,3498

LISTING 2

130 REM ***************************
140 REM *  GRAPHIC VIOLENCE DEMO  *
150 REM *        NUMBER 1         *
160 REM ***************************
170 REM
180 REM *** SET UP GRAPHIC MODE 7 ***
190 GRAPHICS 7+16
200 REM *** SET OFF AN EXPLOSION ***
210 REM *** AT SCREEN CENTER     ***
220 A=USR(ADR(EXPL$),80,48)
230 REM *** WAIT A FEW SECONDS ***
240 FOR WAIT=1 TO 2000: NEXT WAIT
250 REM *** DO EXPLOSION AGAIN ***
260 GOTO 220

LISTING 3

130 REM ***************************
140 REM *  GRAPHIC VIOLENCE DEMO  *
150 REM *        NUMBER 2         *
160 REM ***************************
170 REM
180 REM *** SET UP GRAPHICS 7 FULL SCREEN AND EXPLOSION COLOR ***
190 GRAPHICS 7+16:SETCOLOR 2,15,15
200 REM *** DRAW THE 'GROUND' ***
210 COLOR 1:FOR Y=20 TO 95:PLOT 0,Y:DRAWTO 159,Y:NEXT Y
220 REM *** TRAP ANY ERRORS TO 'THE END' ROUTINE ***
230 TRAP 320
240 REM *** RANDOMIZE START POINT FOR DROPPING BOMBS ***
250 X=5+RND(0)*149:Y=RND(0)*3
260 REM *** ADVANCE THE BOMB AS IT DROPS ***
270 COLOR 0:PLOT X,Y:Y=Y+3
280 REM *** IF THE BOMB HITS COLOR 1, SET OFF EXPLOSION ***
290 LOCATE X,Y,Z:IF Z=1 THEN A=USR(ADR(EXPL$),X,Y):GOTO 250
300 REM *** NO HIT, CONTINUE DROP ***
310 COLOR 2:PLOT X,Y:FOR DELAY=1 TO 10:NEXT DELAY:GOTO 270
320 REM *** 'THE END' ***
330 GRAPHICS 7+16:SETCOLOR 2,15,15:COLOR 1
340 REM *** PLOT 'THE END' ***
350 RESTORE 400:FOR X=1 TO 22:READ FRX,FRY,TUX,TUY:PLOT FRX,FRY:DRAWTO TUX,TUY:NEXT X
360 REM *** SET OFF 200 RANDOM EXPLOSIONS ***
370 FOR EXPL=1 TO 200:A=USR(ADR(EXPL$),48+RND(0)*75,20+RND(0)*55):FOR DELAY=1 TO 40:NEXT DELAY:NEXT EXPL
380 REM *** LET EXPLOSIONS DIE, THEN RE-RUN THE DEMO ***
390 FOR DELAY=1 TO 2000:NEXT DELAY:GOTO 190
400 REM *** 'THE END' DATA ***
410 DATA 50,25,67,25,59,25,59,45,72,25,72,45,72,35,88,35,88,25,88,45,93,25,93,45,93,25,109,25,93,35,109,35
420 DATA 93,45,109,45,50,50,50,70,50,50,67,50,50,60,67,60,50,70,67,70,72,70,72,50,72,50,88,70,88,70,88,50
430 DATA 93,50,93,70,93,50,102,50,102,50,109,56,109,56,109,64,109,64,102,70,102,70,93,70

LISTING 4

0100 ; GRAPHIC VIOLENCE
0110 ; 
0120 ; A.N.A.L.O.G. COMPUTING #8
0130 ;
0140 ; INITIALIZATION CODE
0150 ;
0160 READY = $600
0170 EXPCNT = $601
0180 CYCFLG = $60B
0190 SNDFLG = $60C
0200 COORD1 = $C0
0210 COORD2 = $CD
0220 SETVBV = $E45C
0230  *= $6000
0240 INIT PLA         ;DISCARD
0250  LDA #0          ;ZERO OUT:
0260  STA READY       ;READY FLAG
0270  STA EXPCNT      ;# OF EXPL.
0280  PLA             ;INTERRUPT HI
0290  TAX             ;PUT IN X
0300  PLA             ;INTERRUPT LO
0310  TAY             ;PUT IN Y
0320  LDA #7          ;DEFERRED VBI
0330  JSR SETVBV      ;SET IT!
0340  PLA             ;COORD1 HI
0350  STA COORD1+1    ;SAVE IT
0360  PLA             ;PULL COORD1 LO
0370  STA COORD1      ;SAVE IT
0380  PLA             ;PULL COORD2 HI
0390  STA COORD2+1    ;SAVE IT
0400  PLA             ;PULL COORD2 LO
0410  STA COORD2      ;SAVE IT
0420  PLA             ;DISCARD
0430  PLA             ;PULL COLOR CYCLE FLAG
0440  STA CYCFLG      ;SAVE IT
0450  PLA             ;DISCARD
0460  PLA             ;PULL SOUND FLG
0470  STA SNDFLG      ;SAVE IT
0480  RTS             ;FINISHED!
0490  .END

LISTING 5

0100 ; GRAPHIC VIOLENCE
0110 ;
0120 ; A.N.A.L.O.G. COMPUTING #8
0130 ;
0140 ; EXPLOSION CALL ROUTINE
0150 ;
0160 READY = $600
0170 EXPCNT = $601
0180 NEWX = $602
0190 NEWY = $603
0200  *=$6000
0210  PLA             ;DISCARD
0220  LDA EXPCNT      ;# OF EXPL.
0230  CMP #20         ;20 ACTIVE?
0240  BMI EXPOK       ;NO, IT'S OK!
0250  PLA             ;YES, DISCARD
0260  PLA             ;BOTH COORDS
0270  PLA
0280  PLA
0290  RTS             ;AND EXIT
0300 EXPOK PLA        ;DISCARD HIGH
0310  PLA             ;GET X-COORD
0320  STA NEWX        ;STORE IT
0330  PLA             ;DISCARD HIGH
0340  PLA             ;GET Y-COORD
0350  STA NEMY        ;STORE IT
0360  LDA #1          ;TELL INTERRUPT
0370  STA READY       ;WE'RE READY!
0380  RTS             ;AND EXIT BACK
0390 ;                 TO BASIC!
0400  .END

LISTING 6

0100 ; GRAPHIC VIOLENCE
0110 ;
0120 ; A.N.A.L.O.G. COMPUTING #8
0130 ;
0140 ; VBLANK INTERRUPT ROUTINE
0150 ;
0160 READY = $600
0170 EXPCNT = $601
0180 NEWX = $602
0190 NEWY = $603
0200 PLOTCLR = $604
0210 COUNTR = $605
0220 PLOTX = $606
0230 PLOTY = $607
0240 HIHLD = $608
0250 LOHLD = $609
0260 PLOTBVT = $60A
0270 CYCFLG = $60B
0280 SNDFLG = $60C
0290 SNDCNT = $60D
0300 COLOR = $60E
0310 PLOTBL = $620
0320 XPOS = $640
0330 YPOS = XPOS+21
0340 CNT = YPOS+21
0350 LO = $CF
0360 HI = $D0
0370 COORD1 = $CB
0380 COORD2 = $CD
0390 ;
0400 ;SYSTEM EQUATES
0410 ;
0420 XITVBV = $E462
0430 COLPF2 = $2C6
0440 AUDC1 = $D201
0450 AUDF1 = $D200
0460 SAVMSC = $58
0470 POKMSK = $10
0480 IRQEN = $D20E
0490   *=$6000
0500  CLD             ;CLEAR DECIMAL
0510  LDA POKMSK      ;GET IRQ INT.
0520  AND #$7F        ;NO BREAK KEY
0530  STA POKMSK      ;THE BREAK KEY
0540  STA IRQEN       ;IS NOW OFF!
0550  LDA CYCFLG      ;CYCLING COLOR?
0560  BEQ CONT        ;NO, CONTINUE
0570  LDA COLOR       ;GET LAST COLOR
0580  CLC             ;INCREMENT IT
0590  ADC #16         ;BY 16
0600  STA COLOR       ;AND SAVE IT
0610  LDA COLPF2      ;GET COLOR REG.
0620  AND #$0F        ;GET BRIGHTNESS
0630  ORA COLOR       ;ADD THE COLOR
0640  STA COLPF2      ;AND SAVE IT!
0650 CONT LDA SNDFLG  ;SOUND ON?
0660  BEQ GO          ;NO, SKIP IT!
0670  LDA SNDCNT      ;MORE SOUND?
0680  BEQ GO          ;NO, SKIP IT!
0690  SEC             ;DECREMENT THE
0700  SBC #1          ;SOUND COUNTER
0710  STA SNDCNT      ;AND STORE IT
0720  LSR A           ;SHIFT DOWN TO
0730  LSR A           ;DERIVE VOLUME
0740  LSR A           ;FROM COUNTER
0750  STA AUDC1       ;SET UP SOUND
0760  LDA #40         ;CHANNEL 1...
0770  STA AUDF1       ;FINISHED!
0780 GO LDA READY     ;NEW EXPLOSION?
0790  BEQ MAIN        ;NO, CONTINUE
0800 ;
0810 ;AT THIS POINT, THERE IS A
0820 ;NEW EXPLOSION!
0830 ;
0840  INC EXPCNT      ;ONE MORE EXPL
0850  LDX EXPCNT      ;PUT IN INDEX
0860  LDA NEWX        ;GET X-COORD,
0870  STA XPOS,X      ;PUT IN TABLE
0880  LDA NEWY        ;GET Y-COORD,
0890  STA YPOS,X      ;PUT IN TABLE
0900  LDA #127        ;INITIALIZE THE
0910  STA SNDCNT      ;SOUND COUNTER
0920  LDA #0          ;INIT COUNTER
0930  STA CNT,X       ;FOR EXPL IMAGE
0940  STA READY       ;AND READY FLAG
0950 MAIN STA COUNTR  ;ZERO COUNTER
0960 RUNLP INC COUNTR ;NEXT EXPLOSION
0970  LDA EXPCNT      ;GET # OF EXPL.
0980  CMP COUNTR      ;ANY MORE EXPL?
0990  BPL INDEX       ;YES, CONTINUE
1000  JMP XITVBV
1010 INDEX LDX COUNTR ;GET INDEX
1020  LDA #0          ;SET PLOTCLR
1030  STA PLOTCLR     ;0=PLOT A BLOCK
1040  LDA CNT,X       ;GET COUNTER
1050 ;                 FOR EXPLOSION
1060  CMP #89         ;ALL DRAWN?
1070  BMI DOPLOT      ;NO, DO IT NOW
1080  INC PLOTCLR     ;1=ERASE BLOCK
1090  SEC             ;GET READY FOR
1100  SBC #89         ;ERASE CYCLE
1110  CMP #89         ;ERASE DONE?
1120  BMI DOPLOT      ;NO, ERASE BLOCK
1130  TXA             ;MOVE INDEX
1140  TAY             ;TO Y REGISTER
1150 ;
1160 ;THE FOLLOWING ROUTINE REPACKS
1170 ;THE EXPLOSION TABLE TO GET RID
1180 ;OF EXPLOSIONS THAT ARE DONE.
1190 ;
1200 REPACK INX       ;NEXT EXPLOSION
1210  CPX EXPCNT      ;DONE?
1220  BEQ RPK2        ;NO, REPACK MORE
1230  BPL RPKEND      ;YES, EXIT!
1240 RPK2 LDA XPOS,X  ;NO, START RPK
1250  STA XPOS,Y      ;MOVE BACK X
1260  LDA YPOS,X
1270  STA YPOS,Y      ;MOVE BACK Y
1280  LDA CNT,X
1290  STA CNT,Y       ;MOVE BACK CNT
1300  INY
1310  BNE REPACK      ;NEXT REPACK
1320 RPKEND DEC EXPCNT ;DEC POINTERS
1330  DEC COUNTR      ;DUE TO REPACK
1340  LDA #8          ;FORCE BRANCH
1350  BEQ RUNLP       ;TO NEXT EXPL.
1360 DOPLOT INC CNT,X ;INC COUNTER
1370  TAY             ;EXP PHASE IN Y
1380  LDA XPOS,X      ;GET X-COORD
1390  CLC
1400  ADC (COORD1),Y  ;ADD X OFFSET
1410  STA PLOTX       ;STORE IT
1420  CMP #168        ;OFF SCREEN?
1430  BCS RUNLP       ;YES, DON'T PLOT
1440  LDA YPOS,X      ;GET Y-COORD
1450  CLC
1460  ADC (COORD2),Y  ;ADD Y OFFSET
1470  STA PLOTY       ;STORE IT
1480  CMP #96         ;OFF SCREEN?
1490  BCS RUNLP       ;YES, DON'T PLOT
1500 ;
1510 ;THE FOLLOWING SECTION IS A
1520 ;DEDICATED MULTIPLY ROUTINE
1530 ;WHICH MULTIPLIES THE A REGISTER
1540 ;BY 40, WITH RESULT IN LO & HI
1550 ;
1560  ASL A
1570  STA LO
1580  LDA #8
1590  BEQ X2
1600 JRUNLP BEQ RUNLP
1610 X2 STA HI      ;*2
1620  LDA LO
1630  ASL A
1640  STA LO
1650  LDA HI
1660  ROL A
1670  STA HI        ;*4
1680  LDA LO
1690  ASL A
1700  STA LO
1710  STA LOHLD
1720  LDA HI
1730  ROL A
1748  STA HI
1750  STA HIHLD     ;*8
1760  LDA LO
1770  ASL A
1780  STA LO
1790  LDA HI
1800  ROL A
1818  STA HI        ;*16
1820  LDA LO
1830  ASL A
1840  STA LO
1850  LDA HI
1860  ROL A
1870  STA HI        ;*32
1880  LDA LO
1890  CLC
1900  ADC LOHLD
1910  STA LO
1920  LDA HI
1930  ADC HIHLD
1940  STA HI        ;+*8=*46
1950 ;
1960 ;AT THIS POINT, THE MULTIPLY BY
1970 ;40 IS FINISHED, AND WE NEED TO
1980 ;GET AN OFFSET INTO THE SCREEN
1990 ;MEMORY
2000 ;
2010  LDA SAVMSC     ;ADD THE DISPLAY
2020  CLC            ;ADDRESS TO GET
2030  ADC LO         ;THE ACTUAL
2040  STA LO         ;ADDRESS OF THE
2050  LDA SAVMSC+1   ;BYTE THAT HILL
2060  ADC HI         ;BE ALTERED FOR
2070  STA HI         ;THE PLOT.
2080  LDA PLOTX      ;MASK PLOTX FOR
2090  AND #3         ;THE PLOT AND
2180  TAY            ;PLACE IN Y REG
2110  LDX PLOTBL,Y   ;GET PLOT BITS,
2120  STX PLOTBYT    ;AND SAVE!
2130  LDA PLOTX      ;GET PLOTX AND
2140  LSR A          ;DIVIDE
2150  LSR A          ;BY 4
2160  CLC            ;AND ADD TO
2170  ADC LO         ;PLOT ADDRESS
2180  STA LO         ;FOR FINAL PLOT
2190  LDA HI         ;ADDRESS.
2200  ADC #0
2210  STA HI
2220  LDY #6         ;ZERO OUT Y REG.
2230  LDA PLOTCLR    ;ERASING?
2240  BNE CLEARIT    ;YES,GO CLEAR IT
2250  LDA PLOTBYT    ;GET PLOT BITS,
2260  EOR (LO),Y     ;ALTER DISPLAY,
2270  STA CL01,Y     ;AND PLOT IT!
2280  LDA #6         ;FORCE BRANCH
2290 JRUNLP2 BEQ JRUNLP ;AND EXIT!
2300 CLEARIT LDA PLOTBYT ;PLOT BITS
2310  EOR #$FF       ;FLIP 'EM
2320  AND (LO),Y     ;ALTER DISPLAY
2330  STA (LO),Y     ;AND ERASE IT!
2340  LDA #0         ;FORCE BRANCH
2350  BEQ JRUNLP2    ;AND EXIT!
2360  .END