6: Advanced Techniques
Starshot
Matt Giwer
As this game will demonstrate, Atari BASIC can be fast enough if you know how to speed it up. Requires 24K and game paddles.

Atari graphics approach those available in dedicated graphics-oriented computers. Atari BASIC allows very fast manipulation of strings, Direct Memory Access for the Player/Missile Graphics, and the direct call of machine language from BASIC. This game combines all of these features and a few others.

Let's start the discussion of this program with the subroutine at line 30000. The first thing to do is to enable the Player/Missile Graphics.

Appendix A of the Atari Hardware Manual gives a detailed example of how to do this. This method works only when there is nothing on the screen; as soon as you write to the screen, the method fails. The usual approach is to reserve enough pages for the screen RAM, the Player/Missile graphics pages, etc. All in all, to use Player/Missile Graphics with GRAPHICS 7, you wind up reserving 32 pages and, in the process, taking care of the computer rather than letting the operating system (OS) take care of you. Here is how to do it right.

RAMTOP

Contained in register 106 is the number of pages of RAM available to you for your use after everything needed for the system has been accounted for. What we want to do is to change this number so that RAM is protected for the Player/Missile Graphics pages. This is accomplished by POKE 106, PEEK(106)-16. This puts a number into that register that is 16 pages less than the number the operating system determines upon powering up the computer or upon system reset. But just POKEing a new number does nothing until the computer makes use of it.

The second GRAPHICS 7 call causes the operating system to make use of this new RAMTOP to relocate the screen RAM and the display list below RAMTOP. If you do not make this graphics call, you will find that the screen memory is above the new, lower protected memory limit, and the system will crash at the first attempt to scroll the screen. In other words, your system registers that point to the first screen byte, and the display list will be above RAMTOP. The operating system cannot handle this.

You proceed as normal but much more cleanly now that you have lowered the effective top of your RAM and made the operating system reorganize itself around that new maximum RAM with the second graphics call. Lines 30204 and 30206 are the enabling POKEs for Player/Missile Graphics as described in many articles and in De Re Atari. Line 30208 is the POKE to tell the operating system where to find the start of the Player/Missile data. The start of this data is now simply RAMTOP.

With Player/Missile Graphics set up this way, you can forget about what the rest of the system is doing and treat it just as though Player/Missile Graphics were not in use. The operating system will take care of you.

Player Definition

The next routine of interest is at line 30236. (This is the machine language routine published in COMPUTE!'s First Book of Atari Graphics, page 164.) It provides relocation of the four players at machine language speeds by means of two POKEs and, since the routine is executed during the vertical blanking time, the motion appears to be continuous. The rest of the 30000 lines define the players. Note that the RESTORE in line 30310 makes Player 3 the same as Player 2, although it is defined as a different color in line 30230.

Now let's jump to lines 100-120—we will get to the earlier lines later. These lines are the definitions that will be used later for named subroutines. The use of named subroutines is a desirable feature that greatly aids program development.

Lines 1890-1930 are both the one-time calls and those such as DISPLAY that are needed to set up the game at the start.

The subroutine at line 10000 draws the background in the way that makes this illusion of motion possible. Note that each set of lines is drawn with a different COLOR and that the COLOR numbers rotate 1, 2, 3, 1, 2, 3, and so forth. I will get back to this in a minute.

Color Rotation Simulates Motion

The START subroutine at line 5000 POKEs numbers into the color registers so that you can see the screen and draws the eight attackers. You will also note that COLOR J also rotates the COLOR assigned to the attacker graphic although in a more complex manner than in BACKGROUND.

The DISPLAY subroutine at line 6300 controls the scoring and number of lives information that will be shown in the bottom alphanumeric window.

ASELECT at line 6500 picks the order in which the attackers will attack from among the predefined ATTACK1-4$ in lines 54 and 60.

Within the infinite loop at line 2100 you'll find the reason why I used different COLORs to draw the background. The four statements in line 2110 rotate the colors used in the background through the registers in a bucket brigade manner; the colors seem to be moving toward you. Given the drawn background, it appears that you are moving forward through the trench. This illusion of motion requires the use of three different colors as a minimum. If there were only two colors, they would appear to flicker back and forth rather than move. The instructions in this line will be used in almost every subroutine so that this illusion of motion is maintained.

This technique is useful in many applications—you can simulate many kinds of motion. If you were to reverse the order of the instructions, you would have the illusion of going backwards. Line 2120 is simply a short delay.

Another line that you will find throughout the program is first used at line 5017. A=74+PADDLE(0)/2.92 is the equation that limits the motion of Player 0 on the screen. The farthest left X location that Player 0 can move to is 74. The range of values for the PADDLE(0) is 0 to 228. Dividing this range of values by 2.92 converts the largest value of 228 to the rightmost location of Player 0 and makes the fulileft-to-right motion of the Player a full turn of the PADDLE. In order to simulate continuous motion, this equation is also put into every subroutine where the program execution takes a noticeable amount of time.

The subroutine MOVE at line 5100 is a loitering loop that waits a random number of loops until the first attack begins. When the number 50 is reached, program execution jumps to SELECT at line 5200.

The SELECT subroutine picks the sequence of the attackers from ATTACK1$ through ATTACK4$. ATTACK$ for the first wave was initially called in line 1930. This routine randomly picks one of the four attack sequences defined in lines 54 and 60. An attempt to read the ninth element in this string is TRAPped to line 5211, which redraws the attackers and starts over.

Note this use of the TRAP instruction. It is not meant simply to avoid a program crash, but rather to perform an integral program function. Rather than a RAM and time-consuming test or loop, one simple statement is used.

Lines 5215-5240 erase the chosen attacker, position Player 1 over the erased attacker, and give some warning sounds. Line 5241 calls the subroutine JOIN at line 5800. This routine adds together the strings which are used to define the X and Y positions of Player 1 as it moves from its initial position to its attack position.

Special TRAPs

The strings are the AX1$ and AY1$ through AX8$ and AY8$ that were defined back in the beginning of the program. These are the X and Y coordinates to be POKEd into PLX+1 and PLY+1. They are stored as groups of three numbers. These values are read in lines 5260-5270. Note that by using TRAP here I do not have to keep track of the number of elements in the string. And again instead of some test or loop, a simple statement is used. These strings are merely added together. No matter what the sequence of the attack, the last pattern is always the same, and the last set numbers in the string is always the same.

The ATTACK subroutine at line 5300 is where the shooting occurs. The first call is for the subroutine PATTERN at line 5600. This subroutine chooses among five possible X position patterns and five possible Y position patterns. These are the rest of the strings defined in the beginning of the program. This independent choice of X and Y patterns permits a total of 25 different attack patterns.

In line 5315, the X and Y values for this attack motion are read out in groups of three. In this case, the TRAP is used to jump back to the PATTERN subroutine call to pick another pair of strings when the end of the STRING is reached. This gives continuously varying motion to the attacker.

Lines 5324 and 5325 change the size of the attacker as it comes closer or goes farther away. F and G are flags that control the firing and motion of the missiles. It is worth examining how these flags function.

F controls the attacker's missile firing. Other than its housekeeping function, the primary purpose of the IF F=0 is to fix the X and Y location at the moment of firing so that the motion is calculated only from this point. After F is set to 1, these statements are no longer executed. If they were, the missile would weave back and forth in X and Y in unison with the attacker. Behind the F=1 flag are the calculations that determine whether the missile passes to the left or to the right. The G flag performs a similar program function.

Lines 5350 and 5352 check for missile-to-player collisions and direct action to the appropriate subroutine. Line 5355 clears the collision registers.

HITYOU, HITME, HITUS

The HITYOU, HITME, and HITUS subroutines introduce Players 2 and 3 as the explosions. In HITYOU and HITME, these two players are sequentially put in the same location as the hit player. This sequence is controlled by the TT variable. Note that the two explosion shapes are the same but of different colors. Also, when they are called, they are placed one Y position different. The purpose is to give some illusion of a dynamic explosion.

Lines 5440 and 5540 move the hit player and explosions off the screen. The logical truth statements determine whether the hit player was to the left or right of center when hit and then move it off the screen to the left or right as appropriate. Lines 5545 and 5547 cause the attacker and the explosions to grow larger as they go by.

The significant difference in the two subroutines is that in HITYOU there is an additional collision test in line 5560. This requires you to get out of the way of the hit player as it rolls off the screen. If you don't, you are also destroyed, and both players roll off the screen. This is controlled by the HITUS subroutine. Being hit by the attacker's missile and by the damaged attacker causes you to lose one life.

Good Practice

This is a quick review of a fairly complex program. It exploits many of the Atari's features. The method of reserving the Player/ Missile Graphics pages by moving RAMTOP lets the machine take care of you and perhaps completes the official Atari version of how to tum on the function.

Starshot
40 J=66:PX=5
50 DIM ATTACK$(8),AX5$(J),AY5$(J),AX$(3*J),AY$(3*J),APX1$(J),APY1$(J),APX$(J),APY$(J)
51 DIM AX4$(J),AY4$(J),APX2$(J),APY2$(J),APX3$(J),APY3$(J),APX4$(J),APY4$(J),APX5$(J),APY5$(J)
52 DIM AX3$(J),AY3$(J),AX2$(J),AY2$(J),AX6$(J),AY6$(J),AX7$(J),AY7$(J),AY8$(J),AX8$(J),AX1$(J),AY1$(J)
53 DIM PLAYER$(10),ATTACK1$(8),ATTACK2$(8),ATTACK3$(8),ATTACK4$(8)
54 ATTACK2$="37628415":ATTACK3$="28647135":ATTACK4$="47618325"
60 ATTACK1$="54637281":PLAYER$="1 2 3 4 5"
61 AX5$="136136135134133132131130129128127126124122121121122123124125126126"
62 AY5$="038037035034034034035037039041043045047049052056059062065068071074"
63 AX4$="118120122124126128130132134134132130128126126126126126126126126126"
64 AY4$="036034032030028030032034037040043050057063070076082080078076075074"
65 AX6$="156154152150148146144142140138136"
66 AY6$="038036034033034036038040042040038"
67 AX2$="078080082084086088090092094096098"
68 AY2$="038042044046048050052049046042038"
69 AX1$="058060062064066068070072074076078"
70 AY1$="038035031035038042046048046042038"
71 AX3$="098100102104106108110112114116118"
72 AY3$="040044048046044042040038036037038"
73 AX7$="176174172170168166164162160158156"
74 AY7$="038036034032030033036039042040038"
75 AX8$="196194192190188186184182180178176"
76 AY8$="040044048046044042040038036036038"
83 APX1$="126120114110110114120126132138142142138132126120114110110114120126"
84 APY1$="074077082090095100104105107109112114112109107105104100095090082077"
85 APX2$="126128130134138142142136130124121118110107104107110118120124126128"
86 APY2$="074079084086088094100106110114110108106100094087080080080078076075"
87 APX3$="126130134138142146142138134130126126130134138142144142138134130126"
88 APY3$="074074074074074082086090098106114120114106098090086082074074074074"
89 APX4$="126134142134126118110110126134142134126118110110126134142132126126"
90 APY4$="074078082086092086082078074078082086092096092088084080076072072074"
91 APX5$="126132138144150156162156150144138132126120116110104098104110116126"
92 APY5$="074070068070074080084090096102106102096092086082078076074070072074"
100 BACKGROUND=10000:START=5000:MOVE=5100:SELECT=5200:ATTACK=5300:HITME=5400:HITYOU=5500
110 PATTERN=5600:RESET=5700:JOIN=5800:HITUS=5900
120 XSCR=6000:YSCR=6100:LOSS=6200:DISPLAY=6300:RESET2=6400:ASELECT=6500
1890 GOSUB 30000
1900 GOSUB BACKGROUND
1910 GOSUB START
1920 GOSUB DISPLAY
1930 GOSUB ASELECT
2000 REM CONTROL LOOP
2100 FOR IJK=1 TO 2 STEP 0
2110 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
2120 Q=SIN(1)
2130 GOSUB MOVE
2900 NEXT IJK
5000 REM START
5005 POKE 708,10:POKE 709,0:POKE 710,56:POKE PLY,150:POKE 53761,132:REM 709,152
5010 FOR I=1 TO 8
5011 FOR J=0 TO 2
5016 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5017 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5019 COLOR J*I:IF J*I=4 OR J*I=0 OR J*I=8 OR J*I=12 OR J*I=16 THEN COLOR 1
5020 PLOT 20*I-10,J:DRAWTO 20*I-11,J
5021 COLOR J*I:IF J*I=4 OR J*I=0 OR J*I=8 OR J*I=12 OR J*I=16 THEN COLOR 2
5022 PLOT 20*I-8,J+3:DRAWTO 20*I-12,J+3
5025 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5033 COLOR J*I:IF J*I=4 OR J*I=0 OR J*I=8 OR J*I=12 OR J*I=16 THEN COLOR 3
5034 PLOT 20*I-8,J+6:DRAWTO 20*I-9,J+6:PLOT 20*I-12,J+6:DRAWTO 20*I-11,J+6
5036 NEXT J:NEXT I
5090 RETURN 
5100 REM MOVE
5105 FOR IJK=1 TO 2 STEP 0
5110 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5111 A=SIN(1)
5120 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5130 RR=RR+1:IF RR=50 THEN GOSUB SELECT:RR=INT(40*RND(0)):POKE 53763,0:POKE 53761,132
5185 NEXT IJK
5190 RETURN 
5200 REM SELECT
5205 JJJ=JJJ+1
5210 TRAP 5211:R=VAL(ATTACK$(JJJ,JJJ)):COLOR 0:GOTO 5215:TRAP 40000
5211 GOSUB START:JJJ=0:GOTO 5205
5215 FOR J=0 TO 2
5220 PLOT 20*R-10,J:DRAWTO 20*R-11,J
5223 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5224 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5225 PLOT 20*R-8,8-J:DRAWTO 20*R-9,8-J:PLOT 20*R-12,8-J:DRAWTO 20*R-11,8-J
5230 NEXT J
5235 PLOT 20*R-8,3:DRAWTO 20*R-12,3:PLOT 20*R-8,5:DRAWTO 20*R-12,5
5236 POKE PLX+1,36+20*R:POKE PLY+1,38:PLOT 20*R-8,4:DRAWTO 20*R-12,4
5238 FOR Z=250 TO 50 STEP -50:FOR X=15 TO 0 STEP -5:SOUND 3,Z,8,X:NEXT X
5239 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5240 NEXT Z
5241 GOSUB JOIN
5249 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP:POKE 53763,134
5250 A=86+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5255 FOR J=1 TO 200
5260 TRAP 5280:X=VAL(AX$(J*3-2,J*3)):Y=VAL(AY$(J*3-2,J*3)):POKE PLX+1,X:POKE PLY+1,Y:TRAP 40000:POKE 53762,Y-20
5265 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5266 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5270 NEXT J
5280 GOSUB ATTACK:GOSUB RESET
5290 RETURN 
5300 REM ATTACK
5305 GOSUB PATTERN
5310 FOR J=1 TO 200
5315 TRAP 5305:X=VAL(APX$(J*3-2,J*3)):Y=VAL(APY$(J*3-2,J*3)):TRAP 40000
5321 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5322 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53760,A-33
5324 IF Y>94 THEN POKE 53257,1:POKE 53258,1
5325 IF Y<94 THEN POKE 53257,0:POKE 53258,0
5330 POKE PLX+1,X:POKE PLY+1,Y:POKE 53762,Y-20
5333 IF F=0 THEN M1P=MYPMBASE+777+Y:POKE 53253,X:POKE M1P,12:M1PO=M1P:T=MYPMBASE+907+Y:XT=X
5335 IF F=0 THEN F=1:POKE 53765,207:POKE 53764,100
5337 IF F=1 THEN M1P=M1P+7:XT=(-1.5+XT)*(XT<128)+(1.5+XT)*(XT>128):POKE 53253,XT:POKE M1P,12:POKE M1PO,0
5338 IF F=1 THEN M1PO=M1P:POKE 53765,160:IF M1P>T-50 THEN F=0:POKE M1PO,0
5339 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5340 IF G=0 THEN IF PTRIG(0)=0 THEN M0P=MYPMBASE+768+150:PT=80+PADDLE(0)/2.29:POKE M0P,3:G=1:POKE 53252,PT
5342 IF G=1 THEN M0PO=M0P:T0=M0P-70:G=2:POKE 53765,15:POKE 53764,50
5347 IF G=2 THEN M0P=M0P-7:PT=(3.5+PT)*(PT<128)+(-3.5+PT)*(PT>128):POKE M0P,3:POKE M0PO,0
5349 IF G=2 THEN POKE 53252,PT:M0PO=M0P:POKE 53765,160:IF M0P<T0 THEN G=0:POKE M0PO,0
5350 IF PEEK(53256)=2 THEN GOSUB HITYOU
5352 IF PEEK(53257)=1 THEN GOSUB HITME:POKE M0PO,0:POKE M1PO,0
5355 POKE 53278,0
5375 NEXT J
5380 POKE PLX,PADDLE(0):POKE PLY,148
5395 RETURN 
5400 REM HITME
5405 POKE 53761,15:POKE M0PO,0:POKE M1PO,0:RR=0
5410 FOR J=1 TO 200
5412 IF TT=0 THEN POKE 53258,3:POKE PLY+2,144+RR:POKE PLX+2,A:POKE PLX,A:POKE PLY,148+RR:TT=1
5413 IF TT=1 THEN POKE 53259,3:POKE PLY+3,144+RR:POKE PLX+3,A:POKE PLX,A:POKE PLY,148+RR:TT=0
5415 TRAP 5410:X=VAL(APX$(J*3-2,J*3)):Y=VAL(APY$(J*3-2,J*3)):TRAP 40000
5421 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5424 IF Y>94 THEN POKE 53257,1:POKE 53258,1
5425 IF Y<94 THEN POKE 53257,0:POKE 53258,0
5427 POKE PLX+1,X:POKE PLY+1,Y:POKE 53762,Y+20
5430 IF TT=0 THEN POKE 53258,3:POKE PLY+2,144+RR:POKE PLX+2,A:POKE PLX+3,0:TT=1
5431 IF TT=0 THEN POKE 53258,3:POKE PLY+2,144+RR:POKE PLX+2,A:POKE PLX,A:POKE PLY,148+RR:TT=1
5432 IF TT=1 THEN POKE 53259,3:POKE PLY+3,144+RR:POKE PLX+3,A:POKE PLX,A:POKE PLY,148+RR:TT=0
5435 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5440 RR=(RR+7):A=(A+7)*(A>128)+(A-7)*(A<127):IF A<0 THEN J=201
5441 POKE 53760,RR
5442 IF A<0 OR A>255 THEN J=201
5444 IF 144+RR>255 THEN J=201
5490 NEXT J:GOSUB YSCR
5495 POKE PLY+2,229:POKE PLY+3,229:POKE 53761,0
5497 RETURN 
5500 REM HITYOU
5505 POKE 53763,15:POKE M0PO,0:POKE M1PO,0:RR=0:POKE M0P,0:POKE M1P,0
5510 FOR J=1 TO 200
5531 IF TT=0 THEN POKE PLY+2,Y-10:POKE PLX+2,X:POKE PLY+1,Y:POKE PLX+1,X:POKE PLX+3,0:TT=1
5532 IF TT=1 THEN POKE PLY+3,Y-9:POKE PLX+3,X:POKE PLY+1,Y:POKE PLX+1,X:POKE PLX+2,0:TT=0
5534 A=74+PADDLE(0)/2.92:POKE PLX,A:POKE 53762,Y:POKE 53760,41+PADDLE(0)/2.92
5540 Y=Y+7:X=(X+3.5)*(X>128)+(X-3.5)*(X<128)
5545 IF Y>94 THEN POKE 53257,1:POKE 53258,1:POKE 53259,1
5547 IF Y>130 THEN POKE 53257,3:POKE 53258,3:POKE 53259,3
5550 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5560 IF PEEK(53260)<>0 THEN GOSUB HITUS
5582 IF Y>255 THEN J=201
5584 IF X>255 OR X<0 THEN J=201
5590 NEXT J:GOSUB XSCR
5595 POKE PL2+2,0:POKE PLX+3,0:POKE 53763,0
5597 RETURN 
5600 REM SELECT PATTERN
5610 R=INT(5*RND(0))+1
5621 IF R=1 THEN APX$=APX1$
5622 IF R=2 THEN APX$=APX2$
5623 IF R=3 THEN APX$=APX3$
5624 IF R=4 THEN APX$=APX4$
5625 IF R=5 THEN APX$=APX5$
5626 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5630 R=INT(5*RND(0))+1
5641 IF R=1 THEN APY$=APY1$
5642 IF R=2 THEN APY$=APY2$
5643 IF R=3 THEN APY$=APY3$
5644 IF R=4 THEN APY$=APY4$
5645 IF R=5 THEN APY$=APY5$
5690 RETURN 
5700 REM RESET
5710 F=0:G=0:POKE 53257,0:POKE PLX+1,0
5790 RETURN 
5800 REM JOIN
5810 IF R=1 THEN AX$=AX1$:AX$(LEN(AX$)+1)=AX2$:AX$(LEN(AX$)+1)=AX3$:AX$(LEN(AX$)+1)=AX4$
5812 IF R=1 THEN AY$=AY1$:AY$(LEN(AY$)+1)=AY2$:AY$(LEN(AY$)+1)=AY3$:AY$(LEN(AY$)+1)=AY4$
5815 IF R=2 THEN AX$=AX2$:AX$(LEN(AX$)+1)=AX3$:AX$(LEN(AX$)+1)=AX4$
5817 IF R=2 THEN AY$=AY2$:AY$(LEN(AY$)+1)=AY3$:AY$(LEN(AY$)+1)=AY4$
5820 IF R=3 THEN AX$=AX3$:AX$(LEN(AX$)+1)=AX4$
5822 IF R=3 THEN AY$=AY3$:AY$(LEN(AY$)+1)=AY4$
5825 IF R=4 THEN AX$=AX4$:AY$=AY4$
5830 IF R=5 THEN AX$=AX5$:AY$=AY5$
5835 IF R=6 THEN AX$=AX6$:AX$(LEN(AX6$)+1)=AX5$
5837 IF R=6 THEN AY$=AY6$:AY$(LEN(AY6$)+1)=AY5$
5840 IF R=7 THEN AX$=AX7$:AX$(LEN(AX$)+1)=AX6$:AX$(LEN(AX$)+1)=AX5$
5842 IF R=7 THEN AY$=AY7$:AY$(LEN(AY$)+1)=AY6$:AY$(LEN(AY$)+1)=AY5$
5845 IF R=8 THEN AX$=AX8$:AX$(LEN(AX$)+1)=AX7$:AX$(LEN(AX$)+1)=AX6$:AX$(LEN(AX$)+1)=AX5$
5847 IF R=8 THEN AY$=AY8$:AY$(LEN(AY$)+1)=AY7$:AY$(LEN(AY$)+1)=AY6$:AY$(LEN(AY$)+1)=AY5$
5890 RETURN 
5900 REM HITUS
5905 POKE 53763,15:POKE M0PO,0:POKE M1PO,0:RR=0:POKE M0P,0:POKE M1P,0
5910 FOR J=1 TO 200
5931 POKE PLY+2,Y-10:POKE PLX+2,X:POKE PLY+1,Y:POKE PLX+1,X
5932 POKE PLY+3,Y-10:POKE PLX+3,A:POKE PLY,Y:POKE PLX,A
5940 Y=Y+7:X=(X+3.5)*(X>128)+(X-3.5)*(X<128):A=(A+3.5)*(A>112)+(A-3.5)*(A<112)
5950 TEMP=PEEK(710):POKE 710,PEEK(709):POKE 709,PEEK(708):POKE 708,TEMP
5982 IF Y>255 THEN J=201
5984 IF X>255 OR X<0 THEN J=201
5990 NEXT J:GOSUB YSCR
5995 POKE PL2+2,0:POKE PLX+3,0:POKE 53763,0
5997 RETURN 
6000 REM XSCR
6010 SCORE=SCORE+10
6020 PLAYER$(2*PX-1,2*PX-1)=" "
6080 GOSUB DISPLAY
6090 RETURN 
6100 REM YSCR
6125 PX=PX-1
6130 IF PX=0 THEN GOSUB LOSS
6180 GOSUB DISPLAY
6190 RETURN 
6200 REM LOSS
6210 IF SCORE>HSCR THEN HSCR=SCORE
6220 GOSUB DISPLAY
6280 GOSUB RESET2
6290 RETURN 
6300 REM DISPLAY
6305 POKE 53258,0:POKE 53259,0
6310 ? PLAYER$
6320 ? "SCORE:  ";SCORE
6330 ? "HIGH SCORE:  ";HSCR
6340 IF PX=0 THEN ? " PUSH TRIGGER FOR ANOTHER GAME";
6350 IF PX=0 THEN IF PTRIG(0)=1 THEN 6350:GOSUB RESET2:GOSUB ASELECT
6360 ? PLAYER$
6362 ? "SCORE:  ";SCORE
6364 ? "HIGH SCORE:  ";HSCR
6390 RETURN 
6400 REM RESET2
6410 SCORE=0:PLAYER$="1 2 3 4 5"
6430 PX=5
6490 RETURN 
6500 REM ASELECT
6510 ZZ=INT(4*RND(0))+1
6520 IF ZZ=1 THEN ATTACK$=ATTACK1$
6522 IF ZZ=2 THEN ATTACK$=ATTACK2$
6524 IF ZZ=3 THEN ATTACK$=ATTACK3$
6526 IF ZI=4 THEN ATTACK$=ATTACK4$
6590 RETURN 
10000 REM BACKGROUND
10005 FOR I=0 TO 3:POKE 708+I,0:NEXT I
10007 COLOR 3:PLOT 0,20:DRAWTO 70,20:DRAWTO 70,40:DRAWTO 90,40:DRAWTO 90,20:DRAWTO 159,20
10010 COLOR 1:FOR I=1 TO 2
10020 PLOT 0,20+I:DRAWTO 70-I,20+I:DRAWTO 70-I,40+I:DRAWTO 90+I,40+I:DRAWTO 90+I,20+I:DRAWTO 159,20+I:NEXT I
10040 COLOR 2:FOR I=1 TO 2
10050 PLOT 0,22+I:DRAWTO 68-I,22+I:DRAWTO 68-I,42+I:DRAWTO 92+I,42+I:DRAWTO 92+I,22+I:DRAWTO 159,22+I:NEXT I
10060 COLOR 3:FOR I=1 TO 3
10070 PLOT 0,24+I:DRAWTO 66-I,24+I:DRAWTO 66-I,44+I:DRAWTO 94+I,44+I:DRAWTO 94+I,24+I:DRAWTO 159,24+I:NEXT I
10080 COLOR 1:FOR I=1 TO 3
10090 PLOT 0,27+I:DRAWTO 63-I,27+I:DRAWTO 63-I,47+I:DRAWTO 97+I,47+I:DRAWTO 97+I,27+I:DRAWTO 159,27+I:NEXT I
10100 COLOR 2:FOR I=1 TO 5
10110 PLOT O,30+I:DRAWTO 60-I,30+I:DRAWTO 60-I,50+I:DRAWTO 100+I,50+I:DRAWTO 100+I,30+I:DRAWTO 159,30+I:NEXT I
10120 COLOR 3:FOR I=1 TO 5
10130 PLOT 0,35+I:DRAWTO 55-I,35+I:DRAWTO 55-I,55+I:DRAWTO 105+I,55+I:DRAWTO 105+I,35+I:DRAWTO 159,35+I:NEXT I
10140 COLOR 1:FOR I=1 TO 7
10150 PLOT 0,40+I:DRAWTO 50-I,40+I:DRAWTO 50-I,60+I:DRAWTO 110+I,60+I:DRAWTO 110+I,40+I:DRAWTO 159,40+I:NEXT I
10160 COLOR 2:FOR I=1 TO 7
10170 PLOT 0,47+I:DRAWTO 43-I,47+I:DRAWTO 43-I,67+I:DRAWTO 117+I,67+I:DRAWTO 117+I,47+I:DRAWTO 159,47+I:NEXT I
10180 COLOR 3:FOR I=1 TO 9
10190 PLOT 0,54+I:DRAWTO 36-I,54+I:DRAWTO 36-I,74+I:DRAWTO 124+I,74+I:DRAWTO 124+I,54+I:DRAWTO 159,54+I:NEXT I
10200 COLOR 1:FOR I=1 TO 12
10210 PLOT 0,63+I:DRAWTO 27-I,63+I:DRAWTO 27-I,83+I:DRAWTO 133+I,83+I:DRAWTO 133+I,63+I:DRAWTO 159,63+I:NEXT I
10220 COLOR 2:FOR I=1 TO 20
10230 PLOT 0,75+I:DRAWTO 14,75+I:PLOT 159,75+I:DRAWTO 145,75+I:NEXT I
10300 RETURN 
30000 REM *****PM SETUP*****
30010 GRAPHICS 7:POKE 106,PEEK(106)-16:GRAPHICS 7:POKE 752,1:REM *****16 PAGE RESERVE*****
30020 ? :? :? "{9 SPACES}PREPARE FOR COMBAT"
30204 POKE 53277,3:REM *****GRACTL PLAY&MISS*****
30206 POKE 559,62:REM *****DMACTL,1LINE,PLAY,MIS,NORM FIELD*****
30208 POKE 54279,PEEK(106):REM *****PMBASE IS NOW RAMTOP*****
30210 POKE 53256,3:POKE 53257,0:POKE 53258,0:POKE 53259,0:REM *****PLAY SIZES*****
30212 POKE 623,33:REM *****PRIORITY PL OVER PF*****
30214 MYPMBASE=256*PEEK(106):REM ?????NEW PMBASE?????
30230 POKE 704,134:POKE 705,24:POKE 706,46:POKE 707,54:POKE 1788,(PEEK(106)+4):REM ?????START OF PM DATA?????
30232 POKE 710,52:POKE 709,58:POKE 711,29:POKE 712,0
30236 REM *****VBLANK INTERUPT ROUTINE*****
30238 FOR I=1536 TO 1706:READ A:POKE I,A:NEXT I
30240 FOR I=1774 TO 1787:POKE I,0:NEXT I
30242 DATA 162,3,189,244,6,240,89,56,221,240,6,240,83,141,254,6,106,141
30244 DATA 255,6,142,253,6,24,169,0,109,253,6,24,109,252,6,133,204,133
30246 DATA 206,189,240,6,133,203,173,254,6,133,205,189,248,6,170,232,46,255
30248 DATA 6,144,16,168,177,203,145,205,169,0,145,203,136,202,208,244,76,87
30250 DATA 6,160,0,177,203,145,205,169,0,145,203,200,202,208,244,174,253,6
30252 DATA 173,254,6,157,240,6,189,236,6,240,48,133,203,24,138,141,253,6
30254 DATA 109,235,6,133,204,24,173,253,6,109,252,6,133,206,189,240,6,133
30256 DATA 205,189,248,6,170,160,0,177,203,145,205,200,202,208,248,174,253,6
30258 DATA 169,0,157,236,6,202,48,3,76,2,6,76,98,228,0,0,104,169
30260 DATA 7,162,6,160,0,32,92,228,96
30262 S=USR(1696)
30276 PLX=53248:PLY=1780:PLL=1784
30278 POKE PLL,9:POKE PLL+1,8:POKE PLL+2,26:POKE PLL+3,26
30282 FOR I=MYPMBASE+1024 TO MYPMBASE+1032:READ A:POKE I,A:NEXT I:REM *****DEFENDER PLAYER 0*****
30283 DATA 24,24,60,60,126,255,126,36,36
30285 FOR I=0 TO 7:READ A:POKE MYPMBASE+1280+I,A:NEXT I:REM *****ATTACKER PLAYER 1*****
30287 DATA 204,204,204,252,252,48,48,48
30299 REM *****EXPLOSION PLAYER 2*****
30300 FOR I=MYPMBASE+1280+256 TO MYPMBASE+256+1305:READ A:POKE I,A:NEXT I
30305 DATA 24,36,80,52,90,52,105,93,170,237,181,106,253,94,171,246,173,85,44,90,116,44,52,44,24,8
30309 REM *****EXPLOSION PLAYER 3*****
30310 RESTORE 30305:FOR I=MYPMBASE+1280+512 TO MYPMBASE+1305+512:READ A:POKE I,A:NEXT I
30590 RETURN 

Listing. Starshot.
Download (Saved BASIC) / Download (Listed BASIC)


Return to Table of Contents | Previous Section | Next Section