A.N.A.L.O.G. ISSUE 38 / JANUARY 1986 / PAGE 41

Incoming!

by Conrad Tatge

In Incoming! you must protect your city from wave after wave of incoming helicopters and space shuttles.

The helicopters drop fleets of paratroopers who attempt to land on the rooftops of your city. To land safely, a paratrooper must retain his parachute until he touches ground.

The shuttles release tiny “building bombs” that expand as they fall and build a new city block when they hit something. Shuttles and helicopters alternate waves.

The only defense against all of this is one semi-stationary rapid-fire gun. The gun can shoot up to sixteen steerable rounds at a time. To aim your shots, move the joystick left or right. If you have all sixteen shots in the air at one time, the gun will light up as a warning that you can no longer shoot, until a shot goes off the screen or hits something. Each shot you take will subtract ten points from your score.

The parachutes of the paratroopers can be shot off, which causes the paratrooper to plummet helplessly to the ground, destroying anyone below him. In addition, the helicopters and shuttles must be shot repeatedly to be destroyed. The more hits they take, the faster they fly, until they finally blow up. The debris from any explosion will kill surrounding objects.

Typing it in.

Before typing anything, look at the listings accompanying this article.

Listing 1 is the BASIC data and data checking routine. This listing is used to create both cassette and disk versions of Incoming!. The data statements are listed in hexadecimal (base 16), so the program will fit in 16K cassette systems.

Listing 2 is the assembly language source code for the game of Incoming!, created with the Atari Macro Assembler. You don’t have to type this listing to play the game! It is included for those readers interested in assembly language. Follow the instructions below to make either a cassette or disk version of Incoming!

Cassette instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with Unicheck (see page 14).
  2. Type RUN and press RETURN. The program will begin and ask:
    MAKE CASSETTE (0), OR DISK (1)? Type 0 and press RETURN. The program will begin checking the DATA statements, printing the line number of each as it goes. It will alert you if it finds any problems. Fix any incorrect lines and re-RUN the program, if necessary, until all errors are eliminated.
  3. When all of your DATA lines are correct, the computer will beep twice and prompt you to READY CASSETTE AND PRESS RETURN. Now insert a blank cassette in your recorder. press the RECORD and PLAY buttons simultaneously and hit RETURN. The message WRITING FILE will appear, and the program will create a machine language boot tape version of Incoming!, printing each DATA line number as it goes. When the READY prompt appears, the game is recorded and ready to play. CSAVE the BASIC program onto a separate tape before continuing.
  4. To play, rewind the tape created by the BASIC program to the beginning. Turn your computer OFF and remove all cartridges. Press the PLAY button on your recorder and turn ON your computer while holding down the START key. If you have a 600 or 800XL computer, you must hold the START and OPTION keys when you turn on the power. The computer will “beep” once. Hit the RETURN key, and Incoming! will load and run automatically.

Disk instructions.

  1. Type Listing 1 into your computer using the BASIC cartridge and verify your typing with Unicheck (see page 14).
  2. Type RUN and press RETURN. The program will ask:
    MAKE CASSETTE (0), OR DISK (1)? Type 1 and press RETURN. The program will begin checking the DATA lines, printing the line number of each statement as it goes. It will alert you if it finds any problems. Fix incorrect lines and re-RUN the program, if necessary, mitil all errors are eliminated.
  3. When all the DATA lines are correct, you will be prompted to INSERT DISK WITH DOS, PRESS RETURN. Put a disk containing DOS 2.0S into drive #1 and press RETURN. The message WRITING FILE will appear, and the program will create an AUTORUN.SYS file on the disk, displaying each DATA line number as it goes. When the READY prompt appears, the game is ready to play. Be sure the BASIC program is SAVEd before continuing.
  4. To play the game, insert the disk containing the AUTORUN.SYS file into drive #1. Turn your computer OFF, remove all cartridges and turn the computer back ON. Incoming! will load and run automatically.

Game over.

The game will end as a result of a few situations. Having half of your buildings occupied by paratroopers at the end of the one-minute wave will kill you. Another way to die is to have the base hit by a bomb or to have a paratrooper safely on the gun. You may SELECT a level with the console key Pressing START or the trigger button will start the game.

Advanced strategy.

Possible strategies to winning at Incoming! can be learned by playing a few times, but I’ll tell you the obvious ones.

A paratrooper without a parachute is deadly. They can be used to remove paratroopers who’ve already landed on rooftops. In addition, bombs will kill landed paratroopers.

Since every other level is a shuttle level, one can usually remove mistakes made on the previous level by allowing select bombs to kill men. However, don’t let too many bombs land, as the city will grow to extremes. When there are too many buildings, the chances of a paratrooper landing on a building are increased dramatically. Too many buildings can also hinder the effectiveness of the gun — the buildings will stop your bullets.

Use explosions to your advantage. Pixels from an exploding object are just as effective as a shot from your gun. Also, spread out your shots across the length of the shuttles and the choppers. As one is hit, you’ll hear a tone that indicates how close it is to demise. The tone rises as shots hit the object.

Many more strategies exist, but must be learned through trial and error.

Writing the game.

Three sleepless nights caused by an antibiotic for my cold left me with nothing to do but write a game. Six months later it was complete: my largest machine language game to date, Incoming! It represents a lot of trial and error at the keyboard.

I found that the best way to write these games is to try something new, and then write down what needs to be fixed. When you return to the editor, follow the list of changes, checking them off as you go along.

I used the archaic Atari Macro Assembler (AMAC) and Editor to create Incoming! MAC/65 is a much faster assembler, but I can’t deal with that line number-type editor. I encountered a problem in AMAC which caused the assembler to lock up during the second pass for no apparent reason. Two days later, I realized that it was caused by a disk access problem. If this happens to you, simply copy the offending source code to a new disk. The Macro Assembler has problems dealing with source files that run all over a disk.

At another point, I received the humorous message Memory Overflow stopped the ACT! Of course, it wasn’t that humorous at the time, but I simply went back to previously saved version without incident.

Have fun and watch out for Incoming!


Conrad Tatge is a Computer Science major at Union College in Schenectady, New York. He has worked for PDI in Greenwich, Connecticut and is the author of TwoGun, a two-player shootout that appeared in ANALOG Computing’s issue 28. He has enjoyed working with Ataris since his first 800, back in 1981.


Listing 1.
BASIC Listing.

10 REM *** INCOMING ***
20 TRAP 20:? "MAKE CASSETTE (0), OR DISK (1)";:INPUT DSK:IF DSK>1 THEN 20
30 TRAP 40000:DATA 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15
40 DIM DAT$(91),HEX(22):FOR X=0 TO 22:READ N:HEX(X)=N:NEXT X:LINE=990:RESTORE 1000:TRAP 120:? "CHECKING DATA"
50 LINE=LINE+10:? "LINE:";LINE:READ DAT$:IF LEN(DAT$)<>90 THEN 220
60 DATLIN=PEEK(183)+PEEK(184)*256:IF DATLIN<>LINE THEN ? "LINE ";LINE;" MISSING!":END 
70 FOR X=1 TO 89 STEP 2:D1=ASC(DAT$(X,X))-48:D2=ASC(DAT$(X+1,X+1))-48:BYTE=HEX(D1)*16+HEX(D2)
80 IF PASS=2 THEN PUT #1,BYTE:NEXT X:READ CHKSUM:GOTO 50
90 TOTAL=TOTAL+BYTE:IF TOTAL>999 THEN TOTAL=TOTAL-1000
100 NEXT X:READ CHKSUM:IF TOTAL=CHKSUM THEN 50
110 GOTO 220
120 IF PEEK(195)<>6 THEN 220
130 IF PASS=0 THEN 170
140 IF  NOT DSK THEN 160
150 PUT #1,224:PUT #1,2:PUT #1,225:PUT #1,2:PUT #1,121:PUT #1,54:CLOSE #1:END 
160 FOR X=1 TO 23:PUT #1,0:NEXT X:CLOSE #1:END 
170 IF  NOT DSK THEN 200
180 ? "INSERT DISK WITH DOS, PRESS RETURN";:DIM IN$(1):INPUT IN$:OPEN #1,8,0,"D:AUTORUN.SYS"
190 PUT #1,255:PUT #1,255:PUT #1,0:PUT #1,44:PUT #1,192:PUT #1,61:GOTO 210
200 ? "READY CASSETTE AND PRESS RETURN";:OPEN #1,8,128,"C:":RESTORE 230:FOR X=1 TO 40:READ N:PUT #1,N:NEXT X
210 ? :? "WRITING FILE":PASS=2:LINE=990:RESTORE 1000:TRAP 120:GOTO 50
220 ? "BAD DATA: LINE ";LINE:END 
230 DATA 0,36,216,43,255,43,169,0,141,47,2,169,60,141,2,211,169,0,141,231,2,133,14,169,56,141,232,2
240 DATA 133,15,169,121,133,10,169,54,133,11,24,96
1000 DATA 0000000000696E636F6D696E674141000000000000000000000048634900111918150000000000000000627900,532
1010 DATA 00636F6E7261640074617467650000F3E5ECE5E3F400696E697469616C006C6576656C707265737300F3F4E1F2,897
1020 DATA F400746F00626567696E00686967680073636F72651A0000000C00000000000000000067616D6500006F766572,733
1030 DATA 000000000000696E636F6D696E670000000000000000004100707070C6D13C4D00600D0D0D0D0D0D0D0D0D0D0D,769
1040 DATA 0D8D0D0D0D0D0D0D0D0D0D0D0D0D0D8D0D0D0D0D0D0D0D0D0D0D0D0D0D8D0D0D0D0D0D0D0D0D0D0D0D0D0D8D0D,866
1050 DATA 0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D41A02CA9008580A9608581A200A5809D,81
1060 DATA FD40A5819D5341E8E056F010A5801869288580A581690085814C0B2D60A90048209C2D68A02791808810FB60A2,118
1070 DATA 55202B2DCA10FAA253A9FF202D2DE8A9FF202D2D60A206A9009D01D2CACA10F960A27FA9009D805D9D005E9D80,298
1080 DATA 5E9D005F9D805FCA10EE60BE5940209C2DB91D402918AA980AA8A906858C18BD173D9180C8BD373D9180986927,87
1090 DATA A8E8C68CD0EC60BDFD408580BD5341858160A683209C2DA582484A4AA8682903AAB1806020A72D3DCA2D918060,680
1100 DATA 030C30C0FCF3CF3F3FCFF3FC20A72D3DCA2D1DDA2D91806040100401C0300C0320A72D3DDE2D488A4903AA68CA,352
1110 DATA 30054A4A4CEE2D6020E22DC9029043A8A5824A4A4AAAA58338E906DD6D40B02FC003D01BA9019D1D40A5974A4A,102
1120 DATA 9D45409D3140A905205F33A90985C94C3E2E205530A5828584A5838585A90720AC2EA9006020CE2DA90160C6A0,595
1130 DATA F00160A5A185A0A20F868EBDAD3FF045BDBD3F8582BDCD3F858320B92DA68EBDDD3F1865879DDD3FBDBD3F6586,583
1140 DATA C9A0B02B9DBD3F8582BDED3F1865899DED3FBDCD3F6588C955B0149DCD3F858320F72DA68E9DAD3FC68EA68E10,597
1150 DATA B060A9009DAD3FF0F2858CA68ABDAD3DF005200C2FA68AAD0AD2259E9D6D3FA5849DED3DA5859D2D3E20062F9D,26
1160 DATA 6D3E20062F9DAD3EA9009DED3E9D2D3F20062F259D9DAD3DE68AA58A293F858AAAC68CD0BBA90F85A9A903859E,132
1170 DATA A907859CA93F859D60AD0AD2059C60BDED3D8582BD2D3E858320B92D60C69AF00160A59B859AA23F8696BDAD3D,761
1180 DATA F023200C2FA696DEAD3DF019BD6D3E187DED3E9DED3EBD6D3F2901D00BBDED3DE9004C572F4C912FBDED3D6900,840
1190 DATA C9A0B03F9DED3D8582BDAD3E187D2D3F9D2D3FBD6D3F2902D008BD2D3EE9004C7E2FBD2D3E6900C955B0189D2D,591
1200 DATA 3E858320F72DD005A6969DAD3DC696A696300A4C272FA9009DAD3DF0F06099165E99245E99325E99405E609996,740
1210 DATA 5E99A45E99B25E99C05E6099165F99245F99325F99405F6099965F99A45F99B25F99C05F60A599C599F0FC60A2,655
1220 DATA 08A90095C4CA10FB60868D8A0AA8BD5940AA209C2DA9009180C8918088A68DFE5940BD5940DD6D409045BD1D40,74
1230 DATA 2908D01D205530BD6D40DD8140F038BD6D401869059D6D409D59402055304C5230BD6D404838E9059D6D40A918,355
1240 DATA 9D1D40203A34A68D68DD8140D007C94DF003200E34A48D20732DA68D60868FA9109D1D408AA820732DA68FA900,994
1250 DATA 9D1D408A0A0A0A1869038584BD59401869038585A90A20AC2EA906205F33A90C85C4A68F60A90085A885AAA213,200
1260 DATA BD1D402901F038E6A8BD1D402908D009BD5940C5AA900285AADE3140D021BD45409D3140BD5940C591D011A909,179
1270 DATA 9D1D40A5979D45409D3140A90585CA20E72FCA10BEA5AA85C660A90085A4A5B6C902D004A207D006A5924A0901,300
1280 DATA AA869020C631A690BDA140DD9740D028A5B5F02420BD31B01FA5B6F073C902F017BDBF4038E930C990B00DA592,328
1290 DATA 4A4AAABDDD40F006CA10F84CAF31A490B9A53DD96D40B0F348204432681869149DED40A9009DF1409DF54095BC,27
1300 DATA AD0AD229031869029DE9409DE540A490B9BF401869049DE14038EDC7402907F009A9002A4901A8B9583D9DF940,936
1310 DATA FEDD40A90585CBD033BDBF4038E9284A4A4AAAE014B025BD1D402901D01EA490B9A53DDD6D40B0149D5940A597,363
1320 DATA 4A9D45409D3140A9019D1D4020E72FC6903005A6904CEF30A5A485A560AD0AD20D0AD2C59560BDC940F053E6A4,757
1330 DATA DE9740D021BDA1409D97408A2901A8B9583D187DBF409DBF40D00BA5B6C902F055A9009DC940A5B6C902F04ABD,457
1340 DATA D3401045BDBF4038E9288584BDA53D8585A9009DBF409DC940A91920AC2EA906205F3360A5B5F021A599290FD0,633
1350 DATA 1B20BD31B016AD0AD2290F18658B9D97409DA1404A4A9DD340FEC94060BDED40A888205F32205F32205F32205F,242
1360 DATA 32205F32205F32205F3260B9805D3DC62D99805DC860B9805D1DC22D99805D60C6B1F00160A5B085B185B1A900,285
1370 DATA 85AAA20386B2BDDD40D0034C3A33B5BC290EF030BDE14038E92D4A4A4AAAE014B014BD6D40DD8140F00F186905,456
1380 DATA 9D6D409D59402055304C28338AA820B533A91985CBD063B5BC2901D043FEF140BDF140187DF5409DF540901AFE,922
1390 DATA ED40BDED40A8C5AA900285AA205F32BDED40186904A8206A32DEE540D041BDE9409DE540BDF940187DE140C930,766
1400 DATA 9004C9CA9029BDE14038E92D8584BDED4038E9148585A91420AC2EA905205F33A900A6B29DE1409D04D09DDD40,205
1410 DATA 95BC9DE140C6B23005A6B24C8732A5AA85C660A5C105C0F02CF8A5C138E90185C1A5C0E90085C04C6B33F81865,367
1420 DATA C185C1A5C0690085C0A001A204B9C000209333CA8810F6D860E692A592290F85920A0A0A0A85BB8DC802A492B9,739
1430 DATA A533A21348290F209E33684A4A4A4A09509DD13CCA600102030405060708091011121314151698203334F02DB9,653
1440 DATA 8140CDAB3D902548AA209C2D6838E906998140996D40AA980AA8A20518BDE9339180C89180986927A8CA10F160,939
1450 DATA C3C3FFC3C3FFA205AD0AD2291FC914B0F7A8B96D40C94DD0EF8E093420B533A200CA10E460A90685AD85C560A2,996
1460 DATA 13A000BD8140C94DF008C8DD6D40F0028888CA10EE881004A90185B760C909F002C90A608A203334D0F986B786,325
1470 DATA 93A90085B58DC740A901859EA907859CA9FF859DA94F8584A9508585A9204CAC2EA90285B68593A90085B520DD,24
1480 DATA 2F20502DA27F9D805DCA10FA8DC740A904859BA91385B9A6B9BD6D40C94DF01618690385858A0A0A0A69038584,926
1490 DATA A901859EA90320AC2EC6B910DD302A204B34A9808599D028AD0AD2297F18691085828584AD0AD2293F85838585,770
1500 DATA 20E22DC902B0E4A91020AC2EAD0AD20901859920D62FAD1FD0C907D016201A2FA59910EFAD0AD20D0AD24AB0BE,691
1510 DATA 4AB0894AB0AFA90A859B204B34204B34204038A97885AB8D7736A5C0C5C2901CA5C1C5C3901685C3A5C085C2A2,357
1520 DATA 05BDD13C9D712CCA10F7A9648D77364C0437A90085B5A90120FD39A5922901208A38A5B60A0A0AA8A207B9FF35,98
1530 DATA 9D962CC8CA10F6A98C8D7736200F3620DD2F20502DA980859920D62FA599F00B0A0A0A490FF0F285C6D0EE85C6,447
1540 DATA 200F36A692BD7B3D8595BD6B3D858BBD5B3D859B859A8A4AAABD8B3D8597BD933D85B085B18A4AAABD9F3D8591,200
1550 DATA 8A4AAABDA33D85A185A0A900A2139D1D40CA10FAA2039DDD409DE140CA10F7A20F9DAD3FCA10FAA23F9DAD3DCA,24
1560 DATA 10FAA2079DC9409DBF409DD340CA10F4A2078A18690605BB49F09DB540CA10F2A900858A85936073726570706F,477
1570 DATA 686373656C747475687320D62FA5A2490685A2AAA005BD6D3699E42CE88810F6A5A2F01AA207AD0AD2297F1869,760
1580 DATA 379DBF40AD0AD2290F090A9DB540CA10E860ADE52CC5AB900A200E34A9008DE52CF017A21320D62FEEE52C8A29,719
1590 DATA 010A0A0A8D01D28E00D2CA10EB600D0D0D0D0D0D6A004D2C0046A9008D2F028D08D2A24C9580CA10FB2065E420,473
1600 DATA 012D203A2D205C2D206B3320FB39208C33201A3A20F92EA95085ABA905859FA9018593A9698D0002A9398D0102,275
1610 DATA A9A08D3002A92C8D3102A95C8D07D4A9038D1DD0A9118D6F02A23AA035A906205CE4A205BD113D9D615ECA10F7,18
1620 DATA A9C08D0ED4A9008DC402A9CE8DC502A9428DC602A92E8D2F02A9008D7736A90085B785B885B520502D20DD2FA9,175
1630 DATA 348DC702A207AD0AD2290F09039DC9409D97409DA140CA10EDA902208A38200F36A207BD54399D975DCA10F7A9,862
1640 DATA 008599AD0AD2297F18693AA203189DE1406902CA10F88D1ED020D62FAD1FD02902D017A93C8DE52CA900859920,592
1650 DATA 7B33A91085C8AD1FD02902F0F9AD1FD029012D8402F00FA599297FD0CF2044364C59374C0437A90085C085C120,378
1660 DATA 6B33200F36AD1FD04A90FA203A2DA97D8DC740A9068594A900A2079D975DCA10FAA92E8DC702A213A94D9D6D40,327
1670 DATA 9D8140CA10F7A947A2019D76409D8A40CA10F720EF33203635A90185B5AD1FD0C907F008A93C8D77364C043720,231
1680 DATA D93020472E201A2FA5B6D009208A30205D384C1338207432A5B8F0034C6434A5B5D0CDA2031DDD40CA10FA05A8,761
1690 DATA 05A4D0BFA90A859B85A18593204038201534A5B7D006207B334CDD374C643420472E201A2FA900A20F1DAD3FCA,42
1700 DATA 10FAA23F1DAD3DCA10FAC900D0E460C6AFD028A91785AFA5AE186901290385AEAAA000BD4C3920A22FBD503920,189
1710 DATA AF2FBD443920BC2FBD483920C92F6085B6A8BEB138A000BDCC3820A22FBDD83820AF2FBDB43820BC2FBDC03820,318
1720 DATA C92FE8C8C00C90E260003060070000C0FF3F070100000001FF2078E4E2E2E2E2FC7811FEFF041E27474747473F,195
1730 DATA 1E887FE0000003FFFCE08000000080E0F0F0F8FC7E7FFFFFFFFC7B000000000000F8E4FEFF1FEC000000000000,551
1740 DATA 1F277FFFF837070F0F1F3F7EFEFFFFFF3FDE00000000000C1F1F0F3FFE0000003078FDFFFFFEFFFFEC0000000C,216
1750 DATA 1E5FFFFF7FFFFF3700000000000030F8F8F0FC7F0004060301711C06C38EC360382080C0603C7EFFFFFFFF7E3C,391
1760 DATA A203BD00D015BC95BCCA10F660488A489848D8A698A000B904D01905D02901F00EDED140BD9F4085CC38E9029D,882
1770 DATA 9F40E8C8C8C00490E1205C39A59818690205BB8D0AD48D1AD08D1ED0A698A000BDB5409912D09913D0BDBF4099,508
1780 DATA 00D0186908C89900D0E8C8C00490E48698E006A5B32A290385B3490385B4A203A5B30A0A05B385B3CA10F58D0A,700
1790 DATA D48D0CD0A20318BDE14065B49D04D0CA10F568A868AA6840A90048A205A900202E3ACA202E3A202E3ACA68202E,338
1800 DATA 3A60ADDB3C495A8DDB3CADDE3C494E8DDE3C60DEDA3CBDDA3C290FC90A6009509DDA3CCA60D8A900859885B3E6,16
1810 DATA 99A5B5F03DC694D039A9068594A20520233A902EA909202E3A20123ACA20233A9020A909202E3A20233A9016A9,64
1820 DATA 05202E3ACA20233A900BA90085B520FB39A93085C8A5992903D044AD78024A4A4903AABD573D1865A3C90BB032,450
1830 DATA 85A3AA0A0A0A0A09088DBD40BDA53C8587BDB03C8586BDBB3C8589BDC63C85888A0A0AA8A203B9E53C9D5D5EC8,672
1840 DATA CA10F63053C69FD04FA905859FA593F00CA5B6C902D04120D9304C1C3BAD8402D036854DA20FBDAD3FF008CA10,71
1850 DATA F88EBD403025ADC74049018DC74038E92C9DBD3FA94D9DCD3FA9009DDD3F9DED3FFEAD3FA91085C7204833A203,520
1860 DATA A5B81D08D0CA10FA290185B8205C398D1ED0A5992903F013A5C7F009C6C7A5C78D00D209208D01D24C623BA5A9,807
1870 DATA F0F68DC40209408D01D2AD0AD2291F1869288D00D2C6A9A5C5F039A5992901D03FA5AC09A08D03D2C6AC1034C6,195
1880 DATA AD100AA90085C585AC85ADF01AA6ADBD993B8D02D2A205C93CD002A20A86ACD0123C483C485B79A5C6F0058D02,432
1890 DATA D2A9A88D03D2A5B638E902F043A5CCF00E8D04D2A9A88D05D2A90085CCF034A5A5F02DA5B6F014A5A54809C08D,713
1900 DATA 05D2680A0A0A1869788D04D2D018E6A7A5A7290F85A7AABD853C8D04D2A5A5187D953C8D05D2A9008D07D2A5CA,828
1910 DATA F00FAABD7E3C8D06D2BD783C8D07D2C6CAA5C9F00C8D06D2AABD6E3C8D07D2C6C9A5C4F00FAABD643C8D06D2BD,54
1920 DATA 5A3C8D07D2C6C4A5CBF00D0A0A0A8D06D2A9A68D07D2C6CBA5C8F010A9508D06D2C6C8A5C8290F09A08D07D24C,707
1930 DATA 5FE4A3A4A5A7A9A8A7A6A8AA0406090B0F0C110D130E0C0A08060504030202014547494B4D4F0A0E12161A1E0A,444
1940 DATA 0B0C0D0E0D0C0B0A09080706070809030201000302010002010002020001001F234C80BE004280B4DDE1FFFFFF,659
1950 DATA FFFF000000000000BE804C231F001F234C80BEFFFFFFFFFFFFFFFFFFFFFF00004C00005000000000005A00004E,218
1960 DATA 0000000000F8F8000078F040003870600038707020383870703838383838381C1C381C1C08381C0C003C1E0400,752
1970 DATA 3E3E0000387C7CFEFEFE0000022A022800000F3F302A0228000000000000000000000000220A02280000000080,452
1980 DATA A880280000F0FC0CA8802800000000000000000000000088A08028000000FF0100465A41505050504650505A50,293
1990 DATA 28461E32461E411E322D28231E1915120E0B08050A141E1E282832323C3C4646505A646EFFC0B0A09070503023,92
2000 DATA 1E19140F0A0503BF3F1F1414222C36120B08081616242432320000000000000000000000000000000000000000,918
2010 REM * 4545 BYTES

Listing 2.
Assembly Listing.

* INCOMING!!
* By Conrad Tatge 1985   Hi Katie!

* Copyright (c) 1986 ANALOG Computing

	LIST	-L

* Simple macros/equates

MOV	MACRO	from,to
	LDA	%1
	STA	%2
	ENDM

ZER	MACRO	label
	LDA	#0
	STA	%1
	ENDM

ADD	MACRO	val
	CLC
	ADC	%1
	ENDM

SUB	MACRO	val
	SEC
	SBC	%1
	ENDM

MAD	MACRO	label,loc
	MOV	#LOW %1,%2
	MOV	#HIGH %1,%2+1
	ENDM

PMBASE	=	$D407
SIOINV	=	$E465
VDSLST	=	$200
SDLSTL	=	$230
GRACTL	=	$D01D
GPRIOR	=	$26F
SETVBV	=	$E45C
NMIEN	=	$D40E
COLBK	=	$D01A
SYSVBV	=	$E45F
M0PF	=	$D000
M0PL	=	$D008
P0PF	=	$D004
P1PF	=	$D005
SIZEM	=	$D00C
PMCOL0	=	$D012
COLOR0	=	708
COLOR1	=	709
COLOR2	=	710
COLOR3	=	711
COLOR4	=	712
CONSOL	=	$D01F
AUDF1	=	$D200
AUDC1	=	$D201
AUDF2	=	$D202
AUDC2	=	$D203
AUDF3	=	$D204
AUDC3	=	$D205
AUDF4	=	$D206
AUDC4	=	$D207
AUDCTL	=	$D208
RANDOM	=	$D20A
HPOSP0	=	$D000
HPOSM0	=	$D004
HITCLR	=	$D01E
WSYNC	=	$D40A
ATRACT	=	$4D
STICK	=	$278
STRIG	=	$284
DMACTL	=	559

* Program constants

TOP	=	20	;PM top of GR.7 screen
TITOFF	=	68	;down the screen
MESLEN	=	20	;length of each message
INCOME	=	7*MESLEN
GAMOVR	=	6*MESLEN	;message numbers
HIGHSC	=	5*MESLEN
SELECT	=	3*MESLEN
LEFT	=	$30	;the PM side of screen
YMAX	=	85	;number of GR.7 lines
XMAX	=	160
NUMPAR	=	19	;array size constants-1
NUMEXP	=	63
NUMCHO	=	7
NUMBLO	=	5
NUMSHO	=	15
NUMBOM	=	3
MANLIV	=	1	;alive
MANCHU	=	8	;has chute
MANZER	=	$10
MANLAN	=	$18	;landed
HTBLOK	=	6	;heights
HTPARA	=	5
GROUND	=	YMAX-HTBLOK-2	;where to land
CHEXCL	=	1	;characters
CHPER	=	$0E
CHCOM	=	$0C
CHCOL	=	$1A
CHLPAR	=	8
CHRPAR	=	9
COLMSK	=	$40	;for text
CLOUDY	=	2	;clouds on?
TRISPD	=	5	;trigger speed
SCRMEM	=	$6000	;memory allocation
PMBAS	=	$5C00
MISL	=	PMBAS+$180
PLR0	=	PMBAS+$200
PLR1	=	PMBAS+$280
PLR2	=	PMBAS+$300
PLR3	=	PMBAS+$380

	ORG	$80

VARBEG
LO	DS	1	;pointer
HI	DS	1
XPLOT	DS	1	;where to plot
YPLOT	DS	1
XEXPLO	DS	1	;where to explode
YEXPLO	DS	1
XDRINT	DS	1	;shot deltas
XDRDEC	DS	1
YDRINT	DS	1
YDRDEC	DS	1
NEXPLO	DS	1	;next pixel
CHORAT	DS	1	;rate of choppers
COUNT	DS	1
PARNUM	DS	1
SHONUM	DS	1
KILNUM	DS	1	;the paratrooper to kill
CHONUM	DS	1
CORD	DS	1
LEVEL	DS	1
LEVDON	DS	1	;level is done
JIFFY	DS	1	;tenths of seconds
CHANCE	DS	1
EXPLOC	DS	1	;explosion count
FALVEL	DS	1
DLIPNT	DS	1	;DLI pointer
TIMER	DS	1
EXPTIM	DS	1
EXPSPD	DS	1
EXPMIN	DS	1
EXPMAX	DS	1
EXPAND	DS	1
TRITIM	DS	1	;countdown for trigger
SHOTIM	DS	1	;to move shots
SHOSPD	DS	1	;reset value of SHOTIM
TITLST	DS	1	;title line on?
GUNROT	DS	1	;gun position
CHOPS	DS	1	;helicopters flying
CHONSC	DS	1	;on screen
CHOCMP	DS	1
BLASND	DS	1
PARAS	DS	1	;troopers in air
BRIGHT	DS	1	;brightness of explo
LOWCMP	DS	1
MESMAX	DS	1
NOTVOL	DS	1
NOTNUM	DS	1
BLADE	DS	1	;blade animation
BLATIM	DS	1
BOMRES	DS	1
BOMTIM	DS	1	;bomb delay
BOMNUM	DS	1	;bomb number
BOMSIZ	DS	1	;for DLI display
BOMOFF	DS	1
DOTIME	DS	1	;clock on?
SHUTLE	DS	1	;doing shuttles? 2=clouds
DEAD	DS	1
MPLOR	DS	1
XALTER	DS	1
LIVING	DS	1	;for counting landed
COLSKY	DS	1	;color of sky
MPFOR	DS	4	;collision
SCORE	DS	2	;current
HSCORE	DS	2	;high
VARSND			;sound variables
SCREAM	DS	1	;man yelling?
TUNEON	DS	1	;charge?
LOWEST	DS	1	;lowest man/bomb falling
SHOVOL	DS	1
BINGS	DS	1
RIPSND	DS	1
CHUSND	DS	1
BWOOOP	DS	1
CHOHIT	DS	1
VAREND

	ORG	$2C00

* Text for screen display

TEXT	DB	0,0,0,0,0,'incoming'
	DB	CHEXCL OR $40,CHEXCL OR $40
	DB	0,0,0,0,0
	DB	0,0,0,0,0,0,CHLPAR OR $40
	DB	'c',CHRPAR OR $40,0,$11,$19
	DB	$18,$15,0,0,0,0,0,0
	DB	0,0,'by',0,0,'conrad',0
	DB	'tatge',0,0
	DB	's' OR $C0,'e' OR $C0
	DB	'l' OR $C0,'e' OR $C0
	DB	'c' OR $C0,'t' OR $C0,0
	DB	'initial',0,'level'
	DB	'press',0
	DB	's' OR $C0,'t' OR $C0
	DB	'a' OR $C0,'r' OR $C0
	DB	't' OR $C0,0,'to',0,'begin'
	DB	0,'high',0,'score',CHCOL,0
	DB	0,0,CHCOM,0,0,0,0
	DB	0,0,0,0,0,'game',0,0,'over'
	DB	0,0,0,0,0
	DB	0,'incoming',0,0,0,0,0,0,0
	DB	0,0,CHEXCL OR $40,0

* Display list for game screen

GAMEDL	DB	$70,$70,$70,$C6
	DW	SCORLN
	DB	$4D
	DW	SCRMEM
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$8D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$8D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$8D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$8D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$0D,$0D,$0D,$0D,$0D
	DB	$0D,$41
	DW	GAMEDL

* Set up lookup table, erase screen

SETSCR
	MAD	SCRMEM,LO
	LDX	#0	;set up lookup
SETTAB	LDA	LO
	STA	SCRLO,X
	LDA	HI
	STA	SCRHI,X
	INX
	CPX	#YMAX+1	;bottom yet?
	BEQ	ENDSET
	LDA	LO
	ADD	#40	;40 bytes/line
	STA	LO
	LDA	HI
	ADC	#0
	STA	HI
	JMP	SETTAB

ENDSET	RTS

ERALIN	LDA	#0	;for falling through

DRALIN	PHA
	JSR	SETLO	;set it up
	PLA
	LDY	#39	;bytes
ERALN2	STA	(LO),Y	;do it!
	DEY
	BPL	ERALN2
	RTS

CLRSCR	LDX	#YMAX
CLEAR2	JSR	ERALIN	;erase screen
	DEX
	BPL	CLEAR2
	LDX	#YMAX-2	;draw ground
	LDA	#$FF
	JSR	DRALIN
	INX		;two lines
	LDA	#$FF
	JSR	DRALIN
	RTS

* Clear sound channels

SHUTUP	LDX	#6
	LDA	#0
HUSH	STA	AUDC1,X
	DEX
	DEX
	BPL	HUSH
	RTS

* Clear out PM buffers

CLRPLR	LDX	#$7F
	LDA	#0
CLR2	STA	MISL,X
	STA	PLR0,X
	STA	PLR1,X
	STA	PLR2,X
	STA	PLR3,X
	DEX
	BPL	CLR2
	RTS

* Draw paratrooper image Y on screen

DRAMAN	LDX	PARVER,Y	;vertical
	JSR	SETLO
	LDA	PARTYP,Y	;image number
	AND	#MANLAN	;just pic bits
	TAX
	TYA
	ASL	A
	TAY
	MOV	#6,COUNT	;6 bytes to move
	CLC		;through out loop
MOVMAN	LDA	PARLEF,X	;draw new man
	STA	(LO),Y
	INY
	LDA	PARRIG,X	;and right side
	STA	(LO),Y
	TYA
	ADC	#39	;down one line
	TAY
	INX
	DEC	COUNT	;6 times only
	BNE	MOVMAN
	RTS

SETLO	LDA	SCRLO,X	;SCRMEM to LO
	STA	LO
	LDA	SCRHI,X
	STA	HI
	RTS

* Point LO to pixel XPLOT,YPLOT and
* set up X and Y properly

PLOT	LDX	YPLOT
	JSR	SETLO	;point to line
	LDA	XPLOT	;0-159
	PHA
	LSR	A
	LSR	A	;0-39
	TAY		;point to byte
	PLA
	AND	#3
	TAX		;point to pixel
	LDA	(LO),Y
	RTS

ZEROIT	JSR	PLOT
	AND	BITAND,X	;return point
	STA	(LO),Y
	RTS

BITSON	DB	3,$0C,$30,$C0
BITOFF	DB	$FC,$F3,$CF,$3F
BITAND	DB	$3F,$CF,$F3,$FC	;mask off

PLOTIT	JSR	PLOT
	AND	BITAND,X	;return point
	ORA	BITPF1,X	;mask on
	STA	(LO),Y
	RTS

BITPF1	DB	$40,$10,$04,$01	;COLOR 1
BITPF3	DB	$C0,$30,$0C,$03	;COLOR 3

* Returns color at XPLOT,YPLOT

LOCATE	JSR	PLOT
	AND	BITPF3,X
	PHA		;save byte at coords
	TXA
	EOR	#3	;flip
	TAX
	PLA
SHIFT	DEX		;countdown
	BMI	ENDLOC
	LSR	A
	LSR	A
	JMP	SHIFT

ENDLOC	RTS

* Check pixel XPLOT,YPLOT and take
* action.  Called by SHOTS and EXPLO
* A is fate of pixel (NE or EQ)

NEWPIX	JSR	LOCATE	;what is at pixel?
	CMP	#2	;hit anything?
	BCC	PLOPIX
	TAY		;Yes! save color hit
	LDA	XPLOT
	LSR	A
	LSR	A
	LSR	A	;0-19
	TAX		;find PARatrooper
	LDA	YPLOT	;is pixel
	SEC
	SBC	#HTBLOK
	CMP	LANDED,X	;too low?
	BCS	KILPIX
	CPY	#3	;hit chute?
	BNE	MANHIT	;no.
	LDA	#MANLIV	;take off chute
	STA	PARTYP,X
	LDA	FALVEL	;give speed
	LSR	A
	LSR	A
	STA	PARSPD,X
	STA	PARVEL,X
	LDA	#5
	JSR	ADDSCO	;add 50 points
	MOV	#9,RIPSND
	JMP	KILPIX

MANHIT	JSR	KILPAR
	MOV	XPLOT,XEXPLO
	MOV	YPLOT,YEXPLO
	LDA	#7
	JSR	INIEXP	;boom
KILPIX	LDA	#0	;kill pixel
	RTS

PLOPIX	JSR	PLOTIT	;do the new point
	LDA	#1	;pixel is OK
	RTS

* Move all live shots according to DR

SHOTS	DEC	SHOTIM	;times yet?
	BEQ	MVSHOT
	RTS		;not time yet!

MVSHOT
	MOV	SHOSPD,SHOTIM	;reset
	LDX	#NUMSHO	;up to 16 bullets
	STX	SHONUM
CKSHOT	LDA	SHOLIV,X	;shot here?
	BEQ	NXSHOT
	LDA	SHXINT,X
	STA	XPLOT
	LDA	SHYINT,X
	STA	YPLOT
	JSR	ZEROIT	;erase old point
	LDX	SHONUM	;retreive
	LDA	SHXDEC,X	;horizontal
	ADD	XDRDEC
	STA	SHXDEC,X
	LDA	SHXINT,X
	ADC	XDRINT
	CMP	#XMAX	;off of screen?
	BCS	KILSHO
	STA	SHXINT,X
	STA	XPLOT
	LDA	SHYDEC,X	;and vertical
	ADD	YDRDEC
	STA	SHYDEC,X
	LDA	SHYINT,X
	ADC	YDRINT
	CMP	#YMAX
	BCS	KILSHO
	STA	SHYINT,X
	STA	YPLOT
	JSR	NEWPIX	;check
	LDX	SHONUM
	STA	SHOLIV,X	;kill it?
NXSHOT	DEC	SHONUM	;next!
	LDX	SHONUM
	BPL	CKSHOT
	RTS
KILSHO	LDA	#0
	STA	SHOLIV,X	;kill shot
	BEQ	NXSHOT	;leave...

* Init an explosion at XEXPLO,YEXPLO
* of the size in the accumulator

INIEXP	STA	COUNT	;save size
	LDX	NEXPLO	;maximum 64 pixels
CKEXP	LDA	EXPLIV,X
	BEQ	INEXPL
	JSR	ERAEXP	;erase point
	LDX	NEXPLO	;restore
INEXPL	LDA	RANDOM	;direction
	AND	EXPAND	;could be just up
	STA	EXPDIR,X
	LDA	XEXPLO	;explosion point
	STA	EXPXP,X
	LDA	YEXPLO
	STA	EXPYP,X
	JSR	GETRAN
	STA	EXPXI,X	;increments
	JSR	GETRAN
	STA	EXPYI,X
	LDA	#0
	STA	EXPXAC,X	;accumulators
	STA	EXPYAC,X
	JSR	GETRAN	;length of life
	AND	EXPMAX
	STA	EXPLIV,X
	INC	NEXPLO
	LDA	NEXPLO
	AND	#NUMEXP	;0-63
	STA	NEXPLO
	TAX
	DEC	COUNT
	BNE	CKEXP
	MOV	#$0F,BRIGHT
INITEX
	MOV	#3,EXPAND	;restore
	MOV	#7,EXPMIN	;explo varbs
	MOV	#$3F,EXPMAX
	RTS

GETRAN	LDA	RANDOM	;random between
	ORA	EXPMIN	;minimum
	RTS

* Erase explosion pixel X

ERAEXP	LDA	EXPXP,X
	STA	XPLOT
	LDA	EXPYP,X
	STA	YPLOT
	JSR	ZEROIT
	RTS

* Update the explosion

EXPLO	DEC	EXPTIM
	BEQ	SETEXP
	RTS	;not yet!

SETEXP
	MOV	EXPSPD,EXPTIM	;reset
	LDX	#NUMEXP	;do 64
	STX	EXPLOC
DOEXP1	LDA	EXPLIV,X	;pixel moving?
	BEQ	JXEXPL
	JSR	ERAEXP	;erase the old
	LDX	EXPLOC	;restore
	DEC	EXPLIV,X	;now done?
	BEQ	JXEXPL	;yes...leave
	LDA	EXPXI,X	;a new point!
	CLC
	ADC	EXPXAC,X
	STA	EXPXAC,X
	LDA	EXPDIR,X	;direction
	AND	#1
	BNE	ADDEXX
	LDA	EXPXP,X
	SBC	#0	;with carry!
	JMP	STOEXX

JXEXPL	JMP	NXEXPL

ADDEXX	LDA	EXPXP,X	;ends up here
	ADC	#0
STOEXX	CMP	#XMAX	;off of screen?
	BCS	KILEXP
	STA	EXPXP,X	;new point is OK
	STA	XPLOT
	LDA	EXPYI,X	;now do Y place
	CLC
	ADC	EXPYAC,X
	STA	EXPYAC,X
	LDA	EXPDIR,X
	AND	#2
	BNE	ADDEXY
	LDA	EXPYP,X
	SBC	#0
	JMP	STOEXY

ADDEXY	LDA	EXPYP,X
	ADC	#0
STOEXY	CMP	#YMAX	;off screen?
	BCS	KILEXP
	STA	EXPYP,X
	STA	YPLOT
	JSR	NEWPIX	;do new pixel
	BNE	NXEXPL
	LDX	EXPLOC
	STA	EXPLIV,X	;kill
NXEXPL	DEC	EXPLOC	;next!
	LDX	EXPLOC
	BMI	ENDEXP
	JMP	DOEXP1

KILEXP	LDA	#0
	STA	EXPLIV,X
	BEQ	NXEXPL	;always
ENDEXP	RTS

DOPLR0	STA	PLR0+TOP+2,Y	;this is a
	STA	PLR0+TOP+16,Y	;ridiculous
	STA	PLR0+TOP+30,Y	;waste but
	STA	PLR0+TOP+44,Y	;it works!
	RTS

DOPLR1	STA	PLR1+TOP+2,Y
	STA	PLR1+TOP+16,Y
	STA	PLR1+TOP+30,Y
	STA	PLR1+TOP+44,Y
	RTS

DOPLR2	STA	PLR2+TOP+2,Y
	STA	PLR2+TOP+16,Y
	STA	PLR2+TOP+30,Y
	STA	PLR2+TOP+44,Y
	RTS

DOPLR3	STA	PLR3+TOP+2,Y
	STA	PLR3+TOP+16,Y
	STA	PLR3+TOP+30,Y
	STA	PLR3+TOP+44,Y
	RTS

WAITVB	LDA	TIMER	;wait for VB to end
WAITIT	CMP	TIMER
	BEQ	WAITIT
	RTS

SILENT	LDX	#VAREND-VARSND-1
	LDA	#0
KILSND	STA	VARSND,X
	DEX
	BPL	KILSND
	RTS

* Erase old paratrooper X and draw a
* new one lower.  See if this guy
* has landed.  Called by MOVPAR.

SHOPAR	STX	PARNUM	;hold me now
	TXA
	ASL	A
	TAY		;horizontal
	LDA	PARVER,X	;vertical
	TAX
	JSR	SETLO
	LDA	#0
	STA	(LO),Y	;erase 2 bytes
	INY
	STA	(LO),Y
	DEY		;put back
	LDX	PARNUM
	INC	PARVER,X	;gravity
	LDA	PARVER,X
	CMP	LANDED,X	;has he landed?
	BCC	SHOHIM
	LDA	PARTYP,X	;yes
	AND	#MANCHU	;have chute?
	BNE	SAFETY
	JSR	KILPAR	;no. kill him!
	LDA	LANDED,X
	CMP	ROOF,X	;anyone below?
	BEQ	ENDMAN	;no
	LDA	LANDED,X	;yes
	ADD	#HTPARA	;move down man
	STA	LANDED,X	;adjust down
	STA	PARVER,X	;erase man
	JSR	KILPAR
	JMP	ENDMAN

SAFETY	LDA	LANDED,X	;adjust ground
	PHA		;old
	SUB	#HTPARA	;move up one
	STA	LANDED,X
	LDA	#MANLAN	;raise hands
	STA	PARTYP,X
	JSR	BASHIT	;on base?
	LDX	PARNUM
	PLA		;on building?
	CMP	ROOF,X
	BNE	SHOHIM
	CMP	#GROUND
	BEQ	SHOHIM
	JSR	CHARGE
SHOHIM	LDY	PARNUM	;get man to draw
	JSR	DRAMAN
ENDMAN	LDX	PARNUM
	RTS		;X reg is intact

* Kill paratrooper X (intact)
* by zeroing PARTYP and erasing.

KILPAR	STX	KILNUM	;save the number
	LDA	#MANZER	;erase this guy
	STA	PARTYP,X
	TXA
	TAY
	JSR	DRAMAN
	LDX	KILNUM
	LDA	#0
	STA	PARTYP,X
	TXA
	ASL	A
	ASL	A
	ASL	A
	ADD	#3
	STA	XEXPLO
	LDA	PARVER,X
	ADD	#3
	STA	YEXPLO
	LDA	#10
	JSR	INIEXP	;boom!
	LDA	#6	;60 points!
	JSR	ADDSCO
	MOV	#12,SCREAM
	LDX	KILNUM
	RTS

* Move these guys

MOVPAR
	ZER	PARAS
	STA	LOWCMP
	LDX	#NUMPAR	;do paratroopers
DOPAR	LDA	PARTYP,X	;guy here
	AND	#MANLIV	;to move?
	BEQ	NXTPAR
	INC	PARAS
	LDA	PARTYP,X	;chuteless?
	AND	#MANCHU
	BNE	HASCHU
	LDA	PARVER,X
	CMP	LOWCMP	;lower?
	BCC	HASCHU
	STA	LOWCMP
HASCHU	DEC	PARVEL,X	;countdown
	BNE	NXTPAR
	LDA	PARSPD,X	;reset
	STA	PARVEL,X
	LDA	PARVER,X
	CMP	CORD
	BNE	NXPAR
	LDA	#MANCHU OR MANLIV	;open!
	STA	PARTYP,X
	LDA	FALVEL	;slow him down!
	STA	PARSPD,X
	STA	PARVEL,X
	MOV	#5,CHUSND
NXPAR	JSR	SHOPAR	;move and draw him
NXTPAR	DEX
	BPL	DOPAR
	MOV	LOWCMP,LOWEST
	RTS

* Update the helicopters: Create new
* chopper?  Kill if necessary!
* Drop a paratrooper or a bomb?

MOVCHO
	ZER	CHOPS	;population
	LDA	SHUTLE
	CMP	#CLOUDY
	BNE	NOTCLO
	LDX	#7
	BNE	STCHNM
NOTCLO	LDA	LEVEL	;max of 8 choppers
	LSR	A
	ORA	#1
	TAX		;even
STCHNM	STX	CHONUM
DOCHO	JSR	MOVEM	;move object
	LDX	CHONUM
	LDA	CHOSPD,X	;move?
	CMP	CHOVEL,X
	BNE	JNXCHO
	LDA	DOTIME	;done?
	BEQ	JNXCHO
	JSR	MAYBE	;drop time?
	BCS	JNXCHO
	LDA	SHUTLE	;shuttles?
	BEQ	DOCHOP
	CMP	#CLOUDY	;clouds?
	BEQ	JNXCHO
	LDA	CHOPOS,X	;on screen?
	SUB	#LEFT
	CMP	#XMAX-16
	BCS	JNXCHO
	LDA	LEVEL
	LSR	A
	LSR	A
	TAX
CKBOMS	LDA	BOMLIV,X	;exists?
	BEQ	DROPIT
	DEX
	BPL	CKBOMS
JNXCHO	JMP	NXCHOP	;bag it

DROPIT	LDY	CHONUM
	LDA	ALTVER,Y
	CMP	LANDED,Y
	BCS	JNXCHO
	PHA
	JSR	ERAOLD
	PLA
	ADD	#TOP
	STA	BOMYP,X
	LDA	#0
	STA	BOMYI,X
	STA	BOMYAC,X
	STA	MPFOR,X
	LDA	RANDOM
	AND	#3
	ADD	#2
	STA	BOMSPD,X
	STA	BOMVEL,X
	LDY	CHONUM
	LDA	CHOPOS,Y
	ADD	#4	;center
	STA	BOMXP,X
	SUB	BASPOS	;base
	AND	#7
	BEQ	STBDIR	;straight?
	LDA	#0
	ROL	A
	EOR	#1
	TAY
	LDA	CHODIR,Y	;direction
STBDIR	STA	BOMDIR,X
	INC	BOMLIV,X	;drop bomb X
	MOV	#5,BWOOOP	;sound
	BNE	NXCHOP

DOCHOP	LDA	CHOPOS,X
	SUB	#LEFT-8
	LSR	A
	LSR	A
	LSR	A
	TAX	;correct column
	CPX	#20
	BCS	NXCHOP
	LDA	PARTYP,X	;trooper?
	AND	#MANLIV
	BNE	NXCHOP	;exists
	LDY	CHONUM
	LDA	ALTVER,Y	;get VER
	CMP	LANDED,X
	BCS	NXCHOP
	STA	PARVER,X
	LDA	FALVEL
	LSR	A
	STA	PARSPD,X	;rate of fall
	STA	PARVEL,X
	LDA	#MANLIV	;exists
	STA	PARTYP,X
	JSR	SHOPAR	;and draw him
NXCHOP	DEC	CHONUM	;loop count
	BMI	ENDCHO
	LDX	CHONUM
	JMP	DOCHO

ENDCHO
	MOV	CHOPS,CHONSC
	RTS

MAYBE	LDA	RANDOM
	ORA	RANDOM
	CMP	CHANCE
	RTS

* Move chopper or shuttle X
* and check collision

MOVEM	LDA	CHOLIV,X	;alive?
	BEQ	NEWCHO
	INC	CHOPS
	DEC	CHOVEL,X	;move yet?
	BNE	CKCHOP
	LDA	CHOSPD,X	;restore
	STA	CHOVEL,X
	TXA
	AND	#1
	TAY
	LDA	CHODIR,Y
	CLC
	ADC	CHOPOS,X
	STA	CHOPOS,X
	BNE	CKCHOP
	LDA	SHUTLE
	CMP	#CLOUDY	;cloud?
	BEQ	ENDMOV
	LDA	#0
	STA	CHOLIV,X	;kill
CKCHOP	LDA	SHUTLE	;don't kill clouds
	CMP	#CLOUDY
	BEQ	ENDMOV
	LDA	KILL,X	;was he hit?
	BPL	ENDMOV
	LDA	CHOPOS,X
	SUB	#LEFT-8
	STA	XEXPLO
	LDA	ALTVER,X
	STA	YEXPLO
	LDA	#0	;now zero chopper
	STA	CHOPOS,X
	STA	CHOLIV,X
	LDA	#25
	JSR	INIEXP
	LDA	#6	;60 points
	JSR	ADDSCO
	RTS

NEWCHO	LDA	DOTIME
	BEQ	ENDMOV
	LDA	TIMER
	AND	#$0F
	BNE	ENDMOV
	JSR	MAYBE
	BCS	ENDMOV
	LDA	RANDOM
	AND	#$0F
	ADD	CHORAT	;reappear
	STA	CHOVEL,X
	STA	CHOSPD,X
	LSR	A
	LSR	A
	STA	KILL,X	;resist
	INC	CHOLIV,X	;it lives
ENDMOV	RTS

* For missile work...

ERAOLD	LDA	BOMYP,X	;erase bomb X
	TAY
	DEY
	JSR	MISZER	;7 bytes!
	JSR	MISZER
	JSR	MISZER
	JSR	MISZER
	JSR	MISZER
	JSR	MISZER
	JSR	MISZER
	RTS

MISZER	LDA	MISL,Y	;bits off
	AND	BITOFF,X
	STA	MISL,Y
	INY	;next
	RTS

MISONE	LDA	MISL,Y
	ORA	BITSON,X
	STA	MISL,Y
	RTS

* Move the bombs

BOMBS	DEC	BOMTIM	;time yet?
	BEQ	SETBOM
	RTS

* Reset the time and move 'em

SETBOM
	MOV	BOMRES,BOMTIM
	STA	BOMTIM
	ZER	LOWCMP
	LDX	#NUMBOM
	STX	BOMNUM
DOBOMB	LDA	BOMLIV,X
	BNE	LIVBOM
	JMP	BOTBOM

LIVBOM	LDA	MPFOR,X	;hit the ground?
	AND	#$0E	;exclude shot PF0
	BEQ	DOFALL
	LDA	BOMXP,X
	SUB	#LEFT-3
	LSR	A
	LSR	A
	LSR	A
	TAX
	CPX	#NUMPAR+1	;make sure!
	BCS	JBOTBM
	LDA	LANDED,X
	CMP	ROOF,X
	BEQ	BUILD	;an empty building!
	ADD	#HTPARA	;kill the man
	STA	LANDED,X
	STA	PARVER,X
	JSR	KILPAR	;kill man
JBOTBM	JMP	KILLIT

BUILD	TXA
	TAY
	JSR	DRABLO
	MOV	#25,BWOOOP
	BNE	KILLIT
DOFALL	LDA	MPFOR,X	;hit?
	AND	#1	;shot or explo
	BNE	KILBOM
	INC	BOMYI,X	;gravity
	LDA	BOMYI,X
	CLC
	ADC	BOMYAC,X
	STA	BOMYAC,X
	BCC	XBOMB	;increment?
	INC	BOMYP,X	;move down
	LDA	BOMYP,X	;redraw
	TAY
	CMP	LOWCMP	;make sound?
	BCC	MOVDOW
	STA	LOWCMP
MOVDOW	JSR	MISZER
	LDA	BOMYP,X
	ADD	#4
	TAY
	JSR	MISONE
XBOMB	DEC	BOMVEL,X	;time?
	BNE	BOTBOM
	LDA	BOMSPD,X
	STA	BOMVEL,X
	LDA	BOMDIR,X
	CLC
	ADC	BOMXP,X
	CMP	#LEFT
	BCC	KILBOM
	CMP	#LEFT+XMAX-6
	BCC	SAVBOM
KILBOM	LDA	BOMXP,X
	SUB	#LEFT-3
	STA	XEXPLO
	LDA	BOMYP,X
	SUB	#TOP
	STA	YEXPLO
	LDA	#20
	JSR	INIEXP	;boom
	LDA	#5	;50 points
	JSR	ADDSCO
KILLIT	LDA	#0
	LDX	BOMNUM
	STA	BOMXP,X
	STA	HPOSM0,X	;for now...
	STA	BOMLIV,X
	STA	MPFOR,X
SAVBOM	STA	BOMXP,X	;make sure
BOTBOM	DEC	BOMNUM
	BMI	ENDBOM
	LDX	BOMNUM
	JMP	DOBOMB

ENDBOM
	MOV	LOWCMP,LOWEST
	RTS

* Subtract ten points from score

SUBSCO	LDA	SCORE+1	;cant't be zero!
	ORA	SCORE
	BEQ	ENDSCO
	SED
	LDA	SCORE+1
	SUB	#1	;minus 10 points!
	STA	SCORE+1
	LDA	SCORE
	SBC	#0	;carry
	STA	SCORE
	JMP	SHOSCO

* Add value of accumulator to score

ADDSCO	SED	;for scoring
	ADD	SCORE+1
	STA	SCORE+1
	LDA	SCORE
	ADC	#0	;carry over
	STA	SCORE

SHOSCO	LDY	#1
	LDX	#4
SHO1	LDA	SCORE,Y
	JSR	SHOHEX
	DEX		;skip over comma
	DEY
	BPL	SHO1
	CLD
ENDSCO	RTS

NEXLEV	INC	LEVEL	;add one
	LDA	LEVEL
	AND	#$0F
	STA	LEVEL
	ASL	A
	ASL	A
	ASL	A
	ASL	A
	STA	COLSKY	;for DLI
	STA	COLOR4	;background
SHOLEV	LDY	LEVEL
	LDA	BCD,Y
	LDX	#19	;upper right corner

* Show accumulator as a hex at X

SHOHEX	PHA
	AND	#$0F
	JSR	SHODIG
	PLA
	LSR	A
	LSR	A
	LSR	A
	LSR	A
SHODIG	ORA	#COLMSK OR $10
	STA	SCORLN,X
	DEX
	RTS

BCD	DB	1,2,3,4,5,6,7,8,9,$10
	DB	$11,$12,$13,$14,$15,$16

* Add a building at Y

DRABLO	TYA		;hit the base?
	JSR	CHECKB
	BEQ	ENDBLO	;no draw
	LDA	ROOF,Y	;adjust roof
	CMP	ALTVER+6	;too high?
	BCC	ENDBLO
	PHA
	TAX
	JSR	SETLO	;point
	PLA
	SUB	#HTBLOK
	STA	ROOF,Y
	STA	LANDED,Y
	TAX
	TYA
	ASL	A
	TAY
	LDX	#5
	CLC
DRABL2	LDA	BLOPIC,X	;draw the block
	STA	(LO),Y
	INY
	STA	(LO),Y
	TYA
	ADC	#39
	TAY
	DEX
	BPL	DRABL2
ENDBLO	RTS

* Building graphic

BLOPIC	DB	$C3,$C3,$FF,$C3,$C3,$FF

* Set up landing blocks at bottom

SETBLO	LDX	#NUMBLO
GETRND	LDA	RANDOM
	AND	#$1F	;0-31
	CMP	#20	;0-19
	BCS	GETRND
	TAY
	LDA	LANDED,Y	;taken?
	CMP	#GROUND
	BNE	GETRND
	STX	XREG+1	;self modify
	JSR	DRABLO
XREG	LDX	#0	;gets modified
	DEX
	BPL	GETRND
	RTS

CHARGE
	MOV	#6,NOTNUM
	STA	TUNEON
	RTS

* Check all the buildings...set DEAD
* if half are occupied.

CKDEAD	LDX	#NUMPAR
	LDY	#0
CKDED2	LDA	ROOF,X	;building?
	CMP	#GROUND
	BEQ	CKDED3
	INY
	CMP	LANDED,X	;or man?
	BEQ	CKDED3
	DEY
	DEY
CKDED3	DEX
	BPL	CKDED2
	DEY
	BPL	BASEOK
	MOV	#1,DEAD	;you're out!
BASEOK	RTS

CHECKB	CMP	#9	;do a double check
	BEQ	ENDCK
	CMP	#10
ENDCK	RTS

* Has the base been hit by a trooper?
* Called by SHOPAR to stop gun.

BASHIT	TXA
	JSR	CHECKB
	BNE	ENDCK
	STX	DEAD	;kill
	STX	LEVDON	;no shooting
	ZER	DOTIME	;stop game
	STA	BASPOS

* Blow the base up real good

BLOBAS
	MOV	#1,EXPAND
	MOV	#7,EXPMIN
	MOV	#$FF,EXPMAX
	MOV	#79,XEXPLO
	MOV	#GROUND+3,YEXPLO
	LDA	#[NUMEXP SHR 1]+1	;half
	JMP	INIEXP	;that's it

KILBAS
	MOV	#CLOUDY,SHUTLE
	STA	LEVDON	;kill
	ZER	DOTIME
	JSR	SILENT
	JSR	SHUTUP
	LDX	#$7F
ERAMIS	STA	MISL,X	;erase bombs
	DEX
	BPL	ERAMIS
	STA	BASPOS
	MOV	#4,EXPSPD
BLOBLO
	MOV	#19,XALTER
BLOBL2	LDX	XALTER
	LDA	LANDED,X	;blow 'em up!
	CMP	#GROUND
	BEQ	NEXBLO
	ADD	#3
	STA	YEXPLO
	TXA
	ASL	A
	ASL	A
	ASL	A
	ADC	#3
	STA	XEXPLO
	MOV	#1,EXPAND
	LDA	#3
	JSR	INIEXP
NEXBLO	DEC	XALTER
	BPL	BLOBL2
	BMI	SETWAI

BOOM	JSR	BLOBAS
	MOV	#$80,TIMER
	BNE	ENDGAM
JULY4	LDA	RANDOM	;fireworks
	AND	#$7F
	ADD	#16
	STA	XPLOT
	STA	XEXPLO
	LDA	RANDOM
	AND	#$3F
	STA	YPLOT
	STA	YEXPLO
	JSR	LOCATE
	CMP	#2
	BCS	JULY4
	LDA	#16
	JSR	INIEXP
SETWAI	LDA	RANDOM
	ORA	#1
	STA	TIMER
ENDGAM	JSR	WAITVB
	LDA	CONSOL
	CMP	#7
	BNE	BASEND
	JSR	EXPLO
	LDA	TIMER
	BPL	ENDGAM
	LDA	RANDOM
	ORA	RANDOM
	LSR	A
	BCS	JULY4
	LSR	A
	BCS	BLOBLO
	LSR	A
	BCS	BOOM
BASEND
	MOV	#10,EXPSPD
	JSR	BLOBAS	;last one
	JSR	BLOBAS
	JSR	FINISH	;let finish
	MOV	#GAMOVR,MESMAX
	STA	TITDL+10
	LDA	SCORE	;new high score?
	CMP	HSCORE
	BCC	ENDBAS
	LDA	SCORE+1
	CMP	HSCORE+1
	BCC	ENDBAS
	STA	HSCORE+1
	MOV	SCORE,HSCORE
	LDX	#5
MOVSCO	LDA	SCORLN,X	;move it
	STA	TEXT+[5*20]+13,X
	DEX
	BPL	MOVSCO
	MOV	#HIGHSC,TITDL+10	;point
ENDBAS	JMP	NEWGAM	;try again?

* Begin the next level

NEWLEV
	ZER	DOTIME
	LDA	#1
	JSR	SETTIM	;set minute
	LDA	LEVEL
	AND	#1
	JSR	SHOCHO	;draw choppers
	LDA	SHUTLE
	ASL	A
	ASL	A
	ASL	A
	TAY
	LDX	#7
MOVOPT	LDA	EITHER,Y	;print type
	STA	TEXT+[20*7]+10,X
	INY
	DEX
	BPL	MOVOPT
	MOV	#INCOME,TITDL+10
	JSR	SWITDL	;show message
	JSR	SILENT
	JSR	SHUTUP
	MOV	#$80,TIMER
READIT	JSR	WAITVB
	LDA	TIMER
	BEQ	CONLEV
	ASL	A
	ASL	A
	ASL	A
	EOR	#$0F
	BEQ	READIT
	STA	LOWEST
	BNE	READIT
CONLEV	STA	LOWEST	;zero
	JSR	SWITDL	;back
	LDX	LEVEL	;set up levels
	LDA	LEVCHA,X
	STA	CHANCE
	LDA	LEVRAT,X
	STA	CHORAT
	LDA	LEVEXP,X
	STA	EXPSPD
	STA	EXPTIM
	TXA
	LSR	A
	TAX		;0-7
	LDA	LEVFAL,X	;paratroopers
	STA	FALVEL
	LDA	LEVBOM,X
	STA	BOMRES
	STA	BOMTIM
	TXA
	LSR	A
	TAX		;0-3
	LDA	LEVCOR,X
	STA	CORD
	TXA
	LSR	A
	TAX
	LDA	LEVSHO,X
	STA	SHOSPD
	STA	SHOTIM
	LDA	#0
	LDX	#NUMPAR	;zero databases
ZERPAR	STA	PARTYP,X	;paratroopers
	DEX
	BPL	ZERPAR
	LDX	#NUMBOM
ZERBOM	STA	BOMLIV,X
	STA	BOMXP,X	;horizontal
	DEX
	BPL	ZERBOM
	LDX	#NUMSHO
ZERSHO	STA	SHOLIV,X	;shots
	DEX
	BPL	ZERSHO
	LDX	#NUMEXP
ZEREXP	STA	EXPLIV,X	;explosion
	DEX
	BPL	ZEREXP
	LDX	#NUMCHO
ZERCHO	STA	CHOLIV,X	;choppers
	STA	CHOPOS,X
	STA	KILL,X
	DEX
	BPL	ZERCHO
	LDX	#NUMCHO
SETCOL	TXA
	ADD	#6
	ORA	COLSKY
	EOR	#$F0
	STA	CHOCOL,X
	DEX
	BPL	SETCOL
	ZER	NEXPLO	;start off
	STA	LEVDON	;allow shooting
	RTS

EITHER	DB	'sreppohc'	;back
	DB	'selttuhs'	;wards

SWITDL	JSR	WAITVB	;hold on...
	LDA	TITLST	;OK now swap
	EOR	#6
	STA	TITLST
	TAX
	LDY	#5
DOTITL	LDA	TITDL,X
	STA	GAMEDL+TITOFF,Y
	INX
	DEY
	BPL	DOTITL
	LDA	TITLST
	BEQ	ENDTIT
	LDX	#NUMCHO
MOVCLO	LDA	RANDOM
	AND	#$7F
	ADD	#LEFT+7	;center
	STA	CHOPOS,X
	LDA	RANDOM
	AND	#$0F
	ORA	#$0A
	STA	CHOCOL,X
	DEX
	BPL	MOVCLO
ENDTIT	RTS

NXTMES	LDA	GAMEDL+TITOFF+1
	CMP	MESMAX
	BCC	MOVMES
	JSR	CHARGE
	ZER	GAMEDL+TITOFF+1
	BEQ	ENDMES
MOVMES	LDX	#19	;scroll
SCROLL	JSR	WAITVB
	INC	GAMEDL+TITOFF+1
	TXA
	AND	#1
	ASL	A
	ASL	A
	ASL	A
	STA	AUDC1
	STX	AUDF1
	DEX
	BPL	SCROLL
ENDMES	RTS

TITDL	DB	$0D,$0D,$0D
	DB	$0D,$0D,$0D	;backward
	DB	HIGH [SCRMEM+[40*64]]
	DB	LOW [SCRMEM+[40*64]],$4D
	DB	HIGH TEXT,LOW TEXT,$46

* Game initializes here...

INIT
	ZER	DMACTL	;execution begins here
	STA	AUDCTL	;sounds
	LDX	#VAREND-VARBEG-1
ZERPAG	STA	VARBEG,X	;clear 'em
	DEX
	BPL	ZERPAG
	JSR	SIOINV	;sounds
	JSR	SETSCR	;set up screen
	JSR	CLRSCR	;clear screen
	JSR	CLRPLR
	JSR	SHOSCO
	JSR	ZERTIM
	JSR	SHOLEV
	JSR	ALTPER	;period
	JSR	INITEX
	MOV	#4*20,MESMAX
	MOV	#TRISPD,TRITIM	;for gun
	MOV	#1,LEVDON
	MAD	DLI,VDSLST
	MAD	GAMEDL,SDLSTL
	MOV	#HIGH PMBAS,PMBASE
	MOV	#3,GRACTL
	MOV	#$11,GPRIOR
	LDX	#HIGH VBLANK
	LDY	#LOW VBLANK
	LDA	#6
	JSR	SETVBV
	LDX	#5
DRABAS	LDA	BASPIC,X	;draw base
	STA	PLR0+TOP+GROUND,X
	DEX
	BPL	DRABAS
	MOV	#$C0,NMIEN
	ZER	COLOR0	;shots/explo
	MOV	#$CE,COLOR1	;'troopers
	MOV	#$42,COLOR2	;'chutes
	MOV	#$2E,DMACTL	;on
	ZER	TITDL+10

* A new game starts here...

NEWGAM
	ZER	DEAD
	STA	MPLOR
	STA	DOTIME
	JSR	SHUTUP
	JSR	SILENT
	MOV	#$34,COLOR3	;red sun
	LDX	#NUMCHO
MAKCLO	LDA	RANDOM	;create clouds
	AND	#$0F
	ORA	#3
	STA	CHOLIV,X
	STA	CHOVEL,X
	STA	CHOSPD,X
	DEX
	BPL	MAKCLO
	LDA	#CLOUDY
	JSR	SHOCHO
	JSR	SWITDL	;open a line
	LDX	#7
MOVSUN	LDA	THESUN,X
	STA	MISL+TOP+3,X
	DEX
	BPL	MOVSUN
	ZER	TIMER
	LDA	RANDOM
	AND	#$7F
	ADD	#LEFT+10
	LDX	#3
	CLC
PUTSUN	STA	BOMXP,X
	ADC	#2
	DEX
	BPL	PUTSUN
	STA	HITCLR	;careful!
WAIT	JSR	WAITVB	;a jiffy
	LDA	CONSOL
	AND	#2	;SELECT?
	BNE	CKSTRT
	MOV	#SELECT,GAMEDL+TITOFF+1
	ZER	TIMER
	JSR	NEXLEV	;add one
	MOV	#$10,BINGS
WAISEL	LDA	CONSOL	;let go!
	AND	#2
	BEQ	WAISEL
CKSTRT	LDA	CONSOL
	AND	#1
	AND	STRIG	;either
	BEQ	START
	LDA	TIMER
	AND	#$7F	;switch?
	BNE	WAIT
	JSR	NXTMES
	JMP	WAIT	;bottom of loop

JNEWGM	JMP	NEWGAM

START
	ZER	SCORE
	STA	SCORE+1
	JSR	SHOSCO
	JSR	SWITDL	;restore
WAISTR	LDA	CONSOL	;let go
	LSR	A
	BCC	WAISTR
	JSR	CLRSCR
	MOV	#125,BASPOS	;place gun
	MOV	#6,JIFFY
	LDA	#0
	LDX	#7
ZERSUN	STA	MISL+TOP+3,X
	DEX
	BPL	ZERSUN
	MOV	#$2E,COLOR3	;bombs
	LDX	#NUMPAR
	LDA	#GROUND
ZERLAN	STA	LANDED,X
	STA	ROOF,X
	DEX
	BPL	ZERLAN
	LDA	#GROUND-HTBLOK	;hold base
	LDX	#1
FIXLAN	STA	LANDED+9,X
	STA	ROOF+9,X
	DEX
	BPL	FIXLAN
	JSR	SETBLO	;now it's ok

* Next level begins here...

GAME	JSR	NEWLEV	;a level begins!
	MOV	#1,DOTIME	;start clock up
LOOP	LDA	CONSOL
	CMP	#7
	BEQ	GAMCON
	MOV	#SELECT,TITDL+10
	JMP	NEWGAM

GAMCON	JSR	MOVCHO	;choppers/shuttles
	JSR	SHOTS	;do shots
	JSR	EXPLO	;explosion
	LDA	SHUTLE	;shuttles?
	BNE	LOOP2	;fork
	JSR	MOVPAR	;paratroopers
	JSR	DOBLAD	;animation
	JMP	LOOP3

LOOP2	JSR	BOMBS	;bombs
	LDA	MPLOR	;base hit?
	BEQ	LOOP3
	JMP	KILBAS	;blow up

LOOP3	LDA	DOTIME	;done yet?
	BNE	LOOP	;bottom of loop
	LDX	#NUMBOM
CKOVER	ORA	BOMLIV,X	;all of these
	DEX
	BPL	CKOVER
	ORA	PARAS	;must be zero
	ORA	CHOPS
	BNE	LOOP	;wait for those
	MOV	#10,EXPSPD	;do quickly
	STA	SHOSPD
	STA	LEVDON	;no shooting
	JSR	FINISH
	JSR	CKDEAD
	LDA	DEAD
	BNE	KILLEM
	JSR	NEXLEV	;next level...
	JMP	GAME

KILLEM	JMP	KILBAS

* Let the EXPLOsions and SHOTs quit

FINISH	JSR	SHOTS
	JSR	EXPLO
	LDA	#0
	LDX	#NUMSHO
CKSHOS	ORA	SHOLIV,X
	DEX
	BPL	CKSHOS
	LDX	#NUMEXP
CKEXPL	ORA	EXPLIV,X
	DEX
	BPL	CKEXPL
	CMP	#0
	BNE	FINISH
	RTS

* If time to, animate the blades

DOBLAD	DEC	BLATIM	;time?
	BNE	ENDBLA
	MOV	#23,BLATIM
	LDA	BLADE	;next picture
	ADD	#1
	AND	#3	;0-3
	STA	BLADE
	TAX
	LDY	#0
	LDA	BLLEF1,X
	JSR	DOPLR0
	LDA	BLLEF2,X
	JSR	DOPLR1
	LDA	BLRIG1,X
	JSR	DOPLR2
	LDA	BLRIG2,X
	JSR	DOPLR3
ENDBLA	RTS

* Draw the helicopters (or shuttles)

SHOCHO	STA	SHUTLE
	TAY
	LDX	MULT48,Y	;multiply by 48
	LDY	#0
CHO2	LDA	CHLEF1,X
	JSR	DOPLR0
	LDA	CHLEF2,X
	JSR	DOPLR1
	LDA	CHRIG1,X
	JSR	DOPLR2
	LDA	CHRIG2,X
	JSR	DOPLR3
	INX
	INY
	CPY	#12
	BCC	CHO2
	RTS

MULT48	DB	0,48,96	;times 48

* Player images
CHRIG1	DB	$07,$00,$00,$C0,$FF,$3F
	DB	$07,$01,$00,$00,$00,$01
CHRIG2	DB	$FF,$20,$78,$E4,$E2,$E2
	DB	$E2,$E2,$FC,$78,$11,$FE
CHLEF1	DB	$FF,$04,$1E,$27,$47,$47
	DB	$47,$47,$3F,$1E,$88,$7F
CHLEF2	DB	$E0,$00,$00,$03,$FF,$FC
	DB	$E0,$80,$00,$00,$00,$80

* Space shuttle
SHRIG1	DB	$E0,$F0,$F0,$F8,$FC,$7E
	DB	$7F,$FF,$FF,$FF,$FC,$7B
SHRIG2	DB	0,0,0,0,0,0
	DB	$F8,$E4,$FE,$FF,$1F,$EC
SHLEF1	DB	0,0,0,0,0,0
	DB	$1F,$27,$7F,$FF,$F8,$37
SHLEF2	DB	$07,$0F,$0F,$1F,$3F,$7E
	DB	$FE,$FF,$FF,$FF,$3F,$DE
CLOUDS	DB	0,0,0,0,0,$0C
	DB	$1F,$1F,$F,$3F,$FE,0
	DB	0,0,$30,$78,$FD,$FF
	DB	$FF,$FE,$FF,$FF,$EC,0
	DB	0,0,$0C,$1E,$5F,$FF
	DB	$FF,$7F,$FF,$FF,$37,0
	DB	0,0,0,0,0,$30
	DB	$F8,$F8,$F0,$FC,$7F,0
BLRIG1	DB	$04,$06,$03,$01	;blades
BLRIG2	DB	$71,$1C,$06,$C3
BLLEF1	DB	$8E,$C3,$60,$38
BLLEF2	DB	$20,$80,$C0,$60
THESUN	DB	$3C,$7E,$FF,$FF
	DB	$FF,$FF,$7E,$3C

* ORA the MnPFs together

ORM0PF	LDX	#3
OR2	LDA	M0PF,X	;save collision
	ORA	MPFOR,X
	STA	MPFOR,X
	DEX
	BPL	OR2
	RTS

* The DL interrupt checks shot-
* chopper collisions, gives the
* choppers color & position and gives
* the bombs their expanding effect.

DLI	PHA
	TXA
	PHA
	TYA
	PHA
	CLD
	LDX	DLIPNT
	LDY	#0
DLI1	LDA	P0PF,Y	;chopper hit?
	ORA	P1PF,Y
	AND	#1
	BEQ	DLI2
	DEC	KILL-2,X	;hit him
	LDA	CHOSPD-2,X	;slow down!
	STA	CHOHIT
	SUB	#2
	STA	CHOSPD-2,X
DLI2	INX
	INY
	INY
	CPY	#4
	BCC	DLI1
	JSR	ORM0PF
	LDA	DLIPNT
	ADD	#2
	ORA	COLSKY
	STA	WSYNC
	STA	COLBK	;color of sky
	STA	HITCLR	;clear collisions
	LDX	DLIPNT
	LDY	#0
DLI3	LDA	CHOCOL,X	;show choppers
	STA	PMCOL0,Y
	STA	PMCOL0+1,Y
	LDA	CHOPOS,X
	STA	HPOSP0,Y	;new player
	ADD	#8
	INY
	STA	HPOSP0,Y	;and right
	INX
	INY
	CPY	#4
	BCC	DLI3
	STX	DLIPNT	;update it

	CPX	#6	;handle bombs
	LDA	BOMSIZ
	ROL	A
	AND	#3
	STA	BOMSIZ
	EOR	#3
	STA	BOMOFF
	LDX	#NUMBOM
FIXSIZ	LDA	BOMSIZ	;expand BOMSIZ
	ASL	A
	ASL	A	;for 8 bits
	ORA	BOMSIZ
	STA	BOMSIZ
	DEX
	BPL	FIXSIZ
	STA	WSYNC
	STA	SIZEM	;bomb width
	LDX	#NUMBOM
	CLC
SHOBOM	LDA	BOMXP,X	;show bombs
	ADC	BOMOFF
	STA	HPOSM0,X
	DEX
	BPL	SHOBOM
	PLA
	TAY
	PLA
	TAX
	PLA
	RTI

* Clock is 0:00.0 set minutes with A

ZERTIM	LDA	#0	;early entry
SETTIM	PHA		;set clock for minutes
	LDX	#5
	LDA	#0
	JSR	PUTDIG
	DEX		;period
	JSR	PUTDIG
	JSR	PUTDIG
	DEX		;colon
	PLA
	JSR	PUTDIG
	RTS

* Clock subroutines for VBLANK

ALTCOL	LDA	TIME+1	;blink punctuation
	EOR	#CHCOL OR COLMSK
	STA	TIME+1
ALTPER	LDA	TIME+4
	EOR	#CHPER OR COLMSK
	STA	TIME+4
	RTS

GETDIG	DEC	TIME,X	;subtract
	LDA	TIME,X
	AND	#$0F
	CMP	#10	;and check overflow
	RTS

PUTDIG	ORA	#COLMSK OR $10	;get ready
	STA	TIME,X
	DEX
	RTS

* The vertical blank occurs every
* 60th of a second to adjust time,
* read the joystick, check collisions
* and update the sounds.

VBLANK	CLD
	ZER	DLIPNT	;reset DLI pointer
	STA	BOMSIZ
	INC	TIMER	;general timer
	LDA	DOTIME	;do time now?
	BEQ	CKSTIK
	DEC	JIFFY
	BNE	CKSTIK
	MOV	#6,JIFFY
	LDX	#5	;tenth of a second
	JSR	GETDIG
	BCC	CKSTIK
	LDA	#9	;reset and borrow
	JSR	PUTDIG
	JSR	ALTCOL	;flop
	DEX		;skip period
	JSR	GETDIG	;do seconds
	BCC	CKSTIK
	LDA	#9
	JSR	PUTDIG
	JSR	GETDIG
	BCC	CKSTIK
	LDA	#5
	JSR	PUTDIG
	DEX		;skip colon
	JSR	GETDIG	;do minutes
	BCC	CKSTIK
	ZER	DOTIME	;stop clock
	JSR	ZERTIM	;zero time
	MOV	#$30,BINGS
CKSTIK	LDA	TIMER
	AND	#3
	BNE	CKTRIG
	LDA	STICK	;create delta
	LSR	A
	LSR	A
	EOR	#3	;flip around
	TAX
	LDA	DIREC,X
	ADD	GUNROT
	CMP	#11	;no wrap
	BCS	CKTRIG
	STA	GUNROT
	TAX
	ASL	A
	ASL	A
	ASL	A
	ASL	A
	ORA	#8	;half shade
	STA	BASCOL
	LDA	COSDEC,X
	STA	XDRDEC
	LDA	COSINT,X
	STA	XDRINT
	LDA	SINDEC,X
	STA	YDRDEC
	LDA	SININT,X
	STA	YDRINT
	TXA		;draw new gun
	ASL	A
	ASL	A	;times four
	TAY
	LDX	#3	;four bytes
SHOGUN	LDA	GUNPIC,Y
	STA	PLR0+TOP+73,X
	INY
	DEX
	BPL	SHOGUN	;an NBC show
	BMI	CKCOLL
CKTRIG	DEC	TRITIM
	BNE	CKCOLL
	MOV	#TRISPD,TRITIM
	LDA	LEVDON	;ok to shoot?
	BEQ	TRIZER
	LDA	SHUTLE
	CMP	#CLOUDY
	BNE	CKCOLL
	JSR	MOVCHO	;move clouds
	JMP	CKCOLL

TRIZER	LDA	STRIG	;trigger?
	BNE	CKCOLL
	STA	ATRACT
	LDX	#NUMSHO
CKLIV	LDA	SHOLIV,X	;empty?
	BEQ	DOSHOT
	DEX
	BPL	CKLIV
	STX	BASCOL
	BMI	CKCOLL	;bullets!
DOSHOT	LDA	BASPOS
	EOR	#1
	STA	BASPOS
	SUB	#LEFT-4
	STA	SHXINT,X
	LDA	#GROUND
	STA	SHYINT,X
	LDA	#0
	STA	SHXDEC,X
	STA	SHYDEC,X
	INC	SHOLIV,X
	MOV	#16,SHOVOL
	JSR	SUBSCO	;lose points
CKCOLL	LDX	#3
	LDA	MPLOR
CKBASE	ORA	M0PL,X	;base hit?
	DEX
	BPL	CKBASE
	AND	#1	;just PL0
	STA	MPLOR
	JSR	ORM0PF
	STA	HITCLR
	LDA	TIMER	;sound effects
	AND	#3
	BEQ	BRITNS
	LDA	SHOVOL
	BEQ	STAUD1
	DEC	SHOVOL
	MOV	SHOVOL,AUDF1
	ORA	#$20
STAUD1	STA	AUDC1
	JMP	DOAUD2

BRITNS	LDA	BRIGHT
	BEQ	STAUD1
	STA	COLOR0	;b/w
	ORA	#$40
	STA	AUDC1
	LDA	RANDOM
	AND	#$1F
	ADD	#40
	STA	AUDF1
	DEC	BRIGHT
DOAUD2	LDA	TUNEON	;playing charge?
	BEQ	LOWSND
	LDA	TIMER	;time to update?
	AND	#1
	BNE	DOAUD3
	LDA	NOTVOL	;volume
	ORA	#$A0
	STA	AUDC2
	DEC	NOTVOL	;lower volume
	BPL	DOAUD3
	DEC	NOTNUM	;next note
	BPL	NEXNOT
	ZER	TUNEON	;kill tune
	STA	NOTVOL
	STA	NOTNUM
	BEQ	LOWSND
NEXNOT	LDX	NOTNUM
	LDA	NOTES,X
	STA	AUDF2
	LDX	#5	;note length
	CMP	#60	;long note?
	BNE	SHNOTE
	LDX	#10
SHNOTE	STX	NOTVOL
	BNE	DOAUD3
NOTES	DB	60,72,60,72,91,121
LOWSND	LDA	LOWEST
	BEQ	ZERLOW
	STA	AUDF2
	LDA	#$A8
ZERLOW	STA	AUDC2

DOAUD3	LDA	SHUTLE
	SUB	#2
	BEQ	NOBLAS
	LDA	CHOHIT	;a chopper hit?
	BEQ	ENGSND
	STA	AUDF3
	MOV	#$A8,AUDC3
	ZER	CHOHIT
	BEQ	DOAUD4
ENGSND	LDA	CHONSC
	BEQ	NOBLAS
	LDA	SHUTLE
	BEQ	CHOSND
	LDA	CHONSC	;use for volume
	PHA
	ORA	#$C0
	STA	AUDC3
	PLA
	ASL	A
	ASL	A
	ASL	A
	ADD	#120
	STA	AUDF3
	BNE	DOAUD4
CHOSND	INC	BLASND
	LDA	BLASND
	AND	#$0F
	STA	BLASND
	TAX
	LDA	BLAFRQ,X
	STA	AUDF3
	LDA	CHONSC
	CLC
	ADC	BLACNT,X
NOBLAS	STA	AUDC3

* lots of sound effects here

DOAUD4
	ZER	AUDC4	;make sure
	LDA	CHUSND
	BEQ	CKRIP
	TAX
	LDA	CHUFRQ-1,X
	STA	AUDF4
	LDA	CHUCNT-1,X
	STA	AUDC4
	DEC	CHUSND
CKRIP	LDA	RIPSND	;ripping sound
	BEQ	CKYELL
	STA	AUDF4
	TAX
	LDA	RIPCNT-1,X
	STA	AUDC4
	DEC	RIPSND
CKYELL	LDA	SCREAM
	BEQ	CKBWOP
	TAX
	LDA	SCRFRQ-1,X
	STA	AUDF4
	LDA	SCRCNT-1,X
	STA	AUDC4
	DEC	SCREAM
CKBWOP	LDA	BWOOOP
	BEQ	CKBING
	ASL	A
	ASL	A
	ASL	A
	STA	AUDF4
	MOV	#$A6,AUDC4
	DEC	BWOOOP
CKBING	LDA	BINGS	;bing sound?
	BEQ	ENDVBI
	MOV	#80,AUDF4
	DEC	BINGS
	LDA	BINGS
	AND	#$0F
	ORA	#$A0
	STA	AUDC4
ENDVBI	JMP	SYSVBV	;exit VBI

SCRCNT	DB	$A3,$A4,$A5,$A7,$A9,$A8
	DB	$A7,$A6,$A8,$AA
SCRFRQ	DB	4,6,9,11,15,12,17,13,19,14
RIPCNT	DB	12,10,8,6,5,4,3,2,2,1
CHUCNT	DB	$45,$47,$49,$4B,$4D,$4F
CHUFRQ	DB	10,14,18,22,26,30

BLAFRQ	DB	10,11,12,13,14,13,12,11,10
	DB	9,8,7,6,7,8,9
BLACNT	DB	3,2,1,0,3,2,1,0,2,1,0,2
	DB	2,0,1,0

COS15	=	$E1
COS30	=	$DD
COS45	=	$B4
COS60	=	$80
COS75	=	$42
COS90	=	0
COS105	=	0-COS75
COS120	=	0-COS60
COS135	=	0-COS45
COS150	=	0-COS30
COS165	=	0-COS15
SIN15	=	COS105
SIN30	=	COS120
SIN45	=	COS135
SIN60	=	COS150
SIN75	=	COS165
SIN90	=	0-$100

COSDEC	DB	LOW COS165,LOW COS150
	DB	LOW COS135,LOW COS120
	DB	LOW COS105,LOW COS90
	DB	LOW COS75,LOW COS60
	DB	LOW COS45,LOW COS30
	DB	LOW COS15
COSINT	DB	HIGH COS165,HIGH COS150
	DB	HIGH COS135,HIGH COS120
	DB	HIGH COS105,HIGH COS90
	DB	HIGH COS75,HIGH COS60
	DB	HIGH COS45,HIGH COS30
	DB	HIGH COS15
SINDEC	DB	LOW SIN15,LOW SIN30
	DB	LOW SIN45,LOW SIN60
	DB	LOW SIN75,LOW SIN90
	DB	LOW SIN75,LOW SIN60
	DB	LOW SIN45,LOW SIN30
	DB	LOW SIN15
SININT	DB	HIGH SIN15,HIGH SIN30
	DB	HIGH SIN45,HIGH SIN60
	DB	HIGH SIN75,HIGH SIN90
	DB	HIGH SIN75,HIGH SIN60
	DB	HIGH SIN45,HIGH SIN30
	DB	HIGH SIN15

SCORLN	DB	0,0,CHCOM OR COLMSK,0,0
	DB	$10 OR COLMSK,0,0,0,0,0
	DB	CHCOL OR COLMSK,0,0
	DB	CHPER OR COLMSK,0,0,0,0,0

TIME	=	SCORLN+9	;center it

* Pictures of things...

* Gun at angles

GUNPIC	DB	$F8,$F8,$00,$00
	DB	$78,$F0,$40,$00
	DB	$38,$70,$60,$00
	DB	$38,$70,$70,$20
	DB	$38,$38,$70,$70
	DB	$38,$38,$38,$38	;vertical
	DB	$38,$38,$1C,$1C
	DB	$38,$1C,$1C,$08
	DB	$38,$1C,$0C,$00
	DB	$3C,$1E,$04,$00
	DB	$3E,$3E,$00,$00

BASPIC	DB	$38,$7C,$7C,$FE,$FE,$FE

* Paratrooper images
PARLEF	DB	$00,$00,$02,$2A,$02,$28
	DB	0,0
	DB	$0F,$3F,$30,$2A,$02,$28
	DB	0,0,0,0,0,0,0,0,0,0
	DB	0,0,$22,$0A,$02,$28,0,0
PARRIG	DB	$00,$00,$80,$A8,$80,$28
	DB	0,0
	DB	$F0,$FC,$0C,$A8,$80,$28
	DB	0,0,0,0,0,0,0,0,0,0
	DB	0,0,$88,$A0,$80,$28,0,0
DIREC	DB	0
CHODIR	DB	0-1,1,0

* Level database

LEVEXP	DB	70,90,65,80,80,80,80,70
	DB	80,80,90,80,40,70,30,50
LEVRAT	DB	70,30,65,30,50,45,40,35
	DB	30,25,21,18,14,11,8,5
LEVCHA	DB	10,20,30,30,40,40,50,50
	DB	60,60,70,70,80,90,100,110
LEVFAL	DB	$FF,$C0,$B0,$A0
	DB	$90,$70,$50,$30
LEVBOM	DB	35,30,25,20,15,10,5,3
LEVVEL	DB	$BF,$3F,$1F,$14	;speed
LEVCOR	DB	20,34,44,54	;cord
LEVSHO	DB	18,11
ALTVER	DB	8,8,22,22,36,36,50,50

* Explosion database

EXPLIV	DS	NUMEXP+1
EXPXP	DS	64
EXPYP	DS	64
EXPXI	DS	64
EXPYI	DS	64
EXPXAC	DS	64
EXPYAC	DS	64
EXPDIR	DS	64

* Shot database

SHOLIV	DS	NUMSHO+1	;exists?
SHXINT	DS	16	;position on screen
SHYINT	DS	16
SHXDEC	DS	16
SHYDEC	DS	16
SHVDEC	DS	16	;for gravity
SHVINT	DS	16

* Paratrooper database

PARTYP	DS	NUMPAR+1	;D3=chute D2=landed D0=exists
PARVEL	DS	20	;countdown to inc'
PARSPD	DS	20
PARVER	DS	20	;vertical position
LANDED	DS	20	;landed on ground
ROOF	DS	20	;height of roofs

* Chopper database

	DS	2	;just to be safe
CHOVEL	DS	NUMCHO+1	;countdown
	DS	2
CHOSPD	DS	8	;reset value
	DS	2
CHOTIM	DS	8
	DS	2
CHOCOL	DS	8	;chopper color
	DS	2
BASCOL	=	CHOCOL+NUMCHO+1	;color
CHOPOS	DS	8
	DS	2
BASPOS	=	CHOPOS+NUMCHO+1	;gun
CHOLIV	DS	8
	DS	2
KILL	DS	8	;resistance to shot
	DS	2

* The four bombs are missles

BOMLIV	DS	NUMBOM+1
BOMXP	DS	4
BOMVEL	DS	4	;rate of fall
BOMSPD	DS	4
BOMYP	DS	4
BOMYI	DS	4
BOMYAC	DS	4
BOMDIR	DS	4	;direction

* Screen memory lookup

SCRLO	DS	YMAX+1	;memory pointers
SCRHI	DS	YMAX+1

* And that's all she wrote!

	END	INIT