Space Hi-way disassembly ======================== Space Hi-way was written by Mat Newman, and was published by Amcom for the BBC Micro in 1983. It is a shoot-em-up in which the player must defend a fuel station from waves of aliens. The following disassembly was created by reverse engineering binary images, without access to any source code. It is nevertheless reasonably complete, allowing the technical approaches used to be understood. The author of this disassembly imposes no additional copyright restrictions beyond those already present on the game itself. It is provided for educational purposes only, and it is hoped that the original authors will accept it in the good faith it was intended - as a tribute to their skills. Interesting pokes ================= &2600 = &00 infinite lives &195d = &60 infinite fuel &275a = &ea invulnerability Loader disassembly ================== ; HI-WAY ; 00004000 0000801F 02E0 &4000 0d # Start of BASIC program &4001 00 0a 1d ee 20 85 20 f1 22 48 41 4e 47 20 4f 4e ; 10ON ERROR PRINT"HANG ON!!!!!":GOTO160 &4011 21 21 21 21 21 22 3a e5 8d 74 60 40 0d &401e 00 14 14 eb 37 3a ef 32 33 3b 31 31 3b 30 3b 30 ; 20MODE7: &402e 3b 30 3b 0d ; VDU23;11;0;0;0; # Disable cursor &4032 00 1e 34 f1 8a 31 30 2c 33 29 bd 31 34 31 3b bd ; 30PRINTTAB(10,3)CHR$141;CHR$&86;CHR$157;CHR$&84;"Space Hi_Way ";CHR$156 &4042 26 38 36 3b bd 31 35 37 3b bd 26 38 34 3b 22 53 &4052 70 61 63 65 20 48 69 5f 57 61 79 20 20 22 3b bd &4062 31 35 36 0d &4066 00 28 34 f1 8a 31 30 2c 34 29 bd 31 34 31 3b bd ; 40PRINTTAB(10,4)CHR$141;CHR$&86;CHR$157;CHR$&84;"Space Hi_Way ";CHR$156 &4076 26 38 36 3b bd 31 35 37 3b bd 26 38 34 3b 22 53 &4086 70 61 63 65 20 48 69 5f 57 61 79 20 20 22 3b bd &4096 31 35 36 0d &409a 00 32 2e f1 8a 36 2c 38 29 bd 31 34 31 3b bd 26 ; 50PRINTTAB(6,8)CHR$141;CHR$&81;"Copyright (c) Amcom 1983" &40aa 38 31 3b 22 43 6f 70 79 72 69 67 68 74 20 28 63 &40ba 29 20 41 6d 63 6f 6d 20 31 39 38 33 22 0d &40c8 00 3c 2e f1 8a 36 2c 39 29 bd 31 34 31 3b bd 26 ; 60PRINTTAB(6,9)CHR$141;CHR$&81;"Copyright (c) Amcom 1983" &40d8 38 31 3b 22 43 6f 70 79 72 69 67 68 74 20 28 63 &40e8 29 20 41 6d 63 6f 6d 20 31 39 38 33 22 0d &40f6 00 46 3d f1 8a 36 2c 31 33 29 bd 31 34 31 3b bd ; 70PRINTTAB(6,13)CHR$141;CHR$&86;CHR$157;CHR$&84;"Written by Mat Newman ";CHR$156 &4106 26 38 36 3b bd 31 35 37 3b bd 26 38 34 3b 22 57 &4116 72 69 74 74 65 6e 20 62 79 20 4d 61 74 20 4e 65 &4126 77 6d 61 6e 20 20 22 3b bd 31 35 36 0d &4133 00 50 3d f1 8a 36 2c 31 34 29 bd 31 34 31 3b bd ; 80PRINTTAB(6,14)CHR$141;CHR$&82;CHR$157;CHR$&84;"Written by Mat Newman ";CHR$156 &4143 26 38 32 3b bd 31 35 37 3b bd 26 38 34 3b 22 57 &4153 72 69 74 74 65 6e 20 62 79 20 4d 61 74 20 4e 65 &4163 77 6d 61 6e 20 20 22 3b bd 31 35 36 0d &4170 00 5a 47 f1 8a 31 2c 31 37 29 bd 31 34 31 3b bd ; 90PRINTTAB(1,17)CHR$141;CHR$&83;CHR$157;CHR$&84;"Ideas by Mat Newman & Dan Tench ";CHR$156 &4180 26 38 33 3b bd 31 35 37 3b bd 26 38 34 3b 22 49 &4190 64 65 61 73 20 62 79 20 4d 61 74 20 4e 65 77 6d &41a0 61 6e 20 26 20 44 61 6e 20 54 65 6e 63 68 20 20 &41b0 22 3b bd 31 35 36 0d &41b7 00 64 47 f1 8a 31 2c 31 38 29 bd 31 34 31 3b bd ; 100PRINTTAB(1,18)CHR$141;CHR$&87;CHR$157;CHR$&84;"Ideas by Mat Newman & Dan Tench ";CHR$156 &41c7 26 38 37 3b bd 31 35 37 3b bd 26 38 34 3b 22 49 &41d7 64 65 61 73 20 62 79 20 4d 61 74 20 4e 65 77 6d &41e7 61 6e 20 26 20 44 61 6e 20 54 65 6e 63 68 20 20 &41f7 22 3b bd 31 35 36 0d &41fe 00 6e 21 f1 8a 32 2c 32 30 29 bd 26 38 35 3b 22 ; 110PRINTTAB(2,20)CHR$&85;"Thanks also to:" &420e 54 68 61 6e 6b 73 20 61 6c 73 6f 20 74 6f 3a 22 &421e 0d &421f 00 78 1b f1 8a 31 38 2c 32 31 29 bd 26 38 37 3b ; 120PRINTTAB(18,21)CHR$&87;"Pete Gee" &422f 22 50 65 74 65 20 47 65 65 22 0d &423a 00 82 1e f1 8a 31 38 2c 32 32 29 bd 26 38 37 3b ; 130PRINTTAB(18,22)CHR$&87;"Chris Clare" &424a 22 43 68 72 69 73 20 43 6c 61 72 65 22 0d &4258 00 8c 1a f1 8a 31 38 2c 32 33 29 bd 26 38 37 3b ; 140PRINTTAB(18,23)CHR$&87;"'Eddie'" &4268 22 27 45 64 64 69 65 27 22 0d &4272 00 96 10 ef 32 38 2c 30 2c 32 2c 33 39 2c 30 0d ; 150VDU28,0,2,39,0 # Define text window &4281 00 a0 0b d0 3d 26 34 30 30 30 0d ; 160PAGE=&4000 &428c 00 aa 0c d7 22 41 4d 43 4f 4d 22 0d ; 170CHAIN"AMCOM" &4298 00 b4 16 52 24 3d 22 81 20 20 20 20 20 20 20 8d ; 180R$=" HELLO &42a8 48 45 4c 4c 4f 0d &42ae 00 be 16 52 24 3d 22 81 20 20 20 20 20 20 20 8d ; 190R$=" HELLO &42be 48 45 4c 4c 4f 0d &42c5 ff # End of BASIC program ; unused &42c6 30 30 00 00 00 00 00 30 30 30 00 00 00 00 00 30 &42d6 30 30 00 00 00 00 00 30 30 30 ; AMCOM ; 00004000 0000801F 1220 &4000 0d # Start of BASIC program &4001 00 0a 11 d2 3d 26 36 30 30 30 3a 2a 46 58 31 35 ; 10LOMEM=&6000: &4011 0d ; *FX15 # Flush buffers &4012 00 14 26 52 24 3d 22 41 6d 63 6f 6d 20 61 67 61 ; 20R$="Amcom against REM statements." &4022 69 6e 73 74 20 52 45 4d 20 73 74 61 74 65 6d 65 &4032 6e 74 73 2e 22 0d &4038 00 1e 0e ee 20 85 20 e5 20 8d 74 6a 40 0d ; 30ON ERROR GOTO 170 &4046 00 28 74 e2 31 2c 31 2c 2d 32 2c 2d 31 2c 2d 31 ; 40ENVELOPE1,1,-2,-1,-1,10,10,&64,127,&EC,-2,-4,127,&3C: &4056 2c 31 30 2c 31 30 2c 26 36 34 2c 31 32 37 2c 26 ; R$="FIRE ": &4066 45 43 2c 2d 32 2c 2d 34 2c 31 32 37 2c 26 33 43 ; *KEY10F.T%=&DC0 TO &3000S.255:$T%=STRING$(255," "):N.|M &4076 3a 52 24 3d 22 46 49 52 45 15 22 3a 2a 4b 45 59 ; &4086 31 30 46 2e 54 25 3d 26 44 43 30 20 54 4f 20 26 ; &4096 33 30 30 30 53 2e 32 35 35 3a 24 54 25 3d 53 54 ; &40a6 52 49 4e 47 24 28 32 35 35 2c 22 20 22 29 3a 4e ; &40b6 2e 7c 4d 0d &40ba 00 32 0a 52 24 3d 22 06 22 0d ; 50R$=" " &40c4 00 3c 40 e2 32 2c 31 2c 26 37 37 2c 26 39 43 2c ; 60ENVELOPE2,1,&77,&9C,&47,10,10,&64,&14,0,0,-2,100,100: &40d4 26 34 37 2c 31 30 2c 31 30 2c 26 36 34 2c 26 31 ; R$="FUELCATCH" &40e4 34 2c 30 2c 30 2c 2d 32 2c 31 30 30 2c 31 30 30 &40f4 3a 52 24 3d 22 46 55 45 4c 43 41 54 43 48 22 0d &4104 00 46 50 e2 33 2c 32 2c 2d 34 2c 2d 32 2c 2d 31 ; 70ENVELOPE3,2,-4,-2,-1,8,10,100,0,0,0,0,0,0: &4114 2c 38 2c 31 30 2c 31 30 30 2c 30 2c 30 2c 30 2c ; R$="EXPLOSIONS ": &4124 30 2c 30 2c 30 3a 52 24 3d 22 45 58 50 4c 4f 53 ; ?&212=0: # Set FILEV &4134 49 4f 4e 53 15 22 3a 3f 26 32 31 32 3d 30 3a 3f ; ?&213=&51: # to &5100 (load_main_binary) &4144 26 32 31 33 3d 26 35 31 3a 52 24 3d 22 06 22 0d ; R$=" " &4154 00 50 3c e2 34 2c 31 2c 34 2c 2d 32 2c 34 2c 32 ; 80ENVELOPE4,1,4,-2,4,20,10,30,&32,0,0,&EC,127,127: &4164 30 2c 31 30 2c 33 30 2c 26 33 32 2c 30 2c 30 2c ; R$="BONUS LIFE" &4174 26 45 43 2c 31 32 37 2c 31 32 37 3a 52 24 3d 22 &4184 42 4f 4e 55 53 20 4c 49 46 45 22 0d &4190 00 5a 41 eb 37 3a e3 54 25 3d 30 b8 31 3a f1 8a ; 90MODE7: &41a0 30 2c 54 25 29 3b bd 26 38 31 2b bd 31 35 37 2b ; FORT%=0TO1: &41b0 bd 26 38 36 2b bd 31 34 31 3b 89 28 31 30 29 3b ; PRINTTAB(0,T%);CHR$&81+CHR$157+CHR$&86+CHR$141;SPC(10);"Space Hi-way": &41c0 22 53 70 61 63 65 20 48 69 2d 77 61 79 22 3a ed ; NEXT &41d0 0d &41d1 00 64 11 ef 32 38 2c 30 2c 32 34 2c 33 39 2c 32 ; 100VDU28,0,24,39,2 # Define text window &41e1 0d &41e2 00 6e 0a f2 42 4c 55 52 42 0d ; 110PROCBLURB &41ec 00 78 12 e7 20 49 4e 53 54 3d 30 20 e5 8d 74 6a ; 120IF INST=0 GOTO170 &41fc 40 0d &41fe 00 82 0a f2 42 47 52 4e 44 0d ; 130PROCBGRND &4208 00 8c 09 f2 4c 41 53 41 0d ; 140PROCLASA &4211 00 96 0d f2 46 55 45 4c 53 48 49 50 0d ; 150PROCFUELSHIP &421e 00 a0 09 f2 4b 45 59 53 0d ; 160PROCKEYS &4227 00 aa 30 ef 32 38 2c 30 2c 32 34 2c 33 39 2c 32 ; 170VDU28,0,24,39,22: # Define text window &4237 32 3a db 3a f1 22 50 52 45 53 53 20 50 4c 41 59 ; CLS: &4247 22 3a 2a 4c 4f 41 2e 22 48 49 5f 57 41 59 22 0d ; PRINT"PRESS PLAY": ; *LOA."HI_WAY" # Actually calls load_main_binary &4257 00 b4 0b dd f2 42 4c 55 52 42 0d ; 180DEFPROCBLURB &4262 00 be 4a db 3a f1 27 27 22 54 55 52 4e 20 4f 46 ; 190CLS: &4272 46 20 54 41 50 45 20 50 4c 41 59 45 52 22 27 27 ; PRINT''"TURN OFF TAPE PLAYER"'''''" Do you want instructions??? (y/n)"; &4282 27 27 27 22 20 20 44 6f 20 79 6f 75 20 77 61 6e &4292 74 20 69 6e 73 74 72 75 63 74 69 6f 6e 73 3f 3f &42a2 3f 20 28 79 2f 6e 29 22 3b 0d &42ac 00 c8 14 f5 49 3d a7 22 59 79 4e 6e 22 2c be 29 ; 200REPEAT &42bc 3a fd 49 0d ; I=INSTR("YyNn",GET$): ; UNTILI &42c0 00 d2 18 e7 49 3c 33 20 49 4e 53 54 3d 31 20 8b ; 210IFI<3 INST=1 ELSE INST=0 &42d0 20 49 4e 53 54 3d 30 0d &42d8 00 dc 05 e1 0d ; 220ENDPROC &42dd 00 e6 0b dd f2 42 47 52 4e 44 0d ; 230DEFPROCBGRND &42e8 00 f0 a2 db 3a f1 27 27 bd 26 38 33 3b 22 59 6f ; 240CLS: &42f8 75 20 61 72 65 20 74 68 65 20 6f 77 6e 65 72 20 ; PRINT''CHR$&83;"You are the owner of a nice little fuel"'; &4308 6f 66 20 61 20 6e 69 63 65 20 6c 69 74 74 6c 65 ; ;CHR$&83;"station just off a large intergalactic": &4318 20 66 75 65 6c 22 27 3b bd 26 38 33 3b 22 73 74 ; PRINT'CHR$&83;"Hi_way. Unfortunately the";CHR$&82;"aliens";CHR$&83;"who" &4328 61 74 69 6f 6e 20 6a 75 73 74 20 6f 66 66 20 61 &4338 20 6c 61 72 67 65 20 69 6e 74 65 72 67 61 6c 61 &4348 63 74 69 63 22 3a f1 27 bd 26 38 33 3b 22 48 69 &4358 5f 77 61 79 2e 20 55 6e 66 6f 72 74 75 6e 61 74 &4368 65 6c 79 20 74 68 65 22 3b bd 26 38 32 3b 22 61 &4378 6c 69 65 6e 73 22 3b bd 26 38 33 3b 22 77 68 6f &4388 22 0d &438a 00 fa 82 f1 27 bd 26 38 33 3b 22 75 73 65 20 74 ; 250PRINT'CHR$&83;"use the Hi-way don't wish to pay for": &439a 68 65 20 48 69 2d 77 61 79 20 64 6f 6e 27 74 20 ; PRINT'CHR$&83;"the fuel that they need, and so are": &43aa 77 69 73 68 20 74 6f 20 70 61 79 20 66 6f 72 22 ; PRINT'CHR$&83;"intent on stealing it!!!!!" &43ba 3a f1 27 bd 26 38 33 3b 22 74 68 65 20 66 75 65 &43ca 6c 20 74 68 61 74 20 74 68 65 79 20 6e 65 65 64 &43da 2c 20 61 6e 64 20 73 6f 20 61 72 65 22 3a f1 27 &43ea bd 26 38 33 3b 22 69 6e 74 65 6e 74 20 6f 6e 20 &43fa 73 74 65 61 6c 69 6e 67 20 69 74 21 21 21 21 21 &440a 22 0d &440c 01 04 28 f1 27 27 27 22 20 20 20 20 20 59 6f 75 ; 260PRINT'''" Your job is to stop them." &441c 72 20 6a 6f 62 20 69 73 20 74 6f 20 73 74 6f 70 &442c 20 74 68 65 6d 2e 22 0d &4434 01 0e 0e f2 53 42 28 26 38 36 29 3a e1 0d ; 270PROCSB(&86): ; ENDPROC &4442 01 18 4b dd f2 53 42 28 43 4f 4c 25 29 3a f1 8a ; 280DEFPROCSB(COL%): &4452 32 2c 32 32 29 3b bd 43 4f 4c 25 3b 22 50 72 65 ; PRINTTAB(2,22);CHR$COL%;"Press the space bar to continue...";: &4462 73 73 20 74 68 65 20 73 70 61 63 65 20 62 61 72 ; REPEATUNTILGET=32: &4472 20 74 6f 20 63 6f 6e 74 69 6e 75 65 2e 2e 2e 22 ; ENDPROC &4482 3b 3a f5 fd a5 3d 33 32 3a e1 0d &448d 01 22 0a dd f2 4c 41 53 41 0d ; 290DEFPROCLASA &4497 01 2c 85 db 3a f1 27 27 bd 26 38 35 3b 22 20 20 ; 300CLS: &44a7 20 20 59 6f 75 20 68 61 76 65 20 61 74 20 79 6f ; PRINT''CHR$&85;" You have at your control a"': &44b7 75 72 20 63 6f 6e 74 72 6f 6c 20 61 22 27 3a f1 ; PRINTCHR$&85;"doublesupersaturatedphotonplasmalaser"': &44c7 bd 26 38 35 3b 22 64 6f 75 62 6c 65 73 75 70 65 ; PRINTCHR$&85;" -transientalblaster base!!" &44d7 72 73 61 74 75 72 61 74 65 64 70 68 6f 74 6f 6e &44e7 70 6c 61 73 6d 61 6c 61 73 65 72 22 27 3a f1 bd &44f7 26 38 35 3b 22 20 20 20 20 2d 74 72 61 6e 73 69 &4507 65 6e 74 61 6c 62 6c 61 73 74 65 72 20 62 61 73 &4517 65 21 21 22 0d &451c 01 36 68 f1 27 27 27 27 bd 26 38 35 22 54 68 69 ; 310PRINT''''CHR$&85"This will explode if it hits an";CHR$&82;"alien": &452c 73 20 77 69 6c 6c 20 65 78 70 6c 6f 64 65 20 69 ; PRINT'CHR$&85;"or an";CHR$&82;"aliens'";CHR$&85;"bullet." &453c 66 20 69 74 20 68 69 74 73 20 61 6e 22 3b bd 26 &454c 38 32 3b 22 61 6c 69 65 6e 22 3a f1 27 bd 26 38 &455c 35 3b 22 6f 72 20 61 6e 22 3b bd 26 38 32 3b 22 &456c 61 6c 69 65 6e 73 27 22 3b bd 26 38 35 3b 22 62 &457c 75 6c 6c 65 74 2e 22 0d &4584 01 40 0e f2 53 42 28 26 38 36 29 3a db 0d ; 320PROCSB(&86): ; CLS &4592 01 4a 91 f1 27 27 bd 26 38 36 22 49 74 20 68 61 ; 330PRINT''CHR$&86"It has the small problem (apart from": &45a2 73 20 74 68 65 20 73 6d 61 6c 6c 20 70 72 6f 62 ; PRINT'CHR$&86"pronounciation) that the gun(!) takes a": &45b2 6c 65 6d 20 28 61 70 61 72 74 20 66 72 6f 6d 22 ; PRINTCHR$&86;"short while to charge up, so the second" &45c2 3a f1 27 bd 26 38 36 22 70 72 6f 6e 6f 75 6e 63 &45d2 69 61 74 69 6f 6e 29 20 74 68 61 74 20 74 68 65 &45e2 20 67 75 6e 28 21 29 20 74 61 6b 65 73 20 61 22 &45f2 3a f1 bd 26 38 36 3b 22 73 68 6f 72 74 20 77 68 &4602 69 6c 65 20 74 6f 20 63 68 61 72 67 65 20 75 70 &4612 2c 20 73 6f 20 74 68 65 20 73 65 63 6f 6e 64 22 &4622 0d &4623 01 54 54 f1 bd 26 38 36 3b 22 6f 66 20 74 77 6f ; 340PRINTCHR$&86;"of two rapidly fired shots will be less": &4633 20 72 61 70 69 64 6c 79 20 66 69 72 65 64 20 73 ; PRINTCHR$&86;"powerful than the first." &4643 68 6f 74 73 20 77 69 6c 6c 20 62 65 20 6c 65 73 &4653 73 22 3a f1 bd 26 38 36 3b 22 70 6f 77 65 72 66 &4663 75 6c 20 74 68 61 6e 20 74 68 65 20 66 69 72 73 &4673 74 2e 22 0d &4677 01 5e 69 f2 53 42 28 26 38 33 29 3a db 3a f1 27 ; 350PROCSB(&83): &4687 27 bd 26 38 33 22 54 68 65 20 70 6f 77 65 72 20 ; CLS: &4697 6f 66 20 79 6f 75 72 20 6e 65 78 74 20 73 68 6f ; PRINT''CHR$&83"The power of your next shot is shown in": &46a7 74 20 69 73 20 73 68 6f 77 6e 20 69 6e 22 3a f1 ; PRINTCHR$&83;"a bar chart just under your base." &46b7 bd 26 38 33 3b 22 61 20 62 61 72 20 63 68 61 72 &46c7 74 20 6a 75 73 74 20 75 6e 64 65 72 20 79 6f 75 &46d7 72 20 62 61 73 65 2e 22 0d &46e0 01 68 3e f1 27 27 bd 26 38 33 3b 22 49 66 20 79 ; 360PRINT''CHR$&83;"If you shoot an";CHR$&82;"alien";CHR$&83;"with a weak"' &46f0 6f 75 20 73 68 6f 6f 74 20 61 6e 22 3b bd 26 38 &4700 32 3b 22 61 6c 69 65 6e 22 3b bd 26 38 33 3b 22 &4710 77 69 74 68 20 61 20 77 65 61 6b 22 27 0d &471e 01 72 90 f1 bd 26 38 33 3b 22 73 68 6f 74 20 74 ; 370PRINTCHR$&83;"shot then you will only slow it down,": &472e 68 65 6e 20 79 6f 75 20 77 69 6c 6c 20 6f 6e 6c ; PRINT'CHR$&83;"and will require more shots to finish": &473e 79 20 73 6c 6f 77 20 69 74 20 64 6f 77 6e 2c 22 ; PRINT'CHR$&83;"it off (one powerful shot will kill it" &474e 3a f1 27 bd 26 38 33 3b 22 61 6e 64 20 77 69 6c &475e 6c 20 72 65 71 75 69 72 65 20 6d 6f 72 65 20 73 &476e 68 6f 74 73 20 74 6f 20 66 69 6e 69 73 68 22 3a &477e f1 27 bd 26 38 33 3b 22 69 74 20 6f 66 66 20 28 &478e 6f 6e 65 20 70 6f 77 65 72 66 75 6c 20 73 68 6f &479e 74 20 77 69 6c 6c 20 6b 69 6c 6c 20 69 74 22 0d &47ae 01 7c 24 f1 27 bd 26 38 33 3b 22 72 69 67 68 74 ; 380PRINT'CHR$&83;"right away).": &47be 20 61 77 61 79 29 2e 22 3a f2 53 42 28 26 38 34 ; PROCSB(&84): &47ce 29 3a db 0d ; CLS &47d2 01 86 6a f1 27 27 bd 26 38 31 3b 22 54 68 65 22 ; 390PRINT''CHR$&81;"The";CHR$&82;"aliens";CHR$&81;"go around the Hi-way": &47e2 3b bd 26 38 32 3b 22 61 6c 69 65 6e 73 22 3b bd ; PRINT'CHR$&81;"in groups of eight.One group of eight" &47f2 26 38 31 3b 22 67 6f 20 61 72 6f 75 6e 64 20 74 &4802 68 65 20 48 69 2d 77 61 79 22 3a f1 27 bd 26 38 &4812 31 3b 22 69 6e 20 67 72 6f 75 70 73 20 6f 66 20 &4822 65 69 67 68 74 2e 4f 6e 65 20 67 72 6f 75 70 20 &4832 6f 66 20 65 69 67 68 74 22 0d &483c 01 90 5c f1 27 bd 26 38 31 3b 22 69 73 20 63 61 ; 400PRINT'CHR$&81;"is called a wave, and the game is in": &484c 6c 6c 65 64 20 61 20 77 61 76 65 2c 20 61 6e 64 ; PRINT'CHR$&81;"levels, which consist of varying" &485c 20 74 68 65 20 67 61 6d 65 20 69 73 20 69 6e 22 &486c 3a f1 27 bd 26 38 31 3b 22 6c 65 76 65 6c 73 2c &487c 20 77 68 69 63 68 20 63 6f 6e 73 69 73 74 20 6f &488c 66 20 76 61 72 79 69 6e 67 22 27 0d &4898 01 9a 46 f1 bd 26 38 31 3b 22 6e 75 6d 62 65 72 ; 410PRINTCHR$&81;"numbers of waves (higher levels give": &48a8 73 20 6f 66 20 77 61 76 65 73 20 28 68 69 67 68 ; PRINT'CHR$&81;"more waves.)" &48b8 65 72 20 6c 65 76 65 6c 73 20 67 69 76 65 22 3a &48c8 f1 27 bd 26 38 31 3b 22 6d 6f 72 65 20 77 61 76 &48d8 65 73 2e 29 22 0d &48de 01 a4 63 f2 53 42 28 26 38 36 29 3a db 3a f1 27 ; 420PROCSB(&86): &48ee 27 bd 26 38 36 3b 22 59 6f 75 20 68 61 76 65 20 ; CLS: &48fe 74 68 72 65 65 20 6c 69 76 65 73 2c 20 77 69 74 ; PRINT''CHR$&86;"You have three lives, with bonus lives": &490e 68 20 62 6f 6e 75 73 20 6c 69 76 65 73 22 3a f1 ; PRINT'CHR$&86;"given every 10,000 points." &491e 27 bd 26 38 36 3b 22 67 69 76 65 6e 20 65 76 65 &492e 72 79 20 31 30 2c 30 30 30 20 70 6f 69 6e 74 73 &493e 2e 22 0d &4941 01 ae 56 f1 27 bd 26 38 36 3b 22 54 68 65 72 65 ; 430PRINT'CHR$&86;"There are three numbers in the top left": &4951 20 61 72 65 20 74 68 72 65 65 20 6e 75 6d 62 65 ; PRINTCHR$&86;"of the screen, e.g. "; &4961 72 73 20 69 6e 20 74 68 65 20 74 6f 70 20 6c 65 &4971 66 74 22 3a f1 bd 26 38 36 3b 22 6f 66 20 74 68 &4981 65 20 73 63 72 65 65 6e 2c 20 65 2e 67 2e 20 20 &4991 20 20 20 22 3b 0d &4997 01 b8 2f f1 3b 89 28 35 29 3b bd 26 38 31 3b 22 ; 440PRINT;SPC(5);CHR$&81;"A": &49a7 41 22 3a f1 27 89 28 32 37 29 3b bd 26 38 32 3b ; PRINT'SPC(27);CHR$&82;"B ";CHR$&83;"C"' &49b7 22 42 20 22 3b bd 26 38 33 3b 22 43 22 27 0d &49c6 01 c2 7b f1 bd 26 38 36 3b 22 77 68 65 72 65 22 ; 450PRINTCHR$&86;"where";CHR$&81;"A";CHR$&86;"is the number of lives,": &49d6 3b bd 26 38 31 3b 22 41 22 3b bd 26 38 36 3b 22 ; PRINT'CHR$&82;"B";CHR$&86;"is the level number, and";CHR$&83;"C";CHR$&86;"is the" &49e6 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 &49f6 20 6c 69 76 65 73 2c 22 3a f1 27 bd 26 38 32 3b &4a06 22 42 22 3b bd 26 38 36 3b 22 69 73 20 74 68 65 &4a16 20 6c 65 76 65 6c 20 6e 75 6d 62 65 72 2c 20 61 &4a26 6e 64 22 3b bd 26 38 33 3b 22 43 22 3b bd 26 38 &4a36 36 3b 22 69 73 20 74 68 65 22 0d &4a41 01 cc 6d f1 27 bd 26 38 36 3b 22 6e 75 6d 62 65 ; 460PRINT'CHR$&86;"number of waves left.": &4a51 72 20 6f 66 20 77 61 76 65 73 20 6c 65 66 74 2e ; PRINT'CHR$&86;"The number in the top right of the": &4a61 22 3a f1 27 bd 26 38 36 3b 22 54 68 65 20 6e 75 ; PRINT'CHR$&86;"screen is your score." &4a71 6d 62 65 72 20 69 6e 20 74 68 65 20 74 6f 70 20 &4a81 72 69 67 68 74 20 6f 66 20 74 68 65 22 3a f1 27 &4a91 bd 26 38 36 3b 22 73 63 72 65 65 6e 20 69 73 20 &4aa1 79 6f 75 72 20 73 63 6f 72 65 2e 22 0d &4aae 01 d6 0e f2 53 42 28 26 38 37 29 3a db 0d ; 470PROCSB(&87): ; CLS &4abc 01 e0 8c f1 27 27 22 49 66 20 79 6f 75 20 61 72 ; 480PRINT''"If you are silly enough to let an";CHR$&82;"alien": &4acc 65 20 73 69 6c 6c 79 20 65 6e 6f 75 67 68 20 74 ; PRINT'"land, then it will steal some of your": &4adc 6f 20 6c 65 74 20 61 6e 22 3b bd 26 38 32 3b 22 ; PRINT'"fuel.The fuel, however, is radioactive" &4aec 61 6c 69 65 6e 22 3a f1 27 22 6c 61 6e 64 2c 20 &4afc 74 68 65 6e 20 69 74 20 77 69 6c 6c 20 73 74 65 &4b0c 61 6c 20 73 6f 6d 65 20 6f 66 20 79 6f 75 72 22 &4b1c 3a f1 27 22 66 75 65 6c 2e 54 68 65 20 66 75 65 &4b2c 6c 2c 20 68 6f 77 65 76 65 72 2c 20 69 73 20 72 &4b3c 61 64 69 6f 61 63 74 69 76 65 22 0d &4b48 01 ea 8f f1 27 22 61 6e 64 20 73 6f 20 74 68 65 ; 490PRINT'"and so the";CHR$&82;"alien";CHR$&87;"mutates to a rocket(!)": &4b58 22 3b bd 26 38 32 3b 22 61 6c 69 65 6e 22 3b bd ; PRINT'"It then flys up about } of the way ": &4b68 26 38 37 3b 22 6d 75 74 61 74 65 73 20 74 6f 20 ; PRINT'"to the Hi-way, and now the fun really" &4b78 61 20 72 6f 63 6b 65 74 28 21 29 22 3a f1 27 22 &4b88 49 74 20 74 68 65 6e 20 66 6c 79 73 20 75 70 20 &4b98 61 62 6f 75 74 20 7d 20 6f 66 20 74 68 65 20 77 &4ba8 61 79 20 22 3a f1 27 22 74 6f 20 74 68 65 20 48 &4bb8 69 2d 77 61 79 2c 20 61 6e 64 20 6e 6f 77 20 74 &4bc8 68 65 20 66 75 6e 20 72 65 61 6c 6c 79 22 0d &4bd7 01 f4 2f f1 27 22 73 74 61 72 74 73 2c 20 61 73 ; 500PRINT'"starts, as it will then home in on you!" &4be7 20 69 74 20 77 69 6c 6c 20 74 68 65 6e 20 68 6f &4bf7 6d 65 20 69 6e 20 6f 6e 20 79 6f 75 21 22 0d &4c06 01 fe 0e f2 53 42 28 26 38 31 29 3a db 0d ; 510PROCSB(&81): ; CLS &4c14 02 08 85 f1 27 27 bd 26 38 31 22 54 68 69 73 20 ; 520PRINT''CHR$&81"This is where the auto repeat cannon": &4c24 69 73 20 77 68 65 72 65 20 74 68 65 20 61 75 74 ; PRINT'CHR$&81;"comes in handy, as the mutants can be": &4c34 6f 20 72 65 70 65 61 74 20 63 61 6e 6e 6f 6e 22 ; PRINT'CHR$&81;"killed with any power shot." &4c44 3a f1 27 bd 26 38 31 3b 22 63 6f 6d 65 73 20 69 &4c54 6e 20 68 61 6e 64 79 2c 20 61 73 20 74 68 65 20 &4c64 6d 75 74 61 6e 74 73 20 63 61 6e 20 62 65 22 3a &4c74 f1 27 bd 26 38 31 3b 22 6b 69 6c 6c 65 64 20 77 &4c84 69 74 68 20 61 6e 79 20 70 6f 77 65 72 20 73 68 &4c94 6f 74 2e 22 0d &4c99 02 12 0e f2 53 42 28 26 38 37 29 3a e1 0d ; 530PROCSB(&87): ; ENDPROC &4ca7 02 1c 10 dd f2 46 55 45 4c 53 48 49 50 3a db 0d ; 540DEFPROCFUELSHIP: ; CLS &4cb7 02 26 8e f1 27 27 bd 26 38 36 3b 22 44 75 65 20 ; 550PRINT''CHR$&86;"Due to a small design fault in your": &4cc7 74 6f 20 61 20 73 6d 61 6c 6c 20 64 65 73 69 67 ; PRINT'CHR$&86;"ship, it will explode when you run out": &4cd7 6e 20 66 61 75 6c 74 20 69 6e 20 79 6f 75 72 22 ; PRINT'CHR$&86;"of fuel.Fuel is used up continually" &4ce7 3a f1 27 bd 26 38 36 3b 22 73 68 69 70 2c 20 69 &4cf7 74 20 77 69 6c 6c 20 65 78 70 6c 6f 64 65 20 77 &4d07 68 65 6e 20 79 6f 75 20 72 75 6e 20 6f 75 74 22 &4d17 3a f1 27 bd 26 38 36 3b 22 6f 66 20 66 75 65 6c &4d27 2e 46 75 65 6c 20 69 73 20 75 73 65 64 20 75 70 &4d37 20 63 6f 6e 74 69 6e 75 61 6c 6c 79 22 0d &4d45 02 30 88 f1 27 bd 26 38 36 22 62 75 74 20 65 78 ; 560PRINT'CHR$&86"but extra fuel is used when you fire.": &4d55 74 72 61 20 66 75 65 6c 20 69 73 20 75 73 65 64 ; PRINT'CHR$&86;"Your fuel supply is shown at the": &4d65 20 77 68 65 6e 20 79 6f 75 20 66 69 72 65 2e 22 ; PRINT'CHR$&86;"bottom of the screen in the form of" &4d75 3a f1 27 bd 26 38 36 3b 22 59 6f 75 72 20 66 75 &4d85 65 6c 20 73 75 70 70 6c 79 20 69 73 20 73 68 6f &4d95 77 6e 20 61 74 20 74 68 65 22 3a f1 27 bd 26 38 &4da5 36 3b 22 62 6f 74 74 6f 6d 20 6f 66 20 74 68 65 &4db5 20 73 63 72 65 65 6e 20 69 6e 20 74 68 65 20 66 &4dc5 6f 72 6d 20 6f 66 22 0d &4dcd 02 3a 20 f1 27 bd 26 38 36 3b 22 62 61 72 72 65 ; 570PRINT'CHR$&86;"barrels.": &4ddd 6c 73 2e 22 3a f2 53 42 28 26 38 32 29 3a db 0d ; PROCSB(&82): ; CLS &4ded 02 44 8e f1 27 27 bd 26 38 32 3b 22 59 6f 75 20 ; 580PRINT''CHR$&82;"You can replenish your fuel supply by": &4dfd 63 61 6e 20 72 65 70 6c 65 6e 69 73 68 20 79 6f ; PRINT'CHR$&83;"catching fuel tankers, but to catch": &4e0d 75 72 20 66 75 65 6c 20 73 75 70 70 6c 79 20 62 ; PRINT'CHR$&82;"them you must first make them fall!!" &4e1d 79 22 3a f1 27 bd 26 38 33 3b 22 63 61 74 63 68 &4e2d 69 6e 67 20 66 75 65 6c 20 74 61 6e 6b 65 72 73 &4e3d 2c 20 62 75 74 20 74 6f 20 63 61 74 63 68 22 3a &4e4d f1 27 bd 26 38 32 3b 22 74 68 65 6d 20 79 6f 75 &4e5d 20 6d 75 73 74 20 66 69 72 73 74 20 6d 61 6b 65 &4e6d 20 74 68 65 6d 20 66 61 6c 6c 21 21 22 0d &4e7b 02 4e 60 f1 27 bd 26 38 33 3b 22 54 68 69 73 20 ; 590PRINT'CHR$&83;"This is done by shooting the two space": &4e8b 69 73 20 64 6f 6e 65 20 62 79 20 73 68 6f 6f 74 ; PRINT'CHR$&82;"tugs, one on either end of the fuel" &4e9b 69 6e 67 20 74 68 65 20 74 77 6f 20 73 70 61 63 &4eab 65 22 3a f1 27 bd 26 38 32 3b 22 74 75 67 73 2c &4ebb 20 6f 6e 65 20 6f 6e 20 65 69 74 68 65 72 20 65 &4ecb 6e 64 20 6f 66 20 74 68 65 20 66 75 65 6c 22 0d &4edb 02 58 64 f1 27 bd 26 38 33 3b 22 70 6f 64 2e 20 ; 600PRINT'CHR$&83;"pod. The fuel pods are the";CHR$&86;"cyan";CHR$&83;"things": &4eeb 54 68 65 20 66 75 65 6c 20 70 6f 64 73 20 61 72 ; PRINT'CHR$&82;"with 'F' written on them." &4efb 65 20 74 68 65 22 3b bd 26 38 36 3b 22 63 79 61 &4f0b 6e 22 3b bd 26 38 33 3b 22 74 68 69 6e 67 73 22 &4f1b 3a f1 27 bd 26 38 32 3b 22 77 69 74 68 20 27 46 &4f2b 27 20 77 72 69 74 74 65 6e 20 6f 6e 20 74 68 65 &4f3b 6d 2e 22 0d &4f3f 02 62 0e f2 53 42 28 26 38 31 29 3a e1 0d ; 610PROCSB(&81): ; ENDPROC &4f4d 02 6c 0c dd f2 4b 45 59 53 3a db 0d ; 620DEFPROCKEYS: ; CLS &4f59 02 76 5d f1 27 27 89 28 38 29 3b bd 26 38 34 3b ; 630PRINT''SPC(8);CHR$&84;CHR$157;CHR$&82;CHR$141;"Keys... ";CHR$156: &4f69 bd 31 35 37 3b bd 26 38 32 3b bd 31 34 31 3b 22 ; PRINTSPC(8);CHR$&84;CHR$157;CHR$&82;CHR$141;"Keys... ";CHR$156 &4f79 4b 65 79 73 2e 2e 2e 20 20 20 22 3b bd 31 35 36 &4f89 3a f1 89 28 38 29 3b bd 26 38 34 3b bd 31 35 37 &4f99 3b bd 26 38 32 3b bd 31 34 31 3b 22 4b 65 79 73 &4fa9 2e 2e 2e 20 20 20 22 3b bd 31 35 36 0d &4fb6 02 80 6b f1 27 27 89 28 31 30 29 3b bd 26 38 36 ; 640PRINT''SPC(10);CHR$&86;"Left - 'Caps lock'": &4fc6 3b 22 4c 65 66 74 20 20 20 2d 20 20 27 43 61 70 ; PRINT'SPC(10);CHR$&86;"Right - 'Ctrl'": &4fd6 73 20 6c 6f 63 6b 27 22 3a f1 27 89 28 31 30 29 ; PRINT'SPC(10);CHR$&86;"Fire - 'RETURN'" &4fe6 3b bd 26 38 36 3b 22 52 69 67 68 74 20 20 2d 20 &4ff6 20 27 43 74 72 6c 27 22 3a f1 27 89 28 31 30 29 &5006 3b bd 26 38 36 3b 22 46 69 72 65 20 20 20 2d 20 &5016 20 27 52 45 54 55 52 4e 27 22 0d &5021 02 8a 51 f1 27 89 28 31 30 29 3b bd 26 38 36 3b ; 650PRINT'SPC(10);CHR$&86;"Escape - 'ESCAPE' (returns": &5031 22 45 73 63 61 70 65 20 2d 20 20 27 45 53 43 41 ; PRINT'SPC(10);CHR$&86;"to hi-score board.)" &5041 50 45 27 20 28 72 65 74 75 72 6e 73 22 3a f1 27 &5051 89 28 31 30 29 3b bd 26 38 36 3b 22 74 6f 20 68 &5061 69 2d 73 63 6f 72 65 20 62 6f 61 72 64 2e 29 22 &5071 0d &5072 02 94 33 f1 27 27 bd 26 38 32 3b 22 54 6f 20 67 ; 660PRINT''CHR$&82;"To get auto repeat, hold down 'SHIFT'" &5082 65 74 20 61 75 74 6f 20 72 65 70 65 61 74 2c 20 &5092 68 6f 6c 64 20 64 6f 77 6e 20 27 53 48 49 46 54 &50a2 27 22 0d &50a5 02 9e 36 f1 27 bd 26 38 32 3b 22 61 6e 64 20 27 ; 670PRINT'CHR$&82;"and 'RETURN' at the same time.": &50b5 52 45 54 55 52 4e 27 20 61 74 20 74 68 65 20 73 ; PROCSB(&88): &50c5 61 6d 65 20 74 69 6d 65 2e 22 3a f2 53 42 28 26 ; ENDPROC &50d5 38 38 29 3a e1 0d &50db ff # End of BASIC program ; unused &50dc 4e dc 00 e6 00 f0 00 fa 01 04 01 0e 01 18 01 22 &50ec 01 2c 01 36 01 40 01 4a 01 54 01 5e 01 68 01 72 &50fc 01 7c 01 86 ; load_main_binary &5100 20 0b 51 JSR &510b ; initialise_tape &5103 4c 1b 51 JMP &511b ; read_blocks ; found_string # Stored reversed &5106 64 6e 75 6f 46 ; "Found" ; initialise_tape &510b a9 03 LDA #&03 ; 0000 0011 # Reset ACIA &510d 8d 08 fe STA &fe08 ; Cassette ACIA control register &5110 a9 9d LDA #&9d ; 1001 1101 # Turn on cassette motor; cassette system has control &5112 8d 10 fe STA &fe10 ; Serial ULA control register &5115 78 SEI &5116 a9 00 LDA #&00 &5118 85 72 STA &72 ; block_count &511a 60 RTS ; read_blocks &511b a9 91 LDA #&91 ; 1001 0001 # 1200 baud, even parity, 2 stop bits, 8 bit word &511d 8d 08 fe STA &fe08 ; Cassette ACIA control register ; wait_for_start_of_frame &5120 a9 04 LDA #&04 &5122 2d 08 fe AND &fe08 ; Cassette ACIA status register # &04 set if framing error occurred &5125 d0 f9 BNE &5120 ; wait_for_start_of_frame &5127 a0 f0 LDY #&f0 &5129 84 81 STY &81 ; eor ; wait_for_start_of_data ; wait_for_interrupt &512b 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &512e 10 fb BPL &512b ; wait_for_interrupt &5130 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &5133 29 70 AND #&70 &5135 d0 f4 BNE &512b ; wait_for_interrupt &5137 ad 09 fe LDA &fe09 ; Cassette ACIA data register &513a 45 81 EOR &81 ; eor &513c f0 07 BEQ &5145 ; skip_resetting_eor &513e a0 f0 LDY #&f0 &5140 84 81 STY &81 ; eor &5142 4c 2b 51 JMP &512b ; wait_for_start_of_data ; skip_resetting_eor &5145 e6 81 INC &81 ; eor &5147 d0 e2 BNE &512b ; wait_for_start_of_data ; write_found &5149 a0 05 LDY #&05 ; write_found_loop &514b b9 05 51 LDA &5105,Y ; found_string - 1 &514e 20 ee ff JSR &ffee ; OSWRCH # Write "Found" &5151 88 DEY &5152 d0 f7 BNE &514b ; write_found &5154 a9 20 LDA #&20 ; " " &5156 20 ee ff JSR &ffee ; OSWRCH ; read_next_block ; wait_for_interrupt &5159 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &515c 10 fb BPL &5159 ; wait_for_interrupt &515e ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &5161 29 70 AND #&70 &5163 f0 03 BEQ &5168 ; no_error &5165 4c 06 52 JMP &5206 ; write_error_message ; no_error &5168 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address low &516b 85 70 STA &70 ; block_address_low ; wait_for_interrupt &516d 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &5170 10 fb BPL &516d ; wait_for_interrupt &5172 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &5175 29 70 AND #&70 &5177 f0 03 BEQ &517c ; no_error &5179 4c 06 52 JMP &5206 ; write_error_message ; no_error &517c ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address high &517f 85 71 STA &71 ; block_address_high ; read_block_loop ; wait_for_interrupt &5181 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &5184 10 fb BPL &5181 ; wait_for_interrupt &5186 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &5189 29 70 AND #&70 &518b f0 03 BEQ &5190 ; no_error &518d 4c 06 52 JMP &5206 ; write_error_message ; no_error &5190 ad 09 fe LDA &fe09 ; Cassette ACIA data register &5193 91 70 STA (&70),Y ; block_address &5195 c8 INY &5196 d0 e9 BNE &5181 ; read_block_loop &5198 e6 71 INC &71 ; block_address_high &519a a9 2a LDA #&2a ; "*" &519c 20 ee ff JSR &ffee ; OSWRCH &519f e6 72 INC &72 ; block_count ; wait_for_interrupt &51a1 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &51a4 10 fb BPL &51a1 ; wait_for_interrupt &51a6 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &51a9 29 70 AND #&70 &51ab f0 03 BEQ &51b0 ; no_error &51ad 4c 06 52 JMP &5206 ; write_error_message ; no_error &51b0 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address low &51b3 85 73 STA &73 ; call_address_low ; wait_for_interrupt &51b5 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &51b8 10 fb BPL &51b5 ; wait_for_interrupt &51ba ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &51bd 29 70 AND #&70 &51bf f0 03 BEQ &51c4 ; no_error &51c1 4c 06 52 JMP &5206 ; write_error_message ; no_error &51c4 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address high &51c7 85 74 STA &74 ; call_address_high &51c9 6c 73 00 JMP (&0073) ; call_address ; error_message # Stored reversed &51cc 29 21 79 72 72 6f 73 28 20 74 72 61 74 73 20 6d ; MODE 7 &51dc 6f 72 66 20 6f 64 65 72 0a 0d 6e 65 68 74 20 66 ; "Loading error: switch off then" &51ec 66 6f 20 68 63 74 69 77 73 20 3a 72 6f 72 72 65 ; "redo from start (sorry!)" &51fc 20 67 6e 69 64 61 6f 4c 07 16 ; write_error_message &5206 a0 39 LDY #&39 ; write_error_message_loop &5208 b9 cc 51 LDA &51cc,Y ; error_message &520b 20 ee ff JSR &ffee ; OSWRCH &520e 88 DEY &520f 10 f7 BPL &5208 ; write_error_message_loop ; infinite_loop &5211 4c 11 52 JMP &5211 ; infinite_loop ; unused &5214 a9 11 LDA #&11 ; unused &5216 00 00 00 00 00 00 00 00 00 00 # Loader reads: # # &1400 - &14ff, calls &5159 ; read_next_block # &1500 - &15ff, calls &5159 ; read_next_block # &1600 - &16ff, calls &5159 ; read_next_block # &1700 - &17ff, calls &5159 ; read_next_block # &1800 - &18ff, calls &5159 ; read_next_block # &1900 - &19ff, calls &5159 ; read_next_block # &1a00 - &1aff, calls &5159 ; read_next_block # &1b00 - &1bff, calls &5159 ; read_next_block # &1c00 - &1cff, calls &5159 ; read_next_block # &1d00 - &1dff, calls &5159 ; read_next_block # &1e00 - &1eff, calls &5159 ; read_next_block # &1f00 - &1fff, calls &5159 ; read_next_block # &2000 - &20ff, calls &5159 ; read_next_block # &2100 - &21ff, calls &5159 ; read_next_block # &2200 - &22ff, calls &5159 ; read_next_block # &2300 - &23ff, calls &5159 ; read_next_block # &2400 - &24ff, calls &5159 ; read_next_block # &2500 - &25ff, calls &5159 ; read_next_block # &2600 - &26ff, calls &5159 ; read_next_block # &2700 - &27ff, calls &5159 ; read_next_block # &2800 - &28ff, calls &5159 ; read_next_block # &2900 - &29ff, calls &5159 ; read_next_block # &2a00 - &2aff, calls &5159 ; read_next_block # &2b00 - &2bff, calls &5159 ; read_next_block # &2c00 - &2cff, calls &5159 ; read_next_block # &2d00 - &2dff, calls &5159 ; read_next_block # &2e00 - &2eff, calls &5159 ; read_next_block # &2f00 - &2fff, calls &5159 ; read_next_block # &3000 - &30ff, calls &5159 ; read_next_block # &3100 - &31ff, calls &5159 ; read_next_block # &3200 - &32ff, calls &5159 ; read_next_block # &3300 - &33ff, calls &5159 ; read_next_block # &3400 - &34ff, calls &31ff ; entry_point Game disassembly ================ &0600 - &0629 ; fragments_x &062a - &0653 ; fragments_y &0654 - &067d ; fragments_x_velocity &067e - &06a7 ; fragments_y_velocity &06a8 - &06d1 ; fragments_screen_address_low &06d2 - &06fb ; fragments_screen_address_high &06fc ; explosion_timer &0900 - &0907 ; enemies_x &090c - &0913 ; enemies_y &0918 - &091f ; enemies_screen_address_low &0924 - &092b ; enemies_screen_address_high &0930 - &0937 ; enemies_type # top bit clear if travelling, set if attacking &093c - &0943 ; enemies_attack_x # if travelling ; enemies_energy # if attacking ; enemies_fuel_required # if fuelling or fuelled ; enemies_explosion_cooldown # if exploding &0948 - &094f ; enemies_hiway_section # if travelling ; enemies_explosion_state # if attacking or exploding &0954 - &095b ; enemies_hiway_distance &0960 - &0967 ; enemies_hiway_screen_address_low &096c - &0973 ; enemies_hiway_screen_address_high &0978 - &097f ; enemies_x_direction &0984 - &099b ; enemies_unused &0990 - &0997 ; enemies_hiway_pixel_in_pair # if travelling ; enemies_movement_cooldown # if attacking ; enemies_rocket_homing # if fuelling or fuelled ; enemies_explosion_pixel_value # if exploding &099c - &09a3 ; enemies_timer &09a8 - &09ab ; fuelpods_x &09ac - &09af ; fuelpods_y &09b0 - &09b3 ; fuelpods_state &09b4 - &09b7 ; fuelpods_screen_address_low &09b8 - &09bb ; fuelpods_screen_address_high &09bc - &09bf ; fuelpods_sprite_address_low &09c0 - &09c3 ; fuelpods_sprite_address_high &09c4 - &09c7 ; fuelpods_sprite_width &09c8 ; active_fuelpod &09c9 ; active_fuelpod_direction &09ca - &09ca ; fuelpod_states_x_offset &09da ; fuelpod_update_cooldown &09e0 ; autofire_cooldown &0a00 - &0a05 ; bombs_x &0a10 - &0a15 ; bombs_y &0a20 - &0a25 ; bombs_screen_address_low &0a30 - &0a35 ; bombs_screen_address_high &0a40 - &0a43 ; lasers_x &0a50 - &0a53 ; lasers_y &0a60 - &0a63 ; lasers_energy &0a70 - &0a73 ; lasers_screen_address_low &0a80 - &0a83 ; lasers_screen_address_high &0a90 - &0a9b ; fuelpod_explosions_x &0a9c - &0aa7 ; fuelpod_explosions_y &0aa8 - &0ab3 ; fuelpod_explosions_state &0ab4 - &0abf ; fuelpod_explosions_cooldown # &1400 - &34ff is loaded from stream ; entry_point_after_relocation &1400 4c b5 24 JMP &24b5 ; start_game ; write_string &1403 bd 80 2f LDA &2f80,X ; string_addresses_low_table &1406 85 70 STA &70 ; text_address_low &1408 bd 90 2f LDA &2f90,X ; string_addresses_high_table &140b 85 71 STA &71 ; text_address_high &140d a0 00 LDY #&00 ; write_string_loop &140f b1 70 LDA (&70),Y ; text_address &1411 c9 fe CMP #&fe # &fe indicates end of string &1413 f0 0c BEQ &1421 ; leave &1415 20 ee ff JSR &ffee ; OSWRCH &1418 e6 70 INC &70 ; text_address_low &141a d0 f3 BNE &140f ; write_string_loop &141c e6 71 INC &71 ; text_address_high &141e 4c 0f 14 JMP &140f ; write_string_loop ; leave &1421 60 RTS ; rnd &1422 8a TXA &1423 48 PHA ; tmp_x &1424 a2 08 LDX #&08 ; shuffle_rnd_state_loop &1426 a5 00 LDA &00 ; rnd_state &1428 29 48 AND #&48 &142a 69 38 ADC #&38 &142c 0a ASL A &142d 0a ASL A &142e 26 02 ROL &02 ; rnd_state + 2 &1430 26 01 ROL &01 ; rnd_state + 1 &1432 26 00 ROL &00 ; rnd_state &1434 ca DEX &1435 d0 ef BNE &1426 ; shuffle_rnd_state_loop &1437 a5 00 LDA &00 ; rnd_state &1439 05 01 ORA &01 ; rnd_state + 1 &143b 05 02 ORA &02 ; rnd_state + 2 &143d d0 02 BNE &1441 ; not_zero &143f e6 01 INC &01 ; rnd_state + 1 ; not_zero &1441 68 PLA ; tmp_x &1442 aa TAX &1443 a5 00 LDA &00 ; rnd_state &1445 60 RTS ; set_video_register &1446 8e 00 fe STX &fe00 ; video register number &1449 8d 01 fe STA &fe01 ; video register value &144c 60 RTS ; set_palette &144d 48 PHA ; tmp_a &144e 49 07 EOR #&07 &1450 8d 21 fe STA &fe21 ; video ULA palette register &1453 68 PLA ; tmp_a &1454 60 RTS ; wait_for_vsync &1455 a9 02 LDA #&02 &1457 2d 4d fe AND &fe4d ; System VIA interrupt flag register # &02 set if v-sync interrupt &145a f0 f9 BEQ &1455 ; wait_for_vsync &145c 8d 4d fe STA &fe4d ; System VIA interrupt flag register # Clear interrupt &145f 60 RTS ; calculate_screen_address &1460 98 TYA &1461 49 ff EOR #&ff &1463 a8 TAY &1464 29 f8 AND #&f8 &1466 4a LSR A &1467 4a LSR A &1468 85 71 STA &71 ; screen_address_high &146a 4a LSR A &146b 4a LSR A &146c 08 PHP &146d 18 CLC &146e 65 71 ADC &71 ; screen_address_high &1470 85 71 STA &71 ; screen_address_high &1472 28 PLP &1473 a9 00 LDA #&00 &1475 6a ROR A &1476 85 70 STA &70 ; screen_address_low &1478 8a TXA &1479 0a ASL A &147a 0a ASL A &147b 26 72 ROL &72 ; tmp &147d 0a ASL A &147e 26 72 ROL &72 ; tmp &1480 18 CLC &1481 65 70 ADC &70 ; screen_address_low &1483 85 70 STA &70 ; screen_address_low &1485 a5 72 LDA &72 ; tmp &1487 29 03 AND #&03 &1489 65 71 ADC &71 ; screen_address_high &148b 69 30 ADC #&30 &148d 85 71 STA &71 ; screen_address_high &148f 98 TYA &1490 29 07 AND #&07 &1492 05 70 ORA &70 ; screen_address_low &1494 85 70 STA &70 ; screen_address_low &1496 60 RTS ; use_sprite &1497 aa TAX &1498 bd a0 2f LDA &2fa0,X ; sprite_addresses_low_table &149b 85 72 STA &72 ; sprite_address_low &149d bd b8 2f LDA &2fb8,X ; sprite_addresses_high_table &14a0 85 73 STA &73 ; sprite_address_high &14a2 bd d0 2f LDA &2fd0,X ; sprite_widths_table &14a5 85 74 STA &74 ; sprite_width &14a7 bd e8 2f LDA &2fe8,X ; sprite_heights_table &14aa 85 75 STA &75 ; sprite_height &14ac 60 RTS ; plot_sprite &14ad a5 71 LDA &71 ; screen_address_high &14af d0 01 BNE &14b2 ; is_on_screen &14b1 60 RTS ; is_on_screen &14b2 a0 00 LDY #&00 &14b4 84 78 STY &78 ; collision ; plot_sprite_column_loop &14b6 a5 71 LDA &71 ; screen_address_high &14b8 48 PHA ; screen_address_high &14b9 a5 70 LDA &70 ; screen_address_low &14bb 48 PHA ; screen_address_low &14bc 29 07 AND #&07 &14be 85 77 STA &77 ; row_in_group &14c0 45 70 EOR &70 ; screen_address_low &14c2 85 70 STA &70 ; screen_address_low ; plot_sprite_row_loop &14c4 b1 72 LDA (&72),Y ; sprite_address &14c6 08 PHP ; sprite byte not blank &14c7 c8 INY &14c8 84 76 STY &76 ; row &14ca a4 77 LDY &77 ; row_in_group &14cc 51 70 EOR (&70),Y ; screen_address &14ce 91 70 STA (&70),Y ; screen_address &14d0 c8 INY &14d1 28 PLP ; sprite byte not blank &14d2 f0 04 BEQ &14d8 ; skip_setting_collision &14d4 05 78 ORA &78 ; collision &14d6 85 78 STA &78 ; collision ; skip_setting_collision &14d8 c0 08 CPY #&08 &14da f0 27 BEQ &1503 ; next_group ; next_row &14dc 84 77 STY &77 ; row_in_group &14de a4 76 LDY &76 ; row &14e0 c4 75 CPY &75 ; sprite_height &14e2 d0 e0 BNE &14c4 ; plot_sprite_row_loop &14e4 a0 00 LDY #&00 &14e6 a5 72 LDA &72 ; sprite_address_low &14e8 18 CLC &14e9 65 75 ADC &75 ; sprite_height &14eb 85 72 STA &72 ; sprite_address_low &14ed a5 73 LDA &73 ; sprite_address_high &14ef 69 00 ADC #&00 &14f1 85 73 STA &73 ; sprite_address_high &14f3 18 CLC &14f4 68 PLA ; screen_address_low &14f5 69 08 ADC #&08 # Move right two pixels &14f7 85 70 STA &70 ; screen_address_low &14f9 68 PLA ; screen_address_high &14fa 69 00 ADC #&00 &14fc 85 71 STA &71 ; screen_address_high &14fe c6 74 DEC &74 ; sprite_width &1500 d0 b4 BNE &14b6 ; plot_sprite_column_loop &1502 60 RTS ; next_group &1503 a0 00 LDY #&00 &1505 18 CLC &1506 a5 70 LDA &70 ; screen_address_low &1508 69 80 ADC #&80 # Move down a group &150a 85 70 STA &70 ; screen_address_low &150c a5 71 LDA &71 ; screen_address_high &150e 69 02 ADC #&02 &1510 85 71 STA &71 ; screen_address_high &1512 d0 c8 BNE &14dc ; next_row # Always branches ; check_for_keypress &1514 aa TAX &1515 a9 81 LDA #&81 ; Scan for a particular key &1517 a0 ff LDY #&ff &1519 20 f4 ff JSR &fff4 ; OSBYTE &151c 8a TXA &151d 60 RTS ; initialise_screen &151e a2 00 LDX #&00 ; initialise_game_screen_string &1520 20 03 14 JSR &1403 ; write_string # Change to MODE 2, draw hiway &1523 8a TXA ; 0 &1524 a2 0b LDX #&0b ; R11: Cursor end register &1526 20 46 14 JSR &1446 ; set_video_register # Disable cursor &1529 a2 08 LDX #&08 ; R8: Interlace and delay register &152b 20 46 14 JSR &1446 ; set_video_register # Normal (non-interlaced) sync mode &152e a9 04 LDA #&04 ; Define action of cursor editing keys &1530 a2 01 LDX #&01 ; Cursor keys return ASCII values 135-139 &1532 20 f4 ff JSR &fff4 ; OSBYTE &1535 a9 02 LDA #&02 # Enable v-sync interrupts &1537 8d 4e fe STA &fe4e ; System VIA interrupt enable register &153a 60 RTS ; initialise_enemies &153b ae 00 2f LDX &2f00 ; number_of_enemies &153e f0 3d BEQ &157d ; leave &1540 ca DEX ; initialise_enemies_loop &1541 8a TXA &1542 9d 48 09 STA &0948,X ; enemies_hiway_section # Distribute enemies around hiway &1545 bd f8 27 LDA &27f8,X ; enemies_initial_type &1548 9d 30 09 STA &0930,X ; enemies_type &154b a9 00 LDA #&00 &154d 9d 24 09 STA &0924,X ; enemies_screen_address_high # Set to zero to indicate not plotted &1550 9d 3c 09 STA &093c,X ; enemies_attack_x &1553 9d 54 09 STA &0954,X ; enemies_hiway_distance &1556 8a TXA &1557 48 PHA ; enemy_slot &1558 20 88 15 JSR &1588 ; calculate_screen_address_of_enemy_on_hiway &155b 68 PLA ; enemy_slot &155c aa TAX &155d a9 be LDA #&be &155f 9d 0c 09 STA &090c,X ; enemies_y &1562 ea NOP &1563 ea NOP &1564 a5 70 LDA &70 ; screen_address_low &1566 9d 60 09 STA &0960,X ; enemies_hiway_screen_address_low &1569 a5 71 LDA &71 ; screen_address_high &156b 9d 6c 09 STA &096c,X ; enemies_hiway_screen_address_high &156e a5 73 LDA &73 ; pixel_in_pair &1570 9d 90 09 STA &0990,X ; enemies_hiway_pixel_in_pair &1573 8a TXA &1574 48 PHA ; enemy_slot &1575 20 be 15 JSR &15be ; plot_enemy_on_hiway &1578 68 PLA ; enemy_slot &1579 aa TAX &157a ca DEX &157b 10 c4 BPL &1541 ; initialise_enemies_loop ; leave &157d 60 RTS ; initialise_bombs_and_lasers &157e a9 00 LDA #&00 &1580 aa TAX ; initialise_bombs_and_lasers_loop &1581 9d 00 0a STA &0a00,X # Wipe &0a00 - &0aff &1584 ca DEX &1585 d0 fa BNE &1581 ; initialise_bombs_and_lasers_loop &1587 60 RTS ; calculate_screen_address_of_enemy_on_hiway &1588 a8 TAY &1589 b9 c4 2e LDA &2ec4,Y ; hiway_sections_start_x &158c 0a ASL A &158d 85 70 STA &70 ; x &158f b9 d0 2e LDA &2ed0,Y ; hiway_sections_start_y &1592 85 71 STA &71 ; y &1594 bd 54 09 LDA &0954,X ; enemies_hiway_distance &1597 aa TAX &1598 f0 18 BEQ &15b2 ; skip_moving_along_section ; move_along_section_loop &159a 8a TXA &159b 29 01 AND #&01 &159d d0 08 BNE &15a7 ; skip_moving_horizontally &159f b9 dc 2e LDA &2edc,Y ; hiway_sections_direction_x &15a2 18 CLC &15a3 65 70 ADC &70 ; x &15a5 85 70 STA &70 ; x ; skip_moving_horizontally &15a7 b9 e8 2e LDA &2ee8,Y ; hiway_sections_direction_y &15aa 18 CLC &15ab 65 71 ADC &71 ; y &15ad 85 71 STA &71 ; y &15af ca DEX &15b0 d0 e8 BNE &159a ; move_along_section_loop ; skip_moving_along_section &15b2 66 70 ROR &70 ; x &15b4 66 73 ROR &73 ; pixel_in_pair &15b6 a6 70 LDX &70 ; x &15b8 a4 71 LDY &71 ; y &15ba c8 INY &15bb 4c 60 14 JMP &1460 ; calculate_screen_address ; plot_enemy_on_hiway &15be bd 30 09 LDA &0930,X ; enemies_type &15c1 aa TAX &15c2 bd e5 2c LDA &2ce5,X ; enemy_types_pixel_value - 1 &15c5 a4 73 LDY &73 ; pixel_in_pair &15c7 30 01 BMI &15ca ; skip_shift &15c9 0a ASL A # Use left pixel ; skip_shift &15ca a0 00 LDY #&00 &15cc 51 70 EOR (&70),Y ; screen_address # Plot top of enemy on hiway &15ce 91 70 STA (&70),Y ; screen_address &15d0 e6 70 INC &70 ; screen_address_low # Move down a row &15d2 d0 02 BNE &15d6 ; skip_page &15d4 e6 71 INC &71 ; screen_address_high ; skip_page &15d6 a5 70 LDA &70 ; screen_address_low &15d8 29 07 AND #&07 &15da d0 0d BNE &15e9 ; not_new_group &15dc a5 70 LDA &70 ; screen_address_low &15de 18 CLC &15df 69 78 ADC #&78 # Move down a group &15e1 85 70 STA &70 ; screen_address_low &15e3 a5 71 LDA &71 ; screen_address_high &15e5 69 02 ADC #&02 &15e7 85 71 STA &71 ; screen_address_high ; not_new_group &15e9 bd e5 2c LDA &2ce5,X ; enemy_types_pixel_value - 1 &15ec a4 73 LDY &73 ; pixel_in_pair &15ee 30 01 BMI &15f1 ; skip_shift &15f0 0a ASL A # Use left pixel ; skip_shift &15f1 a0 00 LDY #&00 &15f3 51 70 EOR (&70),Y ; screen_address # Plot bottom of enemy on hiway &15f5 91 70 STA (&70),Y ; screen_address ; leave &15f7 60 RTS ; update_enemies &15f8 ae 00 2f LDX &2f00 ; number_of_enemies &15fb f0 fa BEQ &15f7 ; leave &15fd ca DEX ; update_enemies_loop &15fe 86 80 STX &80 ; enemy_slot &1600 bd 30 09 LDA &0930,X ; enemies_type # Top bit set if enemy is attacking &1603 10 03 BPL &1608 ; update_travelling_enemy &1605 4c 1b 1a JMP &1a1b ; update_attacking_enemy ; update_travelling_enemy &1608 48 PHA ; enemy_type &1609 bd 18 09 LDA &0918,X ; enemies_screen_address_low &160c 85 70 STA &70 ; screen_address_low &160e bd 24 09 LDA &0924,X ; enemies_screen_address_high &1611 85 71 STA &71 ; screen_address_high &1613 a9 00 LDA #&00 &1615 9d 24 09 STA &0924,X ; enemies_screen_address_high # Set to zero to indicate enemy not plotted &1618 68 PLA ; enemy_type &1619 38 SEC &161a e9 01 SBC #&01 &161c 29 03 AND #&03 &161e 20 97 14 JSR &1497 ; use_sprite &1621 20 ad 14 JSR &14ad ; plot_sprite # Unplot enemy &1624 a6 80 LDX &80 ; enemy_slot &1626 bd 54 09 LDA &0954,X ; enemies_hiway_distance &1629 18 CLC &162a 69 01 ADC #&01 # Move enemy along section of hiway &162c bc 48 09 LDY &0948,X ; enemies_hiway_section &162f d9 f4 2e CMP &2ef4,Y ; hiway_sections_length &1632 90 11 BCC &1645 ; not_end_of_section # Is this the end of the section? &1634 bd 48 09 LDA &0948,X ; enemies_hiway_section &1637 18 CLC &1638 69 01 ADC #&01 # If so, move enemy onto next section of hiway &163a c9 0c CMP #&0c &163c d0 02 BNE &1640 ; skip_wraparound &163e a9 00 LDA #&00 # and continue from end to start of hiway ; skip_wraparound &1640 9d 48 09 STA &0948,X ; enemies_hiway_section &1643 a9 00 LDA #&00 ; not_end_of_section &1645 9d 54 09 STA &0954,X ; enemies_hiway_distance &1648 bd 60 09 LDA &0960,X ; enemies_hiway_screen_address_low &164b 85 70 STA &70 ; screen_address_low &164d bd 6c 09 LDA &096c,X ; enemies_hiway_screen_address_high &1650 85 71 STA &71 ; screen_address_high &1652 bd 90 09 LDA &0990,X ; enemies_hiway_pixel_in_pair &1655 85 73 STA &73 ; pixel_in_pair &1657 20 be 15 JSR &15be ; plot_enemy_on_hiway # Unplot enemy on hiway &165a a6 80 LDX &80 ; enemy_slot &165c bd 48 09 LDA &0948,X ; enemies_hiway_section &165f 20 88 15 JSR &1588 ; calculate_screen_address_of_enemy_on_hiway &1662 a6 80 LDX &80 ; enemy_slot &1664 9d 60 09 STA &0960,X ; enemies_hiway_screen_address_low &1667 a5 71 LDA &71 ; screen_address_high &1669 9d 6c 09 STA &096c,X ; enemies_hiway_screen_address_high &166c a5 73 LDA &73 ; pixel_in_pair &166e 9d 90 09 STA &0990,X ; enemies_hiway_pixel_in_pair &1671 20 be 15 JSR &15be ; plot_enemy_on_hiway # Plot enemy on hiway &1674 4c 7f 16 JMP &167f ; consider_updating_enemy_on_screen ; not_on_screen &1677 a9 ff LDA #&ff &1679 9d 00 09 STA &0900,X ; enemies_x # Set to &ff to indicate enemy is not on screen &167c 4c 26 17 JMP &1726 ; consider_next_enemy ; consider_updating_enemy_on_screen &167f a6 80 LDX &80 ; enemy_slot &1681 bd 48 09 LDA &0948,X ; enemies_hiway_section &1684 c9 02 CMP #&02 # Is the enemy on the visible section of the hiway? &1686 d0 ef BNE &1677 ; not_on_screen &1688 bd 54 09 LDA &0954,X ; enemies_hiway_distance &168b c9 0a CMP #&0a &168d 90 e8 BCC &1677 ; not_on_screen &168f c9 57 CMP #&57 &1691 b0 e4 BCS &1677 ; not_on_screen &1693 85 70 STA &70 ; distance &1695 a9 56 LDA #&56 &1697 38 SEC &1698 e5 70 SBC &70 ; distance &169a 48 PHA ; enemy_x &169b 9d 00 09 STA &0900,X ; enemies_x &169e aa TAX &169f a0 be LDY #&be &16a1 20 60 14 JSR &1460 ; calculate_screen_address &16a4 a6 80 LDX &80 ; enemy_slot &16a6 9d 18 09 STA &0918,X ; enemies_screen_address_low &16a9 a5 71 LDA &71 ; screen_address_high &16ab 9d 24 09 STA &0924,X ; enemies_screen_address_high &16ae bd 30 09 LDA &0930,X ; enemies_type &16b1 38 SEC &16b2 e9 01 SBC #&01 &16b4 29 03 AND #&03 &16b6 20 97 14 JSR &1497 ; use_sprite &16b9 20 ad 14 JSR &14ad ; plot_sprite # Plot travelling enemy &16bc a6 80 LDX &80 ; enemy_slot &16be 68 PLA ; enemy_x &16bf c9 4c CMP #&4c &16c1 d0 25 BNE &16e8 ; not_entering_screen # Has the enemy just entered the screen? &16c3 48 PHA ; enemy_x &16c4 20 22 14 JSR &1422 ; rnd &16c7 29 7f AND #&7f &16c9 85 70 STA &70 ; r &16cb 38 SEC &16cc ad 00 2f LDA &2f00 ; number_of_enemies &16cf ed 01 2f SBC &2f01 ; enemies_remaining &16d2 0a ASL A # Enemies are more likely to attack when fewer in number &16d3 0a ASL A &16d4 6d 11 2f ADC &2f11 ; probability_of_enemy_attacking &16d7 c5 70 CMP &70 ; r &16d9 a9 ff LDA #&ff # &ff to suppress enemy attacking this visit &16db 90 07 BCC &16e4 ; set_enemies_attack_x &16dd a5 01 LDA &01 ; rnd_state + 1 &16df 29 3e AND #&3e # Choose a random x position for enemy to attack from &16e1 18 CLC &16e2 69 08 ADC #&08 ; set_enemies_attack_x &16e4 9d 3c 09 STA &093c,X ; enemies_attack_x &16e7 68 PLA ; enemy_x ; not_entering_screen &16e8 dd 3c 09 CMP &093c,X ; enemies_attack_x # Is the enemy at the attack position? &16eb d0 39 BNE &1726 ; consider_next_enemy ; set_enemy_attacking &16ed a0 01 LDY #&01 # Set enemy moving right &16ef 20 22 14 JSR &1422 ; rnd &16f2 10 02 BPL &16f6 ; set_enemy_direction &16f4 a0 ff LDY #&ff # or left, at random ; set_enemy_direction &16f6 98 TYA &16f7 9d 78 09 STA &0978,X ; enemies_x_direction &16fa a9 ff LDA #&ff &16fc 9d 84 09 STA &0984,X ; enemies_unused # Unused variable &16ff ad 0e 2f LDA &2f0e ; initial_enemy_energy &1702 9d 3c 09 STA &093c,X ; enemies_energy &1705 bd 60 09 LDA &0960,X ; enemies_hiway_screen_address_low &1708 85 70 STA &70 ; screen_address_low &170a bd 6c 09 LDA &096c,X ; enemies_hiway_screen_address_high &170d 85 71 STA &71 ; screen_address_high &170f bd 90 09 LDA &0990,X ; enemies_hiway_pixel_in_pair &1712 85 73 STA &73 ; pixel_in_pair &1714 20 be 15 JSR &15be ; plot_enemy_on_hiway # Unplot attacking enemy from hiway &1717 a6 80 LDX &80 ; enemy_slot &1719 a9 30 LDA #&30 &171b 9d 90 09 STA &0990,X ; enemies_movement_cooldown &171e bd 30 09 LDA &0930,X ; enemies_type &1721 09 80 ORA #&80 ; ENEMY_ATTACKING # Set top bit to indicate enemy is attacking &1723 9d 30 09 STA &0930,X ; enemies_type ; consider_next_enemy &1726 a6 80 LDX &80 ; enemy_slot &1728 ca DEX &1729 30 03 BMI &172e ; leave &172b 4c fe 15 JMP &15fe ; update_enemies_loop ; leave &172e 60 RTS ; draw_screen &172f a2 01 LDX #&01 ; ground_string &1731 20 03 14 JSR &1403 ; write_string # Draw magenta line between pillars &1734 a2 08 LDX #&08 &1736 86 80 STX &80 ; x ; plot_fuel_gauge_loop &1738 a6 80 LDX &80 ; x &173a a0 0a LDY #&0a &173c 20 60 14 JSR &1460 ; calculate_screen_address &173f a9 04 LDA #&04 ; SPRITE_FUEL_GAUGE &1741 20 97 14 JSR &1497 ; use_sprite &1744 20 ad 14 JSR &14ad ; plot_sprite # Plot section of fuel gauge &1747 a5 80 LDA &80 ; x &1749 18 CLC &174a 69 04 ADC #&04 &174c 85 80 STA &80 ; x &174e c9 48 CMP #&48 &1750 90 e6 BCC &1738 ; plot_fuel_gauge_loop &1752 a9 81 LDA #&81 # Set colour 8 to red &1754 20 4d 14 JSR &144d ; set_palette &1757 a9 94 LDA #&94 # Set colour 9 to blue &1759 20 4d 14 JSR &144d ; set_palette &175c a9 a4 LDA #&a4 # Set colour 10 to blue &175e 20 4d 14 JSR &144d ; set_palette &1761 a9 80 LDA #&80 &1763 8d 0d 2f STA &2f0d ; fuel_line_colour # Colour 8 &1766 a2 02 LDX #&02 &1768 a0 18 LDY #&18 &176a 20 60 14 JSR &1460 ; calculate_screen_address &176d a9 06 LDA #&06 ; SPRITE_FUEL_LINE_VERTICAL_LEFT &176f 20 97 14 JSR &1497 ; use_sprite &1772 20 ad 14 JSR &14ad ; plot_sprite # Plot left vertical section of fuel line &1775 a2 4d LDX #&4d &1777 a0 18 LDY #&18 &1779 20 60 14 JSR &1460 ; calculate_screen_address &177c a9 08 LDA #&08 ; SPRITE_FUEL_LINE_VERTICAL_RIGHT &177e 20 97 14 JSR &1497 ; use_sprite &1781 20 ad 14 JSR &14ad ; plot_sprite # Plot right vertical section of fuel line &1784 a2 03 LDX #&03 &1786 a0 04 LDY #&04 &1788 20 60 14 JSR &1460 ; calculate_screen_address &178b a9 07 LDA #&07 ; SPRITE_FUEL_LINE_HORIZONTAL &178d 20 97 14 JSR &1497 ; use_sprite &1790 20 ad 14 JSR &14ad ; plot_sprite # Plot left horizontal section of fuel line &1793 a2 48 LDX #&48 &1795 a0 04 LDY #&04 &1797 20 60 14 JSR &1460 ; calculate_screen_address &179a a9 07 LDA #&07 ; SPRITE_FUEL_LINE_HORIZONTAL &179c 20 97 14 JSR &1497 ; use_sprite &179f 20 ad 14 JSR &14ad ; plot_sprite # Plot right horizontal section of fuel line &17a2 a2 01 LDX #&01 &17a4 a0 22 LDY #&22 &17a6 20 60 14 JSR &1460 ; calculate_screen_address &17a9 a9 05 LDA #&05 ; SPRITE_PILLAR # Plot left pillar &17ab 20 97 14 JSR &1497 ; use_sprite &17ae 20 ad 14 JSR &14ad ; plot_sprite &17b1 a2 4c LDX #&4c &17b3 a0 22 LDY #&22 &17b5 20 60 14 JSR &1460 ; calculate_screen_address &17b8 a9 05 LDA #&05 ; SPRITE_PILLAR # Plot right pillar &17ba 20 97 14 JSR &1497 ; use_sprite &17bd 20 ad 14 JSR &14ad ; plot_sprite &17c0 a2 07 LDX #&07 &17c2 a0 18 LDY #&18 &17c4 20 60 14 JSR &1460 ; calculate_screen_address &17c7 a9 09 LDA #&09 ; SPRITE_LASER_GAUGE_LEFT &17c9 20 97 14 JSR &1497 ; use_sprite &17cc 20 ad 14 JSR &14ad ; plot_sprite # Plot left edge of laser gauge &17cf a2 48 LDX #&48 &17d1 a0 18 LDY #&18 &17d3 20 60 14 JSR &1460 ; calculate_screen_address &17d6 a9 0b LDA #&0b ; SPRITE_LASER_GUIDE_RIGHT &17d8 20 97 14 JSR &1497 ; use_sprite &17db 20 ad 14 JSR &14ad ; plot_sprite # Plot right edge of laser gauge &17de a2 08 LDX #&08 &17e0 86 80 STX &80 ; x ; plot_laser_gauge_loop &17e2 a6 80 LDX &80 ; x &17e4 a0 18 LDY #&18 &17e6 20 60 14 JSR &1460 ; calculate_screen_address &17e9 a9 0a LDA #&0a ; SPRITE_LASER_GAUGE_MIDDLE &17eb 20 97 14 JSR &1497 ; use_sprite &17ee 20 ad 14 JSR &14ad ; plot_sprite # Plot part of middle of laser gauge &17f1 e6 80 INC &80 ; x &17f3 a5 80 LDA &80 ; x &17f5 c9 48 CMP #&48 &17f7 d0 e9 BNE &17e2 ; plot_laser_gauge_loop &17f9 a2 47 LDX #&47 &17fb a0 17 LDY #&17 &17fd 20 60 14 JSR &1460 ; calculate_screen_address &1800 a5 70 LDA &70 ; screen_address_low &1802 8d 0b 2f STA &2f0b ; laser_gauge_screen_address_low &1805 a5 71 LDA &71 ; screen_address_high &1807 8d 0c 2f STA &2f0c ; laser_gauge_screen_address_high &180a a9 40 LDA #&40 &180c 8d 0a 2f STA &2f0a ; player_laser_energy # Player starts with full laser &180f a9 09 LDA #&09 &1811 8d 09 2f STA &2f09 ; player_fuel_y &1814 a9 45 LDA #&45 &1816 8d 08 2f STA &2f08 ; player_fuel_x &1819 a9 60 LDA #&60 # Player starts with full fuel &181b 8d 07 2f STA &2f07 ; player_fuel &181e a2 20 LDX #&20 &1820 8e 02 2f STX &2f02 ; player_x &1823 20 5c 18 JSR &185c ; plot_player &1826 a2 00 LDX #&00 &1828 a0 00 LDY #&00 &182a 4c e2 23 JMP &23e2 ; add_to_score # Plot score ; update_player &182d 20 5c 18 JSR &185c ; plot_player # Unplot player &1830 a5 78 LDA &78 ; collision &1832 48 PHA ; collision &1833 a9 bf LDA #&bf ; CAPS LOCK &1835 20 14 15 JSR &1514 ; check_for_keypress &1838 f0 0a BEQ &1844 ; not_moving_left &183a ad 02 2f LDA &2f02 ; player_x &183d c9 05 CMP #&05 # Is the player at the left of the screen? &183f 90 03 BCC &1844 ; not_moving_left &1841 ce 02 2f DEC &2f02 ; player_x # If not, move left ; not_moving_left &1844 a9 fe LDA #&fe ; CTRL &1846 20 14 15 JSR &1514 ; check_for_keypress &1849 f0 0a BEQ &1855 ; not_moving_right &184b ad 02 2f LDA &2f02 ; player_x &184e c9 43 CMP #&43 # Is the player at the right of the screen? &1850 b0 03 BCS &1855 ; not_moving_right &1852 ee 02 2f INC &2f02 ; player_x # If not, move right &1855 20 5c 18 JSR &185c ; plot_player # Plot player ; not_moving_right &1858 68 PLA ; collision &1859 d0 11 BNE &186c ; consider_player_collision &185b 60 RTS ; plot_player &185c ae 02 2f LDX &2f02 ; player_x &185f a0 27 LDY #&27 &1861 20 60 14 JSR &1460 ; calculate_screen_address &1864 a9 0c LDA #&0c ; SPRITE_PLAYER &1866 20 97 14 JSR &1497 ; use_sprite &1869 4c ad 14 JMP &14ad ; plot_sprite ; consider_player_collision &186c ad c8 09 LDA &09c8 ; active_fuelpod # Positive if fuelpod active &186f 10 01 BPL &1872 ; is_active &1871 60 RTS # Leave with non-zero to indicate player killed ; is_active &1872 aa TAX &1873 bd b0 09 LDA &09b0,X ; fuelpods_state &1876 c9 04 CMP #&04 ; FUELPOD_NO_TUGS &1878 f0 03 BEQ &187d ; consider_player_collision_with_fuelpod &187a a9 01 LDA #&01 # Leave with non-zero to indicate player killed &187c 60 RTS ; consider_player_collision_with_fuelpod &187d a8 TAY &187e 88 DEY &187f bd a8 09 LDA &09a8,X ; fuelpods_x &1882 38 SEC &1883 f9 ca 09 SBC &09ca,Y ; fuelpod_states_x_offset # Always zero &1886 38 SEC &1887 ed 02 2f SBC &2f02 ; player_x &188a 18 CLC &188b 69 04 ADC #&04 &188d 10 03 BPL &1892 ; check_x_max &188f a9 01 LDA #&01 # Leave with non-zero to indicate player killed &1891 60 RTS ; check_x_max &1892 c9 0f CMP #&0f &1894 90 01 BCC &1897 ; check_y &1896 60 RTS # Leave with non-zero to indicate player killed ; check_y &1897 bd ac 09 LDA &09ac,X ; fuelpods_y &189a c9 2d CMP #&2d &189c 90 01 BCC &189f ; collect_fuelpod &189e 60 RTS # Leave with non-zero to indicate player killed ; collect_fuelpod &189f a9 00 LDA #&00 ; FUELPOD_NONE &18a1 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod &18a4 a9 ff LDA #&ff &18a6 8d c8 09 STA &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active &18a9 bd b4 09 LDA &09b4,X ; fuelpods_screen_address_low &18ac 85 70 STA &70 ; screen_address_low &18ae bd b8 09 LDA &09b8,X ; fuelpods_screen_address_high &18b1 85 71 STA &71 ; screen_address_high &18b3 bd bc 09 LDA &09bc,X ; fuelpods_sprite_address_low &18b6 85 72 STA &72 ; sprite_address_low &18b8 bd c0 09 LDA &09c0,X ; fuelpods_sprite_address_high &18bb 85 73 STA &73 ; sprite_address_high &18bd bd c4 09 LDA &09c4,X ; fuelpods_sprite_width &18c0 85 74 STA &74 ; sprite_width &18c2 a9 06 LDA #&06 &18c4 85 75 STA &75 ; sprite_height &18c6 20 ad 14 JSR &14ad ; plot_sprite # Unplot fuelpod &18c9 a9 30 LDA #&30 &18cb 20 dd 18 JSR &18dd ; add_to_fuel # Add 48 fuel for collecting fuelpod &18ce a2 50 LDX #&50 &18d0 a0 07 LDY #&07 &18d2 20 e2 23 JSR &23e2 ; add_to_score # Score 750 for collecting fuelpod &18d5 a9 01 LDA #&01 &18d7 20 91 24 JSR &2491 ; play_sound # Play sound for collecting fuelpod &18da a9 00 LDA #&00 # Leave with zero to indicate player not killed &18dc 60 RTS ; add_to_fuel &18dd 48 PHA ; delta &18de 18 CLC &18df 6d 07 2f ADC &2f07 ; player_fuel &18e2 10 06 BPL &18ea ; check_limit &18e4 68 PLA ; delta &18e5 48 PHA ; delta &18e6 10 06 BPL &18ee ; use_maximum &18e8 a9 00 LDA #&00 ; check_limit &18ea c9 61 CMP #&61 &18ec 90 02 BCC &18f0 ; set_fuel_target ; use_maximum &18ee a9 60 LDA #&60 ; set_fuel_target &18f0 85 82 STA &82 ; target &18f2 ad 07 2f LDA &2f07 ; player_fuel &18f5 c5 82 CMP &82 ; target &18f7 d0 02 BNE &18fb ; update_fuel &18f9 68 PLA ; delta &18fa 60 RTS ; update_fuel &18fb ad 0d 2f LDA &2f0d ; fuel_line_colour &18fe 09 04 ORA #&04 ; B &1900 20 4d 14 JSR &144d ; set_palette # Set current colour to blue &1903 29 f0 AND #&f0 &1905 18 CLC &1906 69 10 ADC #&10 # Move to next colour &1908 c9 b0 CMP #&b0 &190a 90 02 BCC &190e ; skip_wraparound &190c a9 80 LDA #&80 # Use colours 8, 9 and 10 ; skip_wraparound &190e 8d 0d 2f STA &2f0d ; fuel_line_colour &1911 09 01 ORA #&01 ; R &1913 20 4d 14 JSR &144d ; set_palette # Set next colour to red &1916 a0 01 LDY #&01 # Unnecessary code &1918 68 PLA ; delta &1919 10 02 BPL &191d ; is_positive &191b a0 ff LDY #&ff # Unnecessary code ; is_positive &191d 30 3e BMI &195d ; lose_fuel_loop ; gain_fuel_loop &191f ac 09 2f LDY &2f09 ; player_fuel_y &1922 c8 INY &1923 c0 0a CPY #&0a &1925 d0 0b BNE &1932 ; not_next_section &1927 a0 04 LDY #&04 &1929 ad 08 2f LDA &2f08 ; player_fuel_x &192c 18 CLC &192d 69 04 ADC #&04 &192f 8d 08 2f STA &2f08 ; player_fuel_x &1932 8c 09 2f STY &2f09 ; player_fuel_y ; not_next_section &1935 ae 08 2f LDX &2f08 ; player_fuel_x &1938 20 60 14 JSR &1460 ; calculate_screen_address &193b a9 03 LDA #&03 ; RR &193d a0 00 LDY #&00 &193f 91 70 STA (&70),Y ; screen_address # Plot left part of full row in fuel gauge &1941 48 PHA ; pixel_value &1942 a5 70 LDA &70 ; screen_address_low &1944 18 CLC &1945 69 08 ADC #&08 # Move right two pixels &1947 85 70 STA &70 ; screen_address_low &1949 a5 71 LDA &71 ; screen_address_high &194b 69 00 ADC #&00 &194d 85 71 STA &71 ; screen_address_high &194f 68 PLA ; pixel_value &1950 91 70 STA (&70),Y ; screen_address # Plot right part of full row in fuel gauge &1952 ee 07 2f INC &2f07 ; player_fuel &1955 ad 07 2f LDA &2f07 ; player_fuel &1958 c5 82 CMP &82 ; target &195a d0 c3 BNE &191f ; gain_fuel_loop &195c 60 RTS ; lose_fuel_loop &195d ae 08 2f LDX &2f08 ; player_fuel_x &1960 ac 09 2f LDY &2f09 ; player_fuel_y &1963 20 60 14 JSR &1460 ; calculate_screen_address &1966 a9 0c LDA #&0c ; GG &1968 a0 00 LDY #&00 &196a 91 70 STA (&70),Y ; screen_address # Plot left part of empty row in fuel gauge &196c 48 PHA ; pixel_value &196d a5 70 LDA &70 ; screen_address_low &196f 18 CLC &1970 69 08 ADC #&08 # Move right two pixels &1972 85 70 STA &70 ; screen_address_low &1974 a5 71 LDA &71 ; screen_address_high &1976 69 00 ADC #&00 &1978 85 71 STA &71 ; screen_address_high &197a 68 PLA ; pixel_value &197b 91 70 STA (&70),Y ; screen_address # Plot right part of empty row in fuel gauge &197d ae 09 2f LDX &2f09 ; player_fuel_y &1980 ca DEX &1981 e0 03 CPX #&03 &1983 d0 0b BNE &1990 ; not_previous_section &1985 a2 09 LDX #&09 &1987 ad 08 2f LDA &2f08 ; player_fuel_x &198a 38 SEC &198b e9 04 SBC #&04 &198d 8d 08 2f STA &2f08 ; player_fuel_x ; not_previous_section &1990 8e 09 2f STX &2f09 ; player_fuel_y &1993 ce 07 2f DEC &2f07 ; player_fuel &1996 ad 07 2f LDA &2f07 ; player_fuel &1999 c5 82 CMP &82 ; target &199b d0 c0 BNE &195d ; lose_fuel_loop &199d 60 RTS ; wipe_laser_gauge &199e a9 c0 LDA #&c0 ; &78c0 = top left of laser gauge &19a0 85 70 STA &70 ; screen_address_low &19a2 8d 0b 2f STA &2f0b ; laser_gauge_screen_address_low &19a5 a9 78 LDA #&78 &19a7 85 71 STA &71 ; screen_address_high &19a9 8d 0c 2f STA &2f0c ; laser_gauge_screen_address_high &19ac a0 00 LDY #&00 &19ae 8c 0a 2f STY &2f0a ; player_laser_energy ; wipe_laser_gauge_loop # Wipe &78c0 - &79ff &19b1 a9 30 LDA #&30 ; BB &19b3 91 70 STA (&70),Y ; screen_address # Plot empty laser gauge &19b5 c8 INY # Move down a row or right a column &19b6 d0 f9 BNE &19b1 ; wipe_laser_gauge_loop &19b8 e6 71 INC &71 ; screen_address_high &19ba a5 71 LDA &71 ; screen_address_high &19bc c9 7a CMP #&7a &19be d0 f1 BNE &19b1 ; wipe_laser_gauge_loop &19c0 a5 70 LDA &70 ; screen_address_low &19c2 c9 b8 CMP #&b8 ; &7ab8 = top right of laser gauge &19c4 d0 01 BNE &19c7 ; next_part &19c6 60 RTS ; next_part # Then wipe &79b8 - &7ab7 &19c7 a9 b8 LDA #&b8 &19c9 85 70 STA &70 ; screen_address_low &19cb a9 79 LDA #&79 &19cd 85 71 STA &71 ; screen_address_high &19cf 4c b1 19 JMP &19b1 ; wipe_laser_gauge_loop ; add_to_player_laser_energy &19d2 18 CLC &19d3 6d 0a 2f ADC &2f0a ; player_laser_energy &19d6 c9 41 CMP #&41 &19d8 90 02 BCC &19dc ; skip_ceiling &19da a9 40 LDA #&40 ; skip_ceiling &19dc 85 82 STA &82 ; target &19de ad 0a 2f LDA &2f0a ; player_laser_energy &19e1 c5 82 CMP &82 ; target &19e3 90 01 BCC &19e6 ; gain_player_laser_energy &19e5 60 RTS ; gain_player_laser_energy &19e6 ad 0b 2f LDA &2f0b ; laser_gauge_screen_address_low &19e9 85 70 STA &70 ; screen_address_low &19eb ad 0c 2f LDA &2f0c ; laser_gauge_screen_address_high &19ee 85 71 STA &71 ; screen_address_high ; gain_player_laser_energy_loop &19f0 a9 03 LDA #&03 ; RR &19f2 a0 07 LDY #&07 ; gain_player_laser_energy_byte_loop &19f4 91 70 STA (&70),Y ; screen_address &19f6 88 DEY &19f7 10 fb BPL &19f4 ; gain_player_laser_energy_byte_loop &19f9 a5 70 LDA &70 ; screen_address_low &19fb 18 CLC &19fc 69 08 ADC #&08 # Move right two pixels &19fe 85 70 STA &70 ; screen_address_low &1a00 a5 71 LDA &71 ; screen_address_high &1a02 69 00 ADC #&00 &1a04 85 71 STA &71 ; screen_address_high &1a06 ee 0a 2f INC &2f0a ; player_laser_energy &1a09 ad 0a 2f LDA &2f0a ; player_laser_energy &1a0c c5 82 CMP &82 ; target &1a0e d0 e0 BNE &19f0 ; gain_player_laser_energy_loop &1a10 a5 70 LDA &70 ; screen_address_low &1a12 8d 0b 2f STA &2f0b ; laser_gauge_screen_address_low &1a15 a5 71 LDA &71 ; screen_address_high &1a17 8d 0c 2f STA &2f0c ; laser_gauge_screen_address_high &1a1a 60 RTS ; update_attacking_enemy &1a1b c9 80 CMP #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &1a1d d0 03 BNE &1a22 ; not_exploding &1a1f 4c e3 1f JMP &1fe3 ; update_exploding_enemy ; not_exploding &1a22 c9 85 CMP #&85 ; ENEMY_ATTACKING | 5 &1a24 90 03 BCC &1a29 ; consider_updating_regular_enemy &1a26 4c 3b 1b JMP &1b3b ; update_rocket_enemy ; consider_updating_regular_enemy &1a29 bd 90 09 LDA &0990,X ; enemies_movement_cooldown &1a2c 38 SEC &1a2d fd 3c 09 SBC &093c,X ; enemies_energy &1a30 9d 90 09 STA &0990,X ; enemies_movement_cooldown &1a33 30 03 BMI &1a38 ; update_regular_enemy &1a35 4c 26 17 JMP &1726 ; consider_next_enemy ; update_regular_enemy &1a38 a9 30 LDA #&30 &1a3a 9d 90 09 STA &0990,X ; enemies_movement_cooldown &1a3d bd 30 09 LDA &0930,X ; enemies_type &1a40 38 SEC &1a41 e9 01 SBC #&01 &1a43 29 03 AND #&03 &1a45 f0 2d BEQ &1a74 ; update_cyan_enemy &1a47 c9 01 CMP #&01 ; ENEMY_RED - 1 &1a49 f0 49 BEQ &1a94 ; update_red_enemy &1a4b c9 02 CMP #&02 ; ENEMY_GREEN - 1 &1a4d f0 48 BEQ &1a97 ; update_green_enemy ; update_white_enemy # White enemies move erratically down &1a4f a0 ff LDY #&ff &1a51 20 22 14 JSR &1422 ; rnd &1a54 c9 55 CMP #&55 # 85 / 256 chance to move diagonally left &1a56 90 06 BCC &1a5e ; set_x_delta &1a58 c8 INY ; 0 &1a59 c9 aa CMP #&aa # 85 / 256 chance to move straight down &1a5b 90 01 BCC &1a5e ; set_x_delta &1a5d c8 INY ; 1 # 86 / 256 chance to move diagonally right ; set_x_delta &1a5e 84 82 STY &82 ; x_delta &1a60 bd 00 09 LDA &0900,X ; enemies_x &1a63 18 CLC &1a64 65 82 ADC &82 ; x_delta &1a66 c9 04 CMP #&04 # but not beyond left &1a68 90 07 BCC &1a71 ; skip_setting_enemies_x &1a6a c9 43 CMP #&43 # or right edges of screen &1a6c b0 03 BCS &1a71 ; skip_setting_enemies_x &1a6e 9d 00 09 STA &0900,X ; enemies_x ; skip_setting_enemies_x &1a71 4c 1a 1c JMP &1c1a ; move_enemy_towards_ground ; update_cyan_enemy # Cyan enemies move diagonally down &1a74 bd 00 09 LDA &0900,X ; enemies_x &1a77 18 CLC &1a78 7d 78 09 ADC &0978,X ; enemies_x_direction &1a7b c9 05 CMP #&05 # only changing direction at left &1a7d b0 07 BCS &1a86 ; not_at_left_edge &1a7f a9 01 LDA #&01 &1a81 9d 78 09 STA &0978,X ; enemies_x_direction &1a84 a9 05 LDA #&05 ; not_at_left_edge &1a86 c9 43 CMP #&43 # and right edges of screen &1a88 90 07 BCC &1a91 ; not_at_right_edge &1a8a a9 ff LDA #&ff &1a8c 9d 78 09 STA &0978,X ; enemies_x_direction &1a8f a9 42 LDA #&42 ; not_at_right_edge &1a91 9d 00 09 STA &0900,X ; enemies_x ; update_red_enemy # Red enemies move straight down &1a94 4c 1a 1c JMP &1c1a ; move_enemy_towards_ground ; update_green_enemy # Green enemies move towards player at steeper diagonal &1a97 fe 9c 09 INC &099c,X ; enemies_timer &1a9a bd 9c 09 LDA &099c,X ; enemies_timer &1a9d 29 01 AND #&01 # i.e. move horizontally 1 in 2 updates &1a9f f0 20 BEQ &1ac1 ; skip_horizontal_movement &1aa1 bd 00 09 LDA &0900,X ; enemies_x &1aa4 18 CLC &1aa5 7d 78 09 ADC &0978,X ; enemies_x_direction &1aa8 c9 05 CMP #&05 # changing direction at left &1aaa b0 07 BCS &1ab3 ; not_at_left_edge &1aac a9 01 LDA #&01 &1aae 9d 78 09 STA &0978,X ; enemies_x_direction &1ab1 a9 05 LDA #&05 ; not_at_left_edge &1ab3 c9 43 CMP #&43 # and right edges of screen &1ab5 90 07 BCC &1abe ; not_at_right_edge &1ab7 a9 ff LDA #&ff &1ab9 9d 78 09 STA &0978,X ; enemies_x_direction &1abc a9 42 LDA #&42 &1abe 9d 00 09 STA &0900,X ; enemies_x ; not_at_right_edge ; skip_horizontal_movement &1ac1 bd 0c 09 LDA &090c,X ; enemies_y &1ac4 38 SEC ; divide_by_sixteen_loop &1ac5 e9 10 SBC #&10 &1ac7 b0 fc BCS &1ac5 ; divide_by_sixteen_loop &1ac9 c9 ff CMP #&ff &1acb f0 03 BEQ &1ad0 ; set_enemy_moving_towards_player # 1 in 16 updates, green enemies change direction &1acd 4c 1a 1c JMP &1c1a ; move_enemy_towards_ground ; set_enemy_moving_towards_player &1ad0 bd 00 09 LDA &0900,X ; enemies_x &1ad3 a0 ff LDY #&ff &1ad5 cd 02 2f CMP &2f02 ; player_x &1ad8 b0 09 BCS &1ae3 ; set_enemies_x_direction &1ada a0 01 LDY #&01 &1adc cd 02 2f CMP &2f02 ; player_x &1adf 90 02 BCC &1ae3 ; set_enemies_x_direction &1ae1 a0 00 LDY #&00 ; set_enemies_x_direction &1ae3 98 TYA &1ae4 9d 78 09 STA &0978,X ; enemies_x_direction &1ae7 4c 1a 1c JMP &1c1a ; move_enemy_towards_ground ; start_enemy_fuelling &1aea a9 01 LDA #&01 &1aec 9d 90 09 STA &0990,X ; enemies_rocket_homing # Set to non-zero to indicate not homing on player &1aef bd 30 09 LDA &0930,X ; enemies_type &1af2 38 SEC &1af3 e9 01 SBC #&01 &1af5 29 03 AND #&03 &1af7 20 97 14 JSR &1497 ; use_sprite &1afa a6 80 LDX &80 ; enemy_slot &1afc a9 25 LDA #&25 &1afe 9d 0c 09 STA &090c,X ; enemies_y &1b01 bd 18 09 LDA &0918,X ; enemies_screen_address_low &1b04 85 70 STA &70 ; screen_address_low &1b06 bd 24 09 LDA &0924,X ; enemies_screen_address_high &1b09 85 71 STA &71 ; screen_address_high &1b0b 20 ad 14 JSR &14ad ; plot_sprite # Unplot enemy &1b0e a6 80 LDX &80 ; enemy_slot &1b10 a9 8f LDA #&8f ; ENEMY_ATTACKING | ENEMY_ROCKET &1b12 9d 30 09 STA &0930,X ; enemies_type # Set enemy fuelling &1b15 bd 0c 09 LDA &090c,X ; enemies_y &1b18 a8 TAY &1b19 bd 00 09 LDA &0900,X ; enemies_x &1b1c aa TAX &1b1d 20 60 14 JSR &1460 ; calculate_screen_address &1b20 a6 80 LDX &80 ; enemy_slot &1b22 a9 04 LDA #&04 &1b24 9d 3c 09 STA &093c,X ; enemies_fuel_required # Enemies need four units of fuel &1b27 a9 0d LDA #&0d ; SPRITE_ENEMY_ROCKET_UNFUELLED &1b29 20 97 14 JSR &1497 ; use_sprite # Will plot new fuelling enemy &1b2c a6 80 LDX &80 ; enemy_slot &1b2e a5 70 LDA &70 ; screen_address_low &1b30 9d 18 09 STA &0918,X ; enemies_screen_address_low &1b33 a5 71 LDA &71 ; screen_address_high &1b35 9d 24 09 STA &0924,X ; enemies_screen_address_high &1b38 4c 09 1c JMP &1c09 ; replot_enemy_and_consider_dropping_bomb ; update_rocket_enemy &1b3b de 3c 09 DEC &093c,X ; enemies_fuel_required # Becomes negative if enemy is fuelled &1b3e 30 31 BMI &1b71 ; update_fuelled_enemy &1b40 fe 9c 09 INC &099c,X ; enemies_timer &1b43 bd 9c 09 LDA &099c,X ; enemies_timer &1b46 29 1f AND #&1f # Add fuel 1 in 32 updates &1b48 f0 06 BEQ &1b50 ; add_fuel_to_enemy &1b4a fe 3c 09 INC &093c,X ; enemies_fuel_required # Undo decrement at &1b3b &1b4d 4c 26 17 JMP &1726 ; consider_next_enemy ; add_fuel_to_enemy &1b50 a9 21 LDA #&21 &1b52 38 SEC &1b53 fd 3c 09 SBC &093c,X ; enemies_fuel_required &1b56 a8 TAY &1b57 bd 00 09 LDA &0900,X ; enemies_x &1b5a 18 CLC &1b5b 69 01 ADC #&01 &1b5d aa TAX &1b5e 20 60 14 JSR &1460 ; calculate_screen_address &1b61 a9 02 LDA #&02 &1b63 a0 00 LDY #&00 &1b65 51 70 EOR (&70),Y ; screen_address # Plot fuel inside enemy &1b67 91 70 STA (&70),Y ; screen_address &1b69 a9 ff LDA #&ff &1b6b 20 dd 18 JSR &18dd ; add_to_fuel # Lose 1 fuel to fuelling enemy &1b6e 4c 26 17 JMP &1726 ; consider_next_enemy ; update_fuelled_enemy &1b71 a9 00 LDA #&00 &1b73 9d 3c 09 STA &093c,X ; enemies_fuel_required # Set to zero to indicate enemy is fuelled &1b76 bd 18 09 LDA &0918,X ; enemies_screen_address_low &1b79 85 70 STA &70 ; screen_address_low &1b7b bd 24 09 LDA &0924,X ; enemies_screen_address_high &1b7e 85 71 STA &71 ; screen_address_high &1b80 a9 0e LDA #&0e ; SPRITE_ENEMY_ROCKET_FUELLED &1b82 20 97 14 JSR &1497 ; use_sprite &1b85 20 ad 14 JSR &14ad ; plot_sprite # Unplot fuelled enemy &1b88 a6 80 LDX &80 ; enemy_slot &1b8a bd 90 09 LDA &0990,X ; enemies_rocket_homing # Zero if fuelled enemy is homing on player &1b8d f0 2e BEQ &1bbd ; move_fuelled_enemy_towards_player &1b8f bc 0c 09 LDY &090c,X ; enemies_y &1b92 c8 INY # Move fuelled enemy up one pixel &1b93 98 TYA &1b94 9d 0c 09 STA &090c,X ; enemies_y &1b97 c9 a0 CMP #&a0 # Has the fuelled enemy reached the hiway? &1b99 d0 05 BNE &1ba0 ; not_at_hiway &1b9b a9 00 LDA #&00 &1b9d 9d 90 09 STA &0990,X ; enemies_rocket_homing # Set to zero to set fuelled enemy homing on player ; not_at_hiway &1ba0 bd 0c 09 LDA &090c,X ; enemies_y &1ba3 a8 TAY &1ba4 bd 00 09 LDA &0900,X ; enemies_x &1ba7 aa TAX &1ba8 20 60 14 JSR &1460 ; calculate_screen_address &1bab a6 80 LDX &80 ; enemy_slot &1bad 9d 18 09 STA &0918,X ; enemies_screen_address_low &1bb0 a5 71 LDA &71 ; screen_address_high &1bb2 9d 24 09 STA &0924,X ; enemies_screen_address_high &1bb5 a9 0e LDA #&0e ; SPRITE_ENEMY_ROCKET_FUELLED &1bb7 20 97 14 JSR &1497 ; use_sprite # Will plot fuelled enemy &1bba 4c 09 1c JMP &1c09 ; replot_enemy_and_consider_dropping_bomb ; move_fuelled_enemy_towards_player &1bbd bd 00 09 LDA &0900,X ; enemies_x &1bc0 38 SEC &1bc1 e9 02 SBC #&02 &1bc3 a0 ff LDY #&ff &1bc5 cd 02 2f CMP &2f02 ; player_x &1bc8 b0 02 BCS &1bcc ; not_left_of_player &1bca a0 01 LDY #&01 ; not_left_of_player &1bcc 84 70 STY &70 ; x_delta &1bce bd 00 09 LDA &0900,X ; enemies_x &1bd1 18 CLC &1bd2 65 70 ADC &70 ; x_delta # Move fuelled enemy towards player &1bd4 9d 00 09 STA &0900,X ; enemies_x &1bd7 bc 0c 09 LDY &090c,X ; enemies_y &1bda 88 DEY # Move fuelled enemy down one pixel &1bdb 98 TYA &1bdc c9 24 CMP #&24 # Has the fuelled enemy reached the ground? &1bde b0 10 BCS &1bf0 ; not_at_ground &1be0 a9 80 LDA #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &1be2 9d 30 09 STA &0930,X ; enemies_type # If so, remove enemy &1be5 a9 00 LDA #&00 &1be7 9d 48 09 STA &0948,X ; enemies_explosion_state # Set to zero to suppress explosion &1bea ce 01 2f DEC &2f01 ; enemies_remaining &1bed 4c 26 17 JMP &1726 ; consider_next_enemy ; not_at_ground &1bf0 9d 0c 09 STA &090c,X ; enemies_y &1bf3 bd 00 09 LDA &0900,X ; enemies_x &1bf6 aa TAX &1bf7 20 60 14 JSR &1460 ; calculate_screen_address &1bfa a6 80 LDX &80 ; enemy_slot &1bfc 9d 18 09 STA &0918,X ; enemies_screen_address_low &1bff a5 71 LDA &71 ; screen_address_high &1c01 9d 24 09 STA &0924,X ; enemies_screen_address_high &1c04 a9 0e LDA #&0e ; SPRITE_ENEMY_ROCKET_FUELLED &1c06 20 97 14 JSR &1497 ; use_sprite # Will plot fuelled enemy ; replot_enemy_and_consider_dropping_bomb &1c09 20 ad 14 JSR &14ad ; plot_sprite # Plot enemy &1c0c 20 22 14 JSR &1422 ; rnd &1c0f cd 10 2f CMP &2f10 ; probability_of_fuelled_enemy_dropping_bomb &1c12 b0 03 BCS &1c17 ; skip_adding_bomb &1c14 20 71 1c JSR &1c71 ; add_bomb ; skip_adding_bomb &1c17 4c 26 17 JMP &1726 ; consider_next_enemy ; move_enemy_towards_ground &1c1a bd 0c 09 LDA &090c,X ; enemies_y &1c1d 38 SEC &1c1e e9 01 SBC #&01 # Move enemy down one pixel &1c20 9d 0c 09 STA &090c,X ; enemies_y &1c23 c9 24 CMP #&24 # Has the enemy reached the ground? &1c25 d0 03 BNE &1c2a ; not_at_ground &1c27 4c ea 1a JMP &1aea ; start_enemy_fuelling ; not_at_ground &1c2a 20 22 14 JSR &1422 ; rnd &1c2d cd 0f 2f CMP &2f0f ; probability_of_regular_enemy_dropping_bomb &1c30 b0 03 BCS &1c35 ; skip_adding_bomb &1c32 20 71 1c JSR &1c71 ; add_bomb ; skip_adding_bomb &1c35 bd 30 09 LDA &0930,X ; enemies_type &1c38 38 SEC &1c39 e9 01 SBC #&01 &1c3b 29 03 AND #&03 &1c3d 48 PHA ; enemy_sprite &1c3e 20 97 14 JSR &1497 ; use_sprite &1c41 a6 80 LDX &80 ; enemy_slot &1c43 bd 18 09 LDA &0918,X ; enemies_screen_address_low &1c46 85 70 STA &70 ; screen_address_low &1c48 bd 24 09 LDA &0924,X ; enemies_screen_address_high &1c4b 85 71 STA &71 ; screen_address_high &1c4d 20 ad 14 JSR &14ad ; plot_sprite # Unplot enemy &1c50 a6 80 LDX &80 ; enemy_slot &1c52 bd 0c 09 LDA &090c,X ; enemies_y &1c55 a8 TAY &1c56 bd 00 09 LDA &0900,X ; enemies_x &1c59 aa TAX &1c5a 20 60 14 JSR &1460 ; calculate_screen_address &1c5d a6 80 LDX &80 ; enemy_slot &1c5f 9d 18 09 STA &0918,X ; enemies_screen_address_low &1c62 a5 71 LDA &71 ; screen_address_high &1c64 9d 24 09 STA &0924,X ; enemies_screen_address_high &1c67 68 PLA ; enemy_sprite &1c68 20 97 14 JSR &1497 ; use_sprite &1c6b 20 ad 14 JSR &14ad ; plot_sprite # Plot enemy ; to_consider_next_enemy &1c6e 4c 26 17 JMP &1726 ; consider_next_enemy ; add_bomb &1c71 a2 05 LDX #&05 ; find_free_slot_for_bomb &1c73 bd 30 0a LDA &0a30,X ; bombs_screen_address_high # Zero if no bomb in slot &1c76 f0 06 BEQ &1c7e ; found_free_slot &1c78 ca DEX &1c79 10 f8 BPL &1c73 ; find_free_slot_for_bomb &1c7b a6 80 LDX &80 ; enemy_slot &1c7d 60 RTS ; found_free_slot &1c7e 86 81 STX &81 ; bomb_slot &1c80 a6 80 LDX &80 ; enemy_slot &1c82 bd 00 09 LDA &0900,X ; enemies_x &1c85 18 CLC &1c86 69 01 ADC #&01 &1c88 85 73 STA &73 ; bomb_x &1c8a bd 0c 09 LDA &090c,X ; enemies_y &1c8d 38 SEC &1c8e e9 09 SBC #&09 &1c90 c9 28 CMP #&28 &1c92 b0 03 BCS &1c97 ; not_close_to_ground # Don't add bomb if enemy is too close to ground &1c94 a6 80 LDX &80 ; enemy_slot &1c96 60 RTS ; not_close_to_ground &1c97 85 74 STA &74 ; bomb_y &1c99 a8 TAY &1c9a a6 73 LDX &73 ; bomb_x &1c9c 20 60 14 JSR &1460 ; calculate_screen_address &1c9f a6 81 LDX &81 ; bomb_slot &1ca1 a5 73 LDA &73 ; bomb_x &1ca3 9d 00 0a STA &0a00,X ; bombs_x &1ca6 a5 74 LDA &74 ; bomb_y &1ca8 9d 10 0a STA &0a10,X ; bombs_y &1cab a5 70 LDA &70 ; screen_address_low &1cad 9d 20 0a STA &0a20,X ; bombs_screen_address_low &1cb0 a5 71 LDA &71 ; screen_address_high &1cb2 9d 30 0a STA &0a30,X ; bombs_screen_address_high &1cb5 20 fd 1c JSR &1cfd ; plot_bomb # Plot new bomb &1cb8 a6 80 LDX &80 ; enemy_slot &1cba 60 RTS ; update_bombs &1cbb a2 05 LDX #&05 ; update_bombs_loop &1cbd bd 30 0a LDA &0a30,X ; bombs_screen_address_high # Non-zero if bomb in slot &1cc0 d0 04 BNE &1cc6 ; update_bomb ; consider_next_bomb &1cc2 ca DEX &1cc3 10 f8 BPL &1cbd ; update_bombs_loop &1cc5 60 RTS ; update_bomb &1cc6 85 71 STA &71 ; screen_address_high &1cc8 bd 20 0a LDA &0a20,X ; bombs_screen_address_low &1ccb 85 70 STA &70 ; screen_address_low &1ccd 20 fd 1c JSR &1cfd ; plot_bomb # Unplot bomb &1cd0 bc 10 0a LDY &0a10,X ; bombs_y &1cd3 88 DEY # Move bomb down two pixels &1cd4 88 DEY &1cd5 98 TYA &1cd6 9d 10 0a STA &0a10,X ; bombs_y &1cd9 c9 22 CMP #&22 # Has the bomb hit the ground? &1cdb b0 07 BCS &1ce4 ; skip_removing_bomb &1cdd a9 00 LDA #&00 &1cdf 9d 30 0a STA &0a30,X ; bombs_screen_address_high # Set to zero to remove bomb &1ce2 f0 de BEQ &1cc2 ; consider_next_bomb # Always branches ; skip_removing_bomb &1ce4 86 80 STX &80 ; bomb_slot &1ce6 bd 00 0a LDA &0a00,X ; bombs_x &1ce9 aa TAX &1cea 20 60 14 JSR &1460 ; calculate_screen_address &1ced a6 80 LDX &80 ; bomb_slot &1cef 9d 20 0a STA &0a20,X ; bombs_screen_address_low &1cf2 a5 71 LDA &71 ; screen_address_high &1cf4 9d 30 0a STA &0a30,X ; bombs_screen_address_high &1cf7 20 fd 1c JSR &1cfd ; plot_bomb # Plot bomb &1cfa 4c c2 1c JMP &1cc2 ; consider_next_bomb ; plot_bomb &1cfd a0 00 LDY #&00 &1cff 86 81 STX &81 ; tmp_x &1d01 a2 04 LDX #&04 ; plot_bomb_loop &1d03 a9 15 LDA #&15 ; KW &1d05 51 70 EOR (&70),Y ; screen_address # Plot pixel of bomb &1d07 91 70 STA (&70),Y ; screen_address &1d09 a5 70 LDA &70 ; screen_address_low &1d0b 18 CLC &1d0c 69 01 ADC #&01 # Move down a row &1d0e 48 PHA ; screen_address_low &1d0f 85 70 STA &70 ; screen_address_low &1d11 a5 71 LDA &71 ; screen_address_high &1d13 69 00 ADC #&00 &1d15 85 71 STA &71 ; screen_address_high &1d17 68 PLA ; screen_address_low &1d18 29 07 AND #&07 &1d1a d0 0d BNE &1d29 ; not_new_group &1d1c a5 70 LDA &70 ; screen_address_low &1d1e 18 CLC &1d1f 69 78 ADC #&78 # Move down a group &1d21 85 70 STA &70 ; screen_address_low &1d23 a5 71 LDA &71 ; screen_address_high &1d25 69 02 ADC #&02 &1d27 85 71 STA &71 ; screen_address_high ; not_new_group &1d29 ca DEX &1d2a d0 d7 BNE &1d03 ; plot_bomb_loop &1d2c a6 81 LDX &81 ; tmp_x &1d2e 60 RTS ; consider_firing &1d2f ad 07 2f LDA &2f07 ; player_fuel &1d32 f0 6c BEQ &1da0 ; update_lasers # Can't fire if out of fuel &1d34 a9 01 LDA #&01 &1d36 20 d2 19 JSR &19d2 ; add_to_player_laser_energy &1d39 a9 ff LDA #&ff ; SHIFT &1d3b 20 14 15 JSR &1514 ; check_for_keypress &1d3e f0 0d BEQ &1d4d ; shift_not_pressed # If SHIFT is pressed, &1d40 ce e0 09 DEC &09e0 ; autofire_cooldown &1d43 ad e0 09 LDA &09e0 ; autofire_cooldown &1d46 29 07 AND #&07 # fire every eight updates &1d48 d0 56 BNE &1da0 ; update_lasers &1d4a 8d 12 2f STA &2f12 ; player_can_fire # Set to zero to allow RETURN to set to non-zero ; shift_not_pressed &1d4d a9 b6 LDA #&b6 ; RETURN &1d4f 20 14 15 JSR &1514 ; check_for_keypress &1d52 f0 03 BEQ &1d57 ; return_not_pressed &1d54 4d 12 2f EOR &2f12 ; player_can_fire # Set to non-zero if firing for the first time ; return_not_pressed &1d57 8e 12 2f STX &2f12 ; player_can_fire # Non-zero if player can fire &1d5a f0 0a BEQ &1d66 ; to_update_lasers &1d5c a2 03 LDX #&03 ; find_free_slot_for_laser_loop &1d5e bd 80 0a LDA &0a80,X ; lasers_screen_address_high # Zero if no laser in slot &1d61 f0 06 BEQ &1d69 ; add_laser &1d63 ca DEX &1d64 10 f8 BPL &1d5e ; find_free_slot_for_laser_loop ; to_update_lasers &1d66 4c a0 1d JMP &1da0 ; update_lasers ; add_laser &1d69 ad 02 2f LDA &2f02 ; player_x &1d6c 18 CLC &1d6d 69 03 ADC #&03 &1d6f 9d 40 0a STA &0a40,X ; lasers_x &1d72 48 PHA ; laser_x &1d73 a9 28 LDA #&28 &1d75 a8 TAY &1d76 9d 50 0a STA &0a50,X ; lasers_y &1d79 ad 0a 2f LDA &2f0a ; player_laser_energy &1d7c 9d 60 0a STA &0a60,X ; lasers_energy &1d7f 86 80 STX &80 ; laser_slot &1d81 68 PLA ; laser_x &1d82 aa TAX &1d83 20 60 14 JSR &1460 ; calculate_screen_address &1d86 a6 80 LDX &80 ; laser_slot &1d88 9d 70 0a STA &0a70,X ; lasers_screen_address_low &1d8b a5 71 LDA &71 ; screen_address_high &1d8d 9d 80 0a STA &0a80,X ; lasers_screen_address_high &1d90 20 e6 1d JSR &1de6 ; plot_laser # Plot new laser &1d93 20 9e 19 JSR &199e ; wipe_laser_gauge &1d96 a9 ff LDA #&ff &1d98 20 dd 18 JSR &18dd ; add_to_fuel # Lose 1 fuel for firing laser &1d9b a9 00 LDA #&00 &1d9d 20 91 24 JSR &2491 ; play_sound # Play sound for firing laser ; update_lasers &1da0 a2 03 LDX #&03 ; update_lasers_loop &1da2 bd 80 0a LDA &0a80,X ; lasers_screen_address_high # Non-zero if laser in slot &1da5 d0 04 BNE &1dab ; update_laser ; consider_next_laser &1da7 ca DEX &1da8 10 f8 BPL &1da2 ; update_lasers_loop &1daa 60 RTS ; update_laser &1dab 86 80 STX &80 ; laser_slot &1dad 85 71 STA &71 ; screen_address_high &1daf bd 70 0a LDA &0a70,X ; lasers_screen_address_low &1db2 85 70 STA &70 ; screen_address_low &1db4 20 e6 1d JSR &1de6 ; plot_laser # Unplot laser &1db7 d0 67 BNE &1e20 ; check_for_laser_collision_with_enemies ; move_laser &1db9 bd 50 0a LDA &0a50,X ; lasers_y &1dbc 18 CLC &1dbd 69 04 ADC #&04 # Move laser up four pixels &1dbf 9d 50 0a STA &0a50,X ; lasers_y &1dc2 c9 be CMP #&be # Has the laser hit the top of the hiway? &1dc4 90 07 BCC &1dcd ; skip_removing_laser &1dc6 a9 00 LDA #&00 &1dc8 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &1dcb f0 da BEQ &1da7 ; consider_next_laser # Always branches ; skip_removing_laser &1dcd a8 TAY &1dce bd 40 0a LDA &0a40,X ; lasers_x &1dd1 aa TAX &1dd2 20 60 14 JSR &1460 ; calculate_screen_address &1dd5 a6 80 LDX &80 ; laser_slot &1dd7 9d 70 0a STA &0a70,X ; lasers_screen_address_low &1dda a5 71 LDA &71 ; screen_address_high &1ddc 9d 80 0a STA &0a80,X ; lasers_screen_address_high &1ddf 20 e6 1d JSR &1de6 ; plot_laser # Plot laser &1de2 a6 80 LDX &80 ; laser_slot &1de4 10 c1 BPL &1da7 ; consider_next_laser # Always branches ; plot_laser &1de6 a0 00 LDY #&00 &1de8 84 72 STY &72 ; laser_collision &1dea a2 05 LDX #&05 ; plot_laser_loop &1dec a9 15 LDA #&15 ; KW &1dee 51 70 EOR (&70),Y ; screen_address # Plot pixel of laser &1df0 91 70 STA (&70),Y ; screen_address &1df2 05 72 ORA &72 ; laser_collision &1df4 85 72 STA &72 ; laser_collision &1df6 a5 70 LDA &70 ; screen_address_low &1df8 38 SEC &1df9 e9 01 SBC #&01 # Move up a row &1dfb 48 PHA ; screen_address_low &1dfc 85 70 STA &70 ; screen_address_low &1dfe a5 71 LDA &71 ; screen_address_high &1e00 e9 00 SBC #&00 &1e02 85 71 STA &71 ; screen_address_high &1e04 68 PLA &1e05 29 07 AND #&07 &1e07 49 07 EOR #&07 &1e09 d0 0d BNE &1e18 ; not_new_group &1e0b a5 70 LDA &70 ; screen_address_low &1e0d 38 SEC &1e0e e9 78 SBC #&78 # Move up a group &1e10 85 70 STA &70 ; screen_address_low &1e12 a5 71 LDA &71 ; screen_address_high &1e14 e9 02 SBC #&02 &1e16 85 71 STA &71 ; screen_address_high ; not_new_group &1e18 ca DEX &1e19 d0 d1 BNE &1dec ; plot_laser_loop &1e1b a6 80 LDX &80 ; laser_slot &1e1d a5 72 LDA &72 ; laser_collision &1e1f 60 RTS ; check_for_laser_collision_with_enemies &1e20 bd 40 0a LDA &0a40,X ; lasers_x &1e23 85 74 STA &74 ; laser_x &1e25 bd 50 0a LDA &0a50,X ; lasers_y &1e28 85 75 STA &75 ; laser_y &1e2a bd 60 0a LDA &0a60,X ; lasers_energy &1e2d 85 76 STA &76 ; laser_energy &1e2f ae 00 2f LDX &2f00 ; number_of_enemies &1e32 ca DEX ; check_for_laser_collision_with_enemies_loop &1e33 bd 30 09 LDA &0930,X ; enemies_type &1e36 c9 80 CMP #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &1e38 d0 03 BNE &1e3d ; check_for_laser_collision_with_enemy ; to_consider_next_enemy &1e3a 4c 03 1f JMP &1f03 ; consider_next_enemy ; check_for_laser_collision_with_enemy &1e3d bd 48 09 LDA &0948,X ; enemies_hiway_section &1e40 c9 02 CMP #&02 # Is the enemy on the visible section of the hiway? &1e42 d0 f6 BNE &1e3a ; to_consider_next_enemy &1e44 a5 74 LDA &74 ; laser_x &1e46 38 SEC &1e47 fd 00 09 SBC &0900,X ; enemies_x &1e4a 30 10 BMI &1e5c ; to_consider_next_enemy # Has the laser hit the enemy? &1e4c c9 04 CMP #&04 &1e4e b0 0c BCS &1e5c ; to_consider_next_enemy &1e50 bd 0c 09 LDA &090c,X ; enemies_y &1e53 38 SEC &1e54 e5 75 SBC &75 ; laser_y &1e56 30 04 BMI &1e5c ; to_consider_next_enemy &1e58 c9 0e CMP #&0e &1e5a 90 03 BCC &1e5f ; laser_hit_enemy ; to_consider_next_enemy &1e5c 4c 03 1f JMP &1f03 ; consider_next_enemy ; laser_hit_enemy &1e5f 8a TXA &1e60 48 PHA ; enemy_slot &1e61 a9 08 LDA #&08 &1e63 20 91 24 JSR &2491 ; play_sound # Play sound for laser hitting enemy &1e66 68 PLA ; enemy_slot &1e67 aa TAX &1e68 bd 30 09 LDA &0930,X ; enemies_type # Top bit set if enemy is attacking, i.e. not on hiway &1e6b 30 1b BMI &1e88 ; skip_removing_from_hiway &1e6d a9 ff LDA #&ff &1e6f 9d 3c 09 STA &093c,X ; enemies_energy # Enemies on hiway are destroyed by any laser &1e72 bd 60 09 LDA &0960,X ; enemies_hiway_screen_address_low &1e75 85 70 STA &70 ; screen_address_low &1e77 bd 6c 09 LDA &096c,X ; enemies_hiway_screen_address_high &1e7a 85 71 STA &71 ; screen_address_high &1e7c bd 90 09 LDA &0990,X ; enemies_hiway_pixel_in_pair &1e7f 85 73 STA &73 ; pixel_in_pair &1e81 8a TXA &1e82 48 PHA ; enemy_slot &1e83 20 be 15 JSR &15be ; plot_enemy_on_hiway # Unplot enemy on hiway &1e86 68 PLA ; enemy_slot &1e87 aa TAX ; skip_removing_from_hiway &1e88 bd 3c 09 LDA &093c,X ; enemies_energy &1e8b 38 SEC &1e8c e5 76 SBC &76 ; laser_energy &1e8e 9d 3c 09 STA &093c,X ; enemies_energy &1e91 10 5b BPL &1eee ; skip_exploding_enemy # Is the laser strong enough to destroy the enemy? &1e93 bd 18 09 LDA &0918,X ; enemies_screen_address_low &1e96 85 70 STA &70 ; screen_address_low &1e98 bd 24 09 LDA &0924,X ; enemies_screen_address_high &1e9b 85 71 STA &71 ; screen_address_high &1e9d bd 30 09 LDA &0930,X ; enemies_type &1ea0 48 PHA ; enemy_type &1ea1 a9 80 LDA #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &1ea3 9d 30 09 STA &0930,X ; enemies_type # Set enemy exploding &1ea6 a9 08 LDA #&08 &1ea8 9d 48 09 STA &0948,X ; enemies_explosion_state # Start explosion &1eab a9 00 LDA #&00 &1ead 9d 3c 09 STA &093c,X ; enemies_explosion_cooldown &1eb0 68 PLA ; enemy_type &1eb1 48 PHA ; enemy_type &1eb2 29 0f AND #&0f &1eb4 a8 TAY &1eb5 b9 e5 2c LDA &2ce5,Y ; enemy_types_pixel_value - 1 # Enemy type sets colour of explosion &1eb8 29 15 AND #&15 ; KW &1eba 9d 90 09 STA &0990,X ; enemies_explosion_pixel_value &1ebd 68 PLA ; enemy_type &1ebe 48 PHA ; enemy_type &1ebf 29 0f AND #&0f &1ec1 38 SEC &1ec2 e9 01 SBC #&01 &1ec4 20 97 14 JSR &1497 ; use_sprite &1ec7 20 ad 14 JSR &14ad ; plot_sprite # Unplot destroyed enemy &1eca 68 PLA ; enemy_type &1ecb 08 PHP ; enemy is attacking &1ecc c9 8f CMP #&8f ; ENEMY_ATTACKING | ENEMY_ROCKET &1ece f0 28 BEQ &1ef8 ; is_rocket &1ed0 38 SEC &1ed1 e9 01 SBC #&01 &1ed3 29 03 AND #&03 &1ed5 a0 00 LDY #&00 &1ed7 28 PLP ; enemy is attacking # Negative if enemy is attacking &1ed8 10 02 BPL &1edc ; skip_bonus &1eda a0 04 LDY #&04 # Score more if enemy is attacking ; skip_bonus &1edc 85 70 STA &70 ; bonus_offset &1ede 98 TYA &1edf 18 CLC &1ee0 65 70 ADC &70 ; bonus_offset &1ee2 aa TAX &1ee3 bd 38 2f LDA &2f38,X ; enemy_types_score_high # Score depending on type of destroyed enemy &1ee6 a8 TAY &1ee7 bd 40 2f LDA &2f40,X ; enemy_types_score_low &1eea aa TAX &1eeb 20 e2 23 JSR &23e2 ; add_to_score ; remove_laser ; skip_exploding_enemy &1eee a6 80 LDX &80 ; laser_slot &1ef0 a9 00 LDA #&00 &1ef2 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &1ef5 4c a7 1d JMP &1da7 ; consider_next_laser ; is_rocket &1ef8 28 PLP &1ef9 a2 00 LDX #&00 &1efb a0 05 LDY #&05 &1efd 20 e2 23 JSR &23e2 ; add_to_score # Score 500 for destroying rocket &1f00 4c ee 1e JMP &1eee ; remove_laser ; consider_next_enemy &1f03 ca DEX &1f04 30 03 BMI &1f09 ; check_for_laser_collision_with_bombs &1f06 4c 33 1e JMP &1e33 ; check_for_laser_collision_with_enemies_loop ; check_for_laser_collision_with_bombs &1f09 a2 0f LDX #&0f ; check_for_laser_collision_with_bombs_loop &1f0b bd 30 0a LDA &0a30,X ; bombs_screen_address_high # Zero if no bomb in slot &1f0e f0 39 BEQ &1f49 ; consider_next_bomb &1f10 bd 00 0a LDA &0a00,X ; bombs_x &1f13 c5 74 CMP &74 ; laser_x # Has the laser hit the bomb? &1f15 d0 32 BNE &1f49 ; consider_next_bomb &1f17 bd 10 0a LDA &0a10,X ; bombs_y &1f1a 38 SEC &1f1b e5 75 SBC &75 ; laser_y &1f1d 18 CLC &1f1e 69 02 ADC #&02 &1f20 30 27 BMI &1f49 ; consider_next_bomb &1f22 c9 07 CMP #&07 &1f24 b0 23 BCS &1f49 ; consider_next_bomb &1f26 bd 20 0a LDA &0a20,X ; bombs_screen_address_low &1f29 85 70 STA &70 ; screen_address_low &1f2b bd 30 0a LDA &0a30,X ; bombs_screen_address_high &1f2e 85 71 STA &71 ; screen_address_high &1f30 a9 00 LDA #&00 &1f32 9d 30 0a STA &0a30,X ; bombs_screen_address_high # Set to zero to remove bomb &1f35 a6 80 LDX &80 ; laser_slot &1f37 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &1f3a 20 fd 1c JSR &1cfd ; plot_bomb # Unplot bomb &1f3d a2 25 LDX #&25 &1f3f a0 00 LDY #&00 &1f41 20 e2 23 JSR &23e2 ; add_to_score # Score 25 for hitting bomb with laser &1f44 a6 80 LDX &80 ; laser_slot &1f46 4c a7 1d JMP &1da7 ; consider_next_laser ; consider_next_bomb &1f49 ca DEX &1f4a 10 bf BPL &1f0b ; check_for_laser_collision_with_bombs_loop ; check_for_laser_collision_with_fuelpod &1f4c ad c8 09 LDA &09c8 ; active_fuelpod # Positive if fuelpod active &1f4f c9 ff CMP #&ff &1f51 d0 03 BNE &1f56 ; check_for_laser_collision_with_active_fuelpod &1f53 4c ce 1f JMP &1fce ; check_for_laser_reaching_top_of_hiway ; check_for_laser_collision_with_active_fuelpod &1f56 aa TAX &1f57 bc b0 09 LDY &09b0,X ; fuelpods_state &1f5a 88 DEY &1f5b bd ac 09 LDA &09ac,X ; fuelpods_y &1f5e 38 SEC &1f5f e5 75 SBC &75 ; laser_y &1f61 30 6b BMI &1fce ; check_for_laser_reaching_top_of_hiway # Is the laser aligned with the fuelpod vertically? &1f63 c9 07 CMP #&07 &1f65 b0 67 BCS &1fce ; check_for_laser_reaching_top_of_hiway &1f67 bd a8 09 LDA &09a8,X ; fuelpods_x &1f6a 38 SEC &1f6b f9 f0 28 SBC &28f0,Y ; fuelpod_state_x_offsets &1f6e 85 76 STA &76 ; fuelpod_x &1f70 38 SEC &1f71 a5 74 LDA &74 ; laser_x &1f73 e5 76 SBC &76 ; fuelpod_x &1f75 30 57 BMI &1fce ; check_for_laser_reaching_top_of_hiway &1f77 d9 fc 28 CMP &28fc,Y ; initial_fuelpod_sprite_widths_table &1f7a b0 52 BCS &1fce ; check_for_laser_reaching_top_of_hiway &1f7c c0 02 CPY #&02 ; FUELPOD_RIGHT_TUG - 1 &1f7e b0 42 BCS &1fc2 ; check_for_laser_collision_with_active_fuelpod_without_left_tug &1f80 c9 08 CMP #&08 &1f82 b0 0f BCS &1f93 ; add_fuelpod_explosion_for_right_tug &1f84 c9 03 CMP #&03 &1f86 90 08 BCC &1f90 ; add_fuelpod_explosion_for_left_tug &1f88 a9 00 LDA #&00 ; FUELPOD_NONE &1f8a 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod &1f8d 4c 96 1f JMP &1f96 ; add_fuelpod_explosion ; add_fuelpod_explosion_for_left_tug &1f90 fe b0 09 INC &09b0,X ; fuelpods_state ; add_fuelpod_explosion_for_right_tug &1f93 fe b0 09 INC &09b0,X ; fuelpods_state ; add_fuelpod_explosion &1f96 a9 00 LDA #&00 &1f98 a6 80 LDX &80 ; laser_slot &1f9a 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &1f9d a2 0b LDX #&0b ; find_free_slot_for_fuelpod_explosion_loop &1f9f bd a8 0a LDA &0aa8,X ; fuelpod_explosions_state # Zero if no fuelpod explosion in slot &1fa2 f0 03 BEQ &1fa7 ; found_free_slot &1fa4 ca DEX &1fa5 10 f8 BPL &1f9f ; find_free_slot_for_fuelpod_explosion_loop ; found_free_slot &1fa7 a5 74 LDA &74 ; laser_x &1fa9 9d 90 0a STA &0a90,X ; fuelpod_explosions_x &1fac a5 75 LDA &75 ; laser_y &1fae 9d 9c 0a STA &0a9c,X ; fuelpod_explosions_y &1fb1 a9 08 LDA #&08 &1fb3 9d a8 0a STA &0aa8,X ; fuelpod_explosions_state &1fb6 a2 00 LDX #&00 &1fb8 a0 03 LDY #&03 &1fba 20 e2 23 JSR &23e2 ; add_to_score # Score 300 for destroy fuelpod or tug &1fbd a6 80 LDX &80 ; laser_slot &1fbf 4c a7 1d JMP &1da7 ; consider_next_laser ; check_for_laser_collision_with_active_fuelpod_without_left_tug &1fc2 c9 05 CMP #&05 &1fc4 b0 cd BCS &1f93 ; add_fuelpod_explosion_for_right_tug &1fc6 a9 00 LDA #&00 ; FUELPOD_NONE &1fc8 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod &1fcb 4c 96 1f JMP &1f96 ; add_fuelpod_explosion ; check_for_laser_reaching_top_of_hiway &1fce a5 75 LDA &75 ; laser_y &1fd0 c9 af CMP #&af &1fd2 90 0a BCC &1fde ; skip_removing_laser # Has the laser reached the top of the hiway? &1fd4 a9 00 LDA #&00 &1fd6 a6 80 LDX &80 ; laser_slot &1fd8 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &1fdb 4c a7 1d JMP &1da7 ; consider_next_laser ; skip_removing_laser &1fde a6 80 LDX &80 ; laser_slot &1fe0 4c b9 1d JMP &1db9 ; move_laser ; update_exploding_enemy &1fe3 bd 48 09 LDA &0948,X ; enemies_explosion_state &1fe6 f0 05 BEQ &1fed ; to_to_consider_next_enemy &1fe8 de 3c 09 DEC &093c,X ; enemies_explosion_cooldown &1feb 30 03 BMI &1ff0 ; update_enemy_explosion ; to_to_consider_next_enemy &1fed 4c 6e 1c JMP &1c6e ; to_consider_next_enemy ; update_enemy_explosion &1ff0 a9 04 LDA #&04 &1ff2 9d 3c 09 STA &093c,X ; enemies_explosion_cooldown &1ff5 bd 48 09 LDA &0948,X ; enemies_explosion_state &1ff8 c9 08 CMP #&08 &1ffa f0 06 BEQ &2002 ; new_explosion &1ffc 20 21 20 JSR &2021 ; plot_explosion # Unplot explosion &1fff 4c 0d 20 JMP &200d ; update_explosion ; new_explosion &2002 48 PHA ; explosion_state &2003 8a TXA &2004 48 PHA ; enemy_slot &2005 a9 02 LDA #&02 &2007 20 91 24 JSR &2491 ; play_sound # Play sound for exploding enemy &200a 68 PLA ; enemy_slot &200b aa TAX &200c 68 PLA ; explosion_state ; update_explosion &200d de 48 09 DEC &0948,X ; enemies_explosion_state &2010 d0 06 BNE &2018 ; not_end_of_explosion &2012 ce 01 2f DEC &2f01 ; enemies_remaining &2015 4c 6e 1c JMP &1c6e ; to_consider_next_enemy ; not_end_of_explosion &2018 bd 48 09 LDA &0948,X ; enemies_explosion_state &201b 20 21 20 JSR &2021 ; plot_explosion # Plot explosion &201e 4c 6e 1c JMP &1c6e ; to_consider_next_enemy ; plot_explosion &2021 85 76 STA &76 ; explosion_state &2023 a9 08 LDA #&08 &2025 38 SEC &2026 e5 76 SBC &76 ; explosion_state &2028 0a ASL A &2029 85 76 STA &76 ; explosion_size &202b bd 00 09 LDA &0900,X ; enemies_x &202e 85 73 STA &73 ; explosion_x &2030 bd 0c 09 LDA &090c,X ; enemies_y &2033 85 74 STA &74 ; explosion_y &2035 bd 90 09 LDA &0990,X ; enemies_explosion_pixel_value &2038 85 75 STA &75 ; explosion_pixel_value &203a a9 07 LDA #&07 &203c 85 77 STA &77 ; particle ; plot_explosion_particles_loop # For each particle in the explosion, &203e a4 77 LDY &77 ; particle &2040 a5 73 LDA &73 ; explosion_x # Calculate x position of particle &2042 a6 76 LDX &76 ; explosion_size ; x_multiplication_loop &2044 18 CLC &2045 79 13 2f ADC &2f13,Y ; explosion_x_deltas &2048 ca DEX &2049 d0 f9 BNE &2044 ; x_multiplication_loop &204b 85 70 STA &70 ; particle_x &204d 30 25 BMI &2074 ; consider_next_particle # Skip plotting if beyond left &204f c9 50 CMP #&50 # or right edge of screen &2051 b0 21 BCS &2074 ; consider_next_particle &2053 a5 74 LDA &74 ; explosion_y # Calculate y position of particle &2055 a6 76 LDX &76 ; explosion_size ; y_multiplication_loop &2057 18 CLC &2058 79 1b 2f ADC &2f1b,Y ; explosion_y_deltas &205b ca DEX &205c d0 f9 BNE &2057 ; y_multiplication_loop &205e a8 TAY &205f c9 28 CMP #&28 # Skip plotting if below ground &2061 90 11 BCC &2074 ; consider_next_particle &2063 c9 b4 CMP #&b4 # or above hiway &2065 b0 0d BCS &2074 ; consider_next_particle &2067 a6 70 LDX &70 ; particle_x &2069 20 60 14 JSR &1460 ; calculate_screen_address &206c a0 00 LDY #&00 &206e a5 75 LDA &75 ; explosion_pixel_value &2070 51 70 EOR (&70),Y ; screen_address # Plot particle &2072 91 70 STA (&70),Y ; screen_address ; consider_next_particle &2074 c6 77 DEC &77 ; particle &2076 10 c6 BPL &203e ; plot_explosion_particles_loop &2078 a6 80 LDX &80 ; enemy_slot, fuelpod_explosion_slot &207a 60 RTS ; update_exploding_fuelpod &207b bd a8 0a LDA &0aa8,X ; fuelpod_explosions_state # Zero if no fuelpod explosion in slot &207e f0 05 BEQ &2085 ; leave &2080 de b4 0a DEC &0ab4,X ; fuelpod_explosions_cooldown &2083 30 01 BMI &2086 ; update_fuelpod_explosion ; leave &2085 60 RTS ; update_fuelpod_explosion &2086 a9 04 LDA #&04 &2088 9d b4 0a STA &0ab4,X ; fuelpod_explosions_cooldown &208b bd a8 0a LDA &0aa8,X ; fuelpod_explosions_state # Zero if no fuelpod explosion in slot &208e c9 08 CMP #&08 &2090 f0 06 BEQ &2098 ; new_fuelpod_explosion &2092 20 af 20 JSR &20af ; plot_fuelpod_explosion # Unplot fuelpod explosion &2095 4c a3 20 JMP &20a3 ; not_new_explosion ; new_fuelpod_explosion &2098 48 PHA ; fuelpod_explosion_state &2099 8a TXA &209a 48 PHA ; fuelpod_explosion_slot &209b a9 06 LDA #&06 &209d 20 91 24 JSR &2491 ; play_sound # Play sound for exploding fuelpod &20a0 68 PLA ; fuelpod_explosion_slot &20a1 aa TAX &20a2 68 PLA ; fuelpod_explosion_state ; not_new_explosion &20a3 de a8 0a DEC &0aa8,X ; fuelpod_explosions_state &20a6 d0 01 BNE &20a9 ; not_end_of_explosion &20a8 60 RTS ; not_end_of_explosion &20a9 bd a8 0a LDA &0aa8,X ; fuelpod_explosions_state # Zero if no fuelpod explosion in slot &20ac 4c af 20 JMP &20af ; plot_fuelpod_explosion # Plot fuelpod explosion ; plot_fuelpod_explosion &20af 85 76 STA &76 ; explosion_state &20b1 a9 08 LDA #&08 &20b3 38 SEC &20b4 e5 76 SBC &76 ; explosion_state &20b6 0a ASL A &20b7 85 76 STA &76 ; explosion_size &20b9 bd 90 0a LDA &0a90,X ; fuelpod_explosions_x &20bc 85 73 STA &73 ; explosion_x &20be bd 9c 0a LDA &0a9c,X ; fuelpod_explosions_y &20c1 85 74 STA &74 ; explosion_y &20c3 a9 0c LDA #&0c ; GG # Fuelpod explosions are green &20c5 85 75 STA &75 ; explosion_pixel_value &20c7 a9 07 LDA #&07 &20c9 85 77 STA &77 ; particle &20cb 4c 3e 20 JMP &203e ; plot_explosion_particles_loop ; update_exploding_fuelpods &20ce a2 0b LDX #&0b &20d0 86 80 STX &80 ; fuelpod_explosion_slot ; update_exploding_fuelpods_loop &20d2 a6 80 LDX &80 ; fuelpod_explosion_slot &20d4 20 7b 20 JSR &207b ; update_exploding_fuelpod &20d7 c6 80 DEC &80 ; fuelpod_explosion_slot &20d9 10 f7 BPL &20d2 ; update_exploding_fuelpods_loop &20db 60 RTS ; explode_player &20dc a9 f1 LDA #&f1 # Set colour 15 to red &20de 20 4d 14 JSR &144d ; set_palette &20e1 20 5c 18 JSR &185c ; plot_player # Unplot player &20e4 20 df 21 JSR &21df ; unplot_bombs_and_lasers &20e7 a9 04 LDA #&04 &20e9 20 91 24 JSR &2491 ; play_sound # Play sound for exploding player &20ec a9 29 LDA #&29 &20ee 85 80 STA &80 ; fragment_slot ; initialise_fragments_loop &20f0 a6 80 LDX &80 ; fragment_slot &20f2 20 22 14 JSR &1422 ; rnd &20f5 29 07 AND #&07 &20f7 85 70 STA &70 ; x_offset &20f9 ad 02 2f LDA &2f02 ; player_x &20fc 18 CLC &20fd 65 70 ADC &70 ; x_offset &20ff 9d 00 06 STA &0600,X ; fragments_x &2102 48 PHA ; fragment_x &2103 a9 25 LDA #&25 &2105 48 PHA ; fragment_y &2106 9d 2a 06 STA &062a,X ; fragments_y &2109 20 22 14 JSR &1422 ; rnd &210c 29 03 AND #&03 &210e 18 CLC &210f 69 02 ADC #&02 # Random y velocity between 2 and 5 &2111 9d 7e 06 STA &067e,X ; fragments_y_velocity &2114 20 22 14 JSR &1422 ; rnd &2117 08 PHP ; sign &2118 29 03 AND #&03 # Random x velocity between -3 and 3 &211a 28 PLP ; sign &211b 10 07 BPL &2124 ; skip_inversion &211d 85 70 STA &70 ; absolute_x_velocity &211f a9 00 LDA #&00 &2121 38 SEC &2122 e5 70 SBC &70 ; absolute_x_velocity ; skip_inversion &2124 9d 54 06 STA &0654,X ; fragments_x_velocity &2127 68 PLA ; fragment_y &2128 a8 TAY &2129 68 PLA ; fragment_x &212a aa TAX &212b 20 60 14 JSR &1460 ; calculate_screen_address &212e a6 80 LDX &80 ; fragment_slot &2130 a5 70 LDA &70 ; screen_address_low &2132 9d a8 06 STA &06a8,X ; fragments_screen_address_low &2135 a5 71 LDA &71 ; screen_address_high &2137 9d d2 06 STA &06d2,X ; fragments_screen_address_high &213a a9 0f LDA #&0f ; SPRITE_EXPLOSION_FRAGMENT &213c 20 97 14 JSR &1497 ; use_sprite &213f 20 ad 14 JSR &14ad ; plot_sprite # Plot initial fragment &2142 c6 80 DEC &80 ; fragment_slot &2144 10 aa BPL &20f0 ; initialise_fragments_loop &2146 a9 96 LDA #&96 &2148 8d fc 06 STA &06fc ; explosion_timer ; update_explosion_frame_loop &214b a9 29 LDA #&29 &214d 20 6f 21 JSR &216f ; update_fragments &2150 20 55 14 JSR &1455 ; wait_for_vsync &2153 ad fc 06 LDA &06fc ; explosion_timer &2156 29 07 AND #&07 &2158 d0 0f BNE &2169 ; skip_palette_change &215a ee 2b 2f INC &2f2b ; explosion_colour_offset &215d ad 2b 2f LDA &2f2b ; explosion_colour_offset &2160 29 07 AND #&07 &2162 a8 TAY &2163 b9 23 2f LDA &2f23,Y ; explosion_colours &2166 20 4d 14 JSR &144d ; set_palette # Set colour 15 to explosion colour ; skip_palette_change &2169 ce fc 06 DEC &06fc ; explosion_timer &216c d0 dd BNE &214b ; update_explosion_frame_loop &216e 60 RTS ; update_fragments &216f 85 80 STA &80 ; fragment_slot ; update_fragments_loop &2171 a6 80 LDX &80 ; fragment_slot &2173 bd a8 06 LDA &06a8,X ; fragments_screen_address_low &2176 85 70 STA &70 ; screen_address_low &2178 bd d2 06 LDA &06d2,X ; fragments_screen_address_high # Zero if no fragment in slot &217b f0 5d BEQ &21da ; consider_next_fragment &217d 85 71 STA &71 ; screen_address_high &217f a9 0f LDA #&0f ; SPRITE_EXPLOSION_FRAGMENT &2181 20 97 14 JSR &1497 ; use_sprite &2184 20 ad 14 JSR &14ad ; plot_sprite # Unplot fragment &2187 a6 80 LDX &80 ; fragment_slot &2189 bd 00 06 LDA &0600,X ; fragments_x &218c 18 CLC &218d 7d 54 06 ADC &0654,X ; fragments_x_velocity # Apply x velocity &2190 a0 00 LDY #&00 &2192 9d 00 06 STA &0600,X ; fragments_x &2195 85 70 STA &70 ; fragment_x &2197 10 01 BPL &219a ; not_off_left_of_screen &2199 c8 INY ; not_off_left_of_screen &219a c9 4f CMP #&4f &219c 90 01 BCC &219f ; not_off_right_of_screen &219e c8 INY ; not_off_right_of_screen &219f 98 TYA &21a0 f0 08 BEQ &21aa ; skip_removing_fragment # Has the fragment gone off the screen horizontally? &21a2 a9 00 LDA #&00 &21a4 9d d2 06 STA &06d2,X ; fragments_screen_address_high # Set to zero to remove fragment &21a7 4c da 21 JMP &21da ; consider_next_fragment ; skip_removing_fragment &21aa bd 2a 06 LDA &062a,X ; fragments_y &21ad 18 CLC &21ae 7d 7e 06 ADC &067e,X ; fragments_y_velocity # Apply y velocity &21b1 c9 b4 CMP #&b4 # Has the fragment gone off the screen vertically? &21b3 90 08 BCC &21bd ; skip_removing_fragment &21b5 a9 00 LDA #&00 &21b7 9d d2 06 STA &06d2,X ; fragments_screen_address_high # Set to zero to remove fragment &21ba 4c da 21 JMP &21da ; consider_next_fragment ; skip_removing_fragment &21bd 9d 2a 06 STA &062a,X ; fragments_y &21c0 a8 TAY &21c1 a6 70 LDX &70 ; screen_address_low &21c3 20 60 14 JSR &1460 ; calculate_screen_address &21c6 a6 80 LDX &80 ; fragment_slot &21c8 a5 70 LDA &70 ; screen_address_low &21ca 9d a8 06 STA &06a8,X ; fragments_screen_address_low &21cd a5 71 LDA &71 ; screen_address_high &21cf 9d d2 06 STA &06d2,X ; fragments_screen_address_high &21d2 a9 0f LDA #&0f ; SPRITE_EXPLOSION_FRAGMENT &21d4 20 97 14 JSR &1497 ; use_sprite &21d7 20 ad 14 JSR &14ad ; plot_sprite # Plot fragment ; consider_next_fragment &21da c6 80 DEC &80 ; fragment_slot &21dc 10 93 BPL &2171 ; update_fragments_loop &21de 60 RTS ; unplot_bombs_and_lasers &21df a2 0f LDX #&0f ; unplot_bombs_loop &21e1 bd 30 0a LDA &0a30,X ; bombs_screen_address_high # Zero if no bomb in slot &21e4 f0 0a BEQ &21f0 ; consider_next_bomb &21e6 85 71 STA &71 ; screen_address_high &21e8 bd 20 0a LDA &0a20,X ; bombs_screen_address_low &21eb 85 70 STA &70 ; screen_address_low &21ed 20 fd 1c JSR &1cfd ; plot_bomb # Unplot bomb ; consider_next_bomb &21f0 ca DEX &21f1 10 ee BPL &21e1 ; unplot_bombs_loop &21f3 a2 03 LDX #&03 ; unplot_lasers_loop &21f5 86 80 STX &80 ; laser_slot &21f7 bd 80 0a LDA &0a80,X ; lasers_screen_address_high # Zero if no laser in slot &21fa f0 0a BEQ &2206 ; consider_next_laser &21fc 85 71 STA &71 ; screen_address_high &21fe bd 70 0a LDA &0a70,X ; lasers_screen_address_low &2201 85 70 STA &70 ; screen_address_low &2203 20 e6 1d JSR &1de6 ; plot_laser # Unplot laser ; consider_next_laser &2206 ca DEX &2207 10 ec BPL &21f5 ; unplot_lasers_loop &2209 60 RTS ; consider_updating_fuelpod &220a ce da 09 DEC &09da ; fuelpod_update_cooldown &220d 30 01 BMI &2210 ; update_fuelpod &220f 60 RTS ; update_fuelpod &2210 ad 30 2f LDA &2f30 ; maximum_fuelpod_update_cooldown &2213 8d da 09 STA &09da ; fuelpod_update_cooldown &2216 ad c8 09 LDA &09c8 ; active_fuelpod # Positive if fuelpod active &2219 c9 ff CMP #&ff &221b d0 22 BNE &223f ; update_active_fuelpod &221d 20 22 14 JSR &1422 ; rnd &2220 29 7f AND #&7f &2222 c9 04 CMP #&04 # 1 in 128 chance of activating each fuelpod &2224 90 01 BCC &2227 ; consider_setting_active_fuelpod &2226 60 RTS ; consider_setting_active_fuelpod &2227 aa TAX &2228 bd b0 09 LDA &09b0,X ; fuelpods_state # Non-zero if fuelpod is present &222b d0 01 BNE &222e ; set_active_fuelpod &222d 60 RTS ; set_active_fuelpod &222e 8e c8 09 STX &09c8 ; active_fuelpod &2231 bd a8 09 LDA &09a8,X ; fuelpods_x &2234 a0 01 LDY #&01 &2236 c9 28 CMP #&28 # Fuelpods at the left of the screen move right &2238 90 02 BCC &223c ; set_active_fuelpod_direction &223a a0 ff LDY #&ff # Fuelpods at the left of the screen move left ; set_active_fuelpod_direction &223c 8c c9 09 STY &09c9 ; active_fuelpod_direction ; update_active_fuelpod &223f ae c8 09 LDX &09c8 ; active_fuelpod ; plot_or_unplot_fuelpod &2242 86 80 STX &80 ; fuelpod_slot &2244 bd b4 09 LDA &09b4,X ; fuelpods_screen_address_low &2247 85 70 STA &70 ; screen_address_low &2249 bd b8 09 LDA &09b8,X ; fuelpods_screen_address_high &224c 85 71 STA &71 ; screen_address_high &224e bd bc 09 LDA &09bc,X ; fuelpods_sprite_address_low &2251 85 72 STA &72 ; sprite_address_low &2253 bd c0 09 LDA &09c0,X ; fuelpods_sprite_address_high &2256 85 73 STA &73 ; sprite_address_high &2258 bd c4 09 LDA &09c4,X ; fuelpods_sprite_width &225b 85 74 STA &74 ; sprite_width &225d a9 06 LDA #&06 &225f 85 75 STA &75 ; sprite_height &2261 20 ad 14 JSR &14ad ; plot_sprite # Unplot fuelpod if updating &2264 a6 80 LDX &80 ; fuelpod_slot &2266 bc b0 09 LDY &09b0,X ; fuelpods_state # Non-zero if fuelpod is present &2269 d0 05 BNE &2270 ; is_present &226b 88 DEY ; &ff &226c 8c c8 09 STY &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active &226f 60 RTS ; is_present &2270 88 DEY &2271 c0 03 CPY #&03 ; FUELPOD_NO_TUGS - 1 &2273 d0 03 BNE &2278 ; update_moving_fuelpod &2275 4c 16 23 JMP &2316 ; update_falling_fuelpod ; update_moving_fuelpod &2278 bd a8 09 LDA &09a8,X ; fuelpods_x &227b 18 CLC &227c 6d c9 09 ADC &09c9 ; active_fuelpod_direction &227f 9d a8 09 STA &09a8,X ; fuelpods_x &2282 d0 05 BNE &2289 ; not_at_left # Has the fuelpod reached the left of the screen? &2284 a9 ff LDA #&ff &2286 8d c8 09 STA &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active ; not_at_left &2289 c9 55 CMP #&55 # Has the fuelpod reached the right of the screen? &228b 90 05 BCC &2292 ; not_at_right &228d a9 ff LDA #&ff &228f 8d c8 09 STA &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active ; not_at_right &2292 bd a8 09 LDA &09a8,X ; fuelpods_x &2295 38 SEC &2296 f9 f0 28 SBC &28f0,Y ; fuelpod_state_x_offsets &2299 85 70 STA &70 ; x &229b b9 fc 28 LDA &28fc,Y ; initial_fuelpod_sprite_widths_table &229e 85 71 STA &71 ; width &22a0 b9 f4 28 LDA &28f4,Y ; initial_fuelpod_sprite_addresses_low_table &22a3 85 72 STA &72 ; sprite_address_low &22a5 b9 f8 28 LDA &28f8,Y ; initial_fuelpod_sprite_addresses_high_table &22a8 85 73 STA &73 ; sprite_address_high &22aa a5 70 LDA &70 ; x &22ac 10 2d BPL &22db ; skip_clipping_to_left # Does the fuelpod cross the left of the screen? &22ae 18 CLC &22af 65 71 ADC &71 ; width &22b1 85 71 STA &71 ; width &22b3 38 SEC &22b4 e9 01 SBC #&01 &22b6 10 06 BPL &22be ; clip_to_left # Is the fuelpod completely beyond the left of the screen? &22b8 a9 00 LDA #&00 &22ba 9d b8 09 STA &09b8,X ; fuelpods_screen_address_high # If so, set to zero to indicate fuelpod not visible &22bd 60 RTS ; clip_to_left &22be a9 00 LDA #&00 &22c0 38 SEC &22c1 e5 70 SBC &70 ; x &22c3 a8 TAY &22c4 a9 00 LDA #&00 ; calculate_left_clip_loop # Calculate start of visible part of sprite &22c6 18 CLC &22c7 69 06 ADC #&06 &22c9 88 DEY &22ca d0 fa BNE &22c6 ; calculate_left_clip_loop &22cc 18 CLC &22cd 65 72 ADC &72 ; sprite_address_low &22cf 85 72 STA &72 ; sprite_address_low &22d1 a5 73 LDA &73 ; sprite_address_high &22d3 69 00 ADC #&00 &22d5 85 73 STA &73 ; sprite_address_high &22d7 a9 00 LDA #&00 # Start plotting fuelpod at left of screen &22d9 85 70 STA &70 ; x ; skip_clipping_to_left &22db 18 CLC &22dc 65 71 ADC &71 ; width &22de c9 50 CMP #&50 &22e0 90 17 BCC &22f9 ; plot_moving_fuelpod # Does the fuelpod cross the right of the screen? &22e2 38 SEC &22e3 e9 50 SBC #&50 &22e5 85 74 STA &74 ; right_clip &22e7 a5 71 LDA &71 ; width &22e9 38 SEC &22ea e5 74 SBC &74 ; right_clip &22ec 85 71 STA &71 ; width # Calculate end of visible part of sprite &22ee 38 SEC &22ef e9 01 SBC #&01 &22f1 10 06 BPL &22f9 ; plot_moving_fuelpod # Is the fuelpod completely beyond the right of the screen? &22f3 a9 00 LDA #&00 &22f5 9d b8 09 STA &09b8,X ; fuelpods_screen_address_high # If so, set to zero to indicate fuelpod not visible &22f8 60 RTS ; plot_moving_fuelpod &22f9 a5 72 LDA &72 ; sprite_address_low &22fb 9d bc 09 STA &09bc,X ; fuelpods_sprite_address_low &22fe a5 73 LDA &73 ; sprite_address_high &2300 9d c0 09 STA &09c0,X ; fuelpods_sprite_address_high &2303 a5 71 LDA &71 ; width &2305 9d c4 09 STA &09c4,X ; fuelpods_sprite_width &2308 85 74 STA &74 ; sprite_width &230a a9 06 LDA #&06 &230c 85 75 STA &75 ; sprite_height &230e a5 70 LDA &70 ; x &2310 bc ac 09 LDY &09ac,X ; fuelpods_y &2313 4c 58 23 JMP &2358 ; plot_fuelpod ; update_falling_fuelpod &2316 a9 00 LDA #&00 &2318 8d da 09 STA &09da ; fuelpod_update_cooldown # Set to zero to make fuelpod fall every update &231b bd ac 09 LDA &09ac,X ; fuelpods_y &231e 38 SEC &231f e9 02 SBC #&02 # Move fuelpod down two pixels &2321 9d ac 09 STA &09ac,X ; fuelpods_y &2324 c9 24 CMP #&24 &2326 b0 0b BCS &2333 ; not_at_ground &2328 a9 00 LDA #&00 ; FUELPOD_NONE &232a 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod &232d a9 ff LDA #&ff &232f 8d c8 09 STA &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active &2332 60 RTS ; not_at_ground &2333 a8 TAY &2334 ad fb 28 LDA &28fb ; initial_fuelpod_sprite_addresses_high_table + 3 &2337 9d c0 09 STA &09c0,X ; fuelpods_sprite_address_high &233a 85 73 STA &73 ; sprite_address_high &233c ad f7 28 LDA &28f7 ; initial_fuelpod_sprite_addresses_low_table + 3 &233f 9d bc 09 STA &09bc,X ; fuelpods_sprite_address_low &2342 a9 05 LDA #&05 &2344 85 74 STA &74 ; sprite_width &2346 9d c4 09 STA &09c4,X ; fuelpods_sprite_width &2349 bd c0 09 LDA &09c0,X ; fuelpods_sprite_address_high # Unnecessary code &234c 85 73 STA &73 ; sprite_address_high # set at &233a &234e a9 06 LDA #&06 &2350 85 75 STA &75 ; sprite_height &2352 bd a8 09 LDA &09a8,X ; fuelpods_x &2355 38 SEC &2356 e9 05 SBC #&05 ; plot_fuelpod &2358 aa TAX &2359 20 60 14 JSR &1460 ; calculate_screen_address &235c a6 80 LDX &80 ; fuelpod_slot &235e a5 70 LDA &70 ; screen_address_low &2360 9d b4 09 STA &09b4,X ; fuelpods_screen_address_low &2363 a5 71 LDA &71 ; screen_address_high &2365 9d b8 09 STA &09b8,X ; fuelpods_screen_address_high &2368 bd bc 09 LDA &09bc,X ; fuelpods_sprite_address_low &236b 85 72 STA &72 ; sprite_address_low &236d 4c ad 14 JMP &14ad ; plot_sprite # Plot fuelpod ; initialise_fuelpods &2370 a9 ff LDA #&ff &2372 8d c8 09 STA &09c8 ; active_fuelpod # Set to negative to indicate no fuelpod active &2375 a9 00 LDA #&00 &2377 8d a8 09 STA &09a8 ; fuelpods_x # Fuelpods 0 and 2 start on the left of the screen &237a 8d aa 09 STA &09aa ; fuelpods_x + 2 &237d a9 55 LDA #&55 &237f 8d a9 09 STA &09a9 ; fuelpods_x + 1 # Fuelpods 1 and 3 start on the right of the screen &2382 8d ab 09 STA &09ab ; fuelpods_x + 3 &2385 a9 6a LDA #&6a &2387 8d ac 09 STA &09ac ; fuelpods_y &238a a9 76 LDA #&76 &238c 8d ad 09 STA &09ad ; fuelpods_y + 1 &238f a9 82 LDA #&82 &2391 8d ae 09 STA &09ae ; fuelpods_y + 2 &2394 a9 8e LDA #&8e &2396 8d af 09 STA &09af ; fuelpods_y + 3 &2399 ad 31 2f LDA &2f31 ; enemies_and_fuelpods_need_initialising # Zero at start of level &239c d0 0e BNE &23ac ; skip_initialising_fuelpod_states &239e a9 01 LDA #&01 ; FUELPOD_BOTH_TUGS &23a0 8d b0 09 STA &09b0 ; fuelpods_state # Reset fuelpods at start of level &23a3 8d b1 09 STA &09b1 ; fuelpods_state + 1 &23a6 8d b2 09 STA &09b2 ; fuelpods_state + 2 &23a9 8d b3 09 STA &09b3 ; fuelpods_state + 3 ; skip_initialising_fuelpod_states &23ac a2 03 LDX #&03 ; initialise_fuelpod_sprites_loop &23ae bc b0 09 LDY &09b0,X ; fuelpods_state &23b1 b9 fc 28 LDA &28fc,Y ; initial_fuelpod_sprite_widths_table &23b4 9d c4 09 STA &09c4,X ; fuelpods_sprite_width &23b7 b9 f8 28 LDA &28f8,Y ; initial_fuelpod_sprite_addresses_high_table &23ba 9d c0 09 STA &09c0,X ; fuelpods_sprite_address_high &23bd b9 f4 28 LDA &28f4,Y ; initial_fuelpod_sprite_addresses_low_table &23c0 9d bc 09 STA &09bc,X ; fuelpods_sprite_address_low &23c3 a9 00 LDA #&00 &23c5 9d b8 09 STA &09b8,X ; fuelpods_screen_address_high # Set to zero to indicate fuelpod not plotted &23c8 ca DEX &23c9 10 e3 BPL &23ae ; initialise_fuelpod_sprites_loop &23cb a2 03 LDX #&03 ; plot_initial_fuelpods_loop &23cd a9 00 LDA #&00 &23cf 8d c9 09 STA &09c9 ; active_fuelpod_direction &23d2 86 82 STX &82 ; fuelpod_slot &23d4 20 42 22 JSR &2242 ; plot_or_unplot_fuelpod # Plot fuelpod &23d7 a6 82 LDX &82 ; fuelpod_slot &23d9 ca DEX &23da 10 f1 BPL &23cd ; plot_initial_fuelpods_loop &23dc a9 02 LDA #&02 &23de 8d da 09 STA &09da ; fuelpod_update_cooldown &23e1 60 RTS ; add_to_score &23e2 f8 SED &23e3 8a TXA &23e4 18 CLC &23e5 6d 04 2f ADC &2f04 ; score &23e8 8d 04 2f STA &2f04 ; score &23eb 98 TYA &23ec 6d 05 2f ADC &2f05 ; score + 1 &23ef 8d 05 2f STA &2f05 ; score + 1 &23f2 08 PHP ; ten thousands &23f3 a9 00 LDA #&00 &23f5 6d 06 2f ADC &2f06 ; score + 2 &23f8 8d 06 2f STA &2f06 ; score + 2 &23fb 28 PLP ; ten thousands &23fc d8 CLD &23fd 90 03 BCC &2402 ; skip_extra_life &23ff 20 5e 24 JSR &245e ; extra_life # Extra life every 10,000 points ; skip_extra_life &2402 a2 03 LDX #&03 &2404 a0 ef LDY #&ef &2406 20 60 14 JSR &1460 ; calculate_screen_address &2409 a9 00 LDA #&00 &240b 8d 2d 2f STA &2f2d ; leading_zeros # Set to zero to skip leading zeros &240e a2 02 LDX #&02 ; plot_score_loop &2410 bd 04 2f LDA &2f04,X ; score &2413 20 1a 24 JSR &241a ; plot_two_digit_number # Plot score &2416 ca DEX &2417 10 f7 BPL &2410 ; plot_score_loop &2419 60 RTS ; plot_two_digit_number &241a 86 82 STX &82 ; tmp_x &241c 48 PHA ; number &241d 29 f0 AND #&f0 &241f 20 36 24 JSR &2436 ; plot_digit &2422 68 PLA ; number &2423 0a ASL A &2424 0a ASL A &2425 0a ASL A &2426 0a ASL A &2427 e0 00 CPX #&00 &2429 d0 05 BNE &2430 ; skip_zero &242b a2 01 LDX #&01 &242d 8e 2d 2f STX &2f2d ; leading_zeros ; skip_zero &2430 20 36 24 JSR &2436 ; plot_digit &2433 a6 82 LDX &82 ; tmp_x &2435 60 RTS ; plot_digit &2436 85 72 STA &72 ; sprite_address_low &2438 0d 2d 2f ORA &2f2d ; leading_zeros &243b 8d 2d 2f STA &2f2d ; leading_zeros &243e a9 2a LDA #&2a ; &2a00 = digit_sprites &2440 85 73 STA &73 ; sprite_address_high &2442 a0 0f LDY #&0f ; plot_digit_loop &2444 ad 2d 2f LDA &2f2d ; leading_zeros # Zero to skip leading zeros &2447 f0 02 BEQ &244b ; use_blank &2449 b1 72 LDA (&72),Y ; sprite_address ; use_blank &244b 91 70 STA (&70),Y ; screen_address &244d 88 DEY &244e 10 f4 BPL &2444 ; plot_digit_loop &2450 a5 70 LDA &70 ; screen_address_low &2452 18 CLC &2453 69 10 ADC #&10 # Move four pixels right &2455 85 70 STA &70 ; screen_address_low &2457 a5 71 LDA &71 ; screen_address_high &2459 69 00 ADC #&00 &245b 85 71 STA &71 ; screen_address_high &245d 60 RTS ; extra_life &245e f8 SED &245f ad 03 2f LDA &2f03 ; player_lives &2462 18 CLC &2463 69 01 ADC #&01 &2465 8d 03 2f STA &2f03 ; player_lives &2468 d8 CLD &2469 a9 0a LDA #&0a &246b 20 91 24 JSR &2491 ; play_sound # Play sound for extra life ; plot_lives &246e a2 4a LDX #&4a &2470 a0 ef LDY #&ef &2472 20 60 14 JSR &1460 ; calculate_screen_address &2475 a2 00 LDX #&00 &2477 8e 2d 2f STX &2f2d ; leading_zeros # Set to zero to skip leading zeros &247a ad 03 2f LDA &2f03 ; player_lives &247d 4c 1a 24 JMP &241a ; plot_two_digit_number # Plot lives ; consider_draining_player_fuel &2480 ce 2e 2f DEC &2f2e ; player_fuel_drain_cooldown &2483 f0 01 BEQ &2486 ; drain_player_fuel &2485 60 RTS ; drain_player_fuel &2486 ad 2f 2f LDA &2f2f ; maximum_player_fuel_drain_cooldown &2489 8d 2e 2f STA &2f2e ; player_fuel_drain_cooldown &248c a9 ff LDA #&ff &248e 4c dd 18 JMP &18dd ; add_to_fuel # Lose 1 fuel ; play_sound &2491 0a ASL A &2492 0a ASL A &2493 0a ASL A &2494 85 70 STA &70 ; sound_address_low &2496 a9 29 LDA #&29 ; &2900 = sound_data &2498 85 71 STA &71 ; sound_address_high &249a a0 01 LDY #&01 &249c b1 70 LDA (&70),Y ; sound_address # Second byte of sound data specifies number of sounds &249e 85 83 STA &83 ; count ; play_sound_loop &24a0 a4 71 LDY &71 ; sound_address_high &24a2 a9 07 LDA #&07 ; Generate a sound &24a4 a6 70 LDX &70 ; sound_address_low &24a6 20 f1 ff JSR &fff1 ; OSWORD &24a9 a5 70 LDA &70 ; sound_address_low &24ab 18 CLC &24ac 69 08 ADC #&08 &24ae 85 70 STA &70 ; sound_address_low &24b0 c6 83 DEC &83 ; count &24b2 10 ec BPL &24a0 ; play_sound_loop &24b4 60 RTS ; start_game &24b5 a9 00 LDA #&00 &24b7 8d 35 2f STA &2f35 ; unused_variable &24ba 8d 36 2f STA &2f36 ; unused_variable + 1 &24bd 8d 37 2f STA &2f37 ; unused_variable + 2 ; start_game_without_resetting_unused_variable &24c0 20 2d 26 JSR &262d ; initialise_game ; start_new_life &24c3 20 8a 26 JSR &268a ; initialise_game_screen ; start_new_level &24c6 20 e5 26 JSR &26e5 ; reset_fuelpods_and_plot_level_and_waves_remaining ; start_new_wave &24c9 20 50 27 JSR &2750 ; play_game # Returns zero if player was killed, &24cc d0 03 BNE &24d1 ; is_complete_or_escape # one if player completed wave &24ce 4c f7 25 JMP &25f7 ; lose_life ; is_complete_or_escape &24d1 c9 02 CMP #&02 # or two if ESCAPE pressed &24d3 d0 03 BNE &24d8 ; end_of_wave &24d5 4c 27 26 JMP &2627 ; escape_pressed_in_game ; end_of_wave &24d8 ce 32 2f DEC &2f32 ; waves_remaining &24db f0 23 BEQ &2500 ; start_next_level &24dd a2 4a LDX #&4a &24df a0 df LDY #&df &24e1 20 60 14 JSR &1460 ; calculate_screen_address &24e4 a2 00 LDX #&00 &24e6 8e 2d 2f STX &2f2d ; leading_zeros # Set to zero to skip leading zeros &24e9 ad 32 2f LDA &2f32 ; waves_remaining &24ec 38 SEC &24ed e9 01 SBC #&01 &24ef 20 1a 24 JSR &241a ; plot_two_digit_number # Plot waves remaining &24f2 a9 08 LDA #&08 &24f4 8d 00 2f STA &2f00 ; number_of_enemies &24f7 8d 01 2f STA &2f01 ; enemies_remaining &24fa 20 3b 15 JSR &153b ; initialise_enemies &24fd 4c c9 24 JMP &24c9 ; start_new_wave ; start_next_level &2500 20 df 21 JSR &21df ; unplot_bombs_and_lasers &2503 a2 0f LDX #&0f &2505 a9 00 LDA #&00 ; remove_lasers_and_bombs_loop &2507 9d 80 0a STA &0a80,X ; lasers_screen_address_high # Set to zero to remove laser &250a 9d 30 0a STA &0a30,X ; bombs_screen_address_high # Set to zero to remove bomb &250d ca DEX &250e 10 f7 BPL &2507 ; remove_lasers_and_bombs_loop &2510 a9 11 LDA #&11 &2512 8d 00 09 STA &0900 ; sound_block (channel) &2515 a9 00 LDA #&00 &2517 8d 01 09 STA &0901 ; sound_block + 1 (channel high) &251a a9 ff LDA #&ff &251c 8d 03 09 STA &0903 ; sound_block + 3 (volume high) &251f a9 f3 LDA #&f3 &2521 8d 02 09 STA &0902 ; sound_block + 2 (volume) &2524 a9 00 LDA #&00 &2526 8d 05 09 STA &0905 ; sound_block + 5 (pitch high) &2529 8d 07 09 STA &0907 ; sound_block + 7 (duration high) &252c a9 01 LDA #&01 &252e 8d 06 09 STA &0906 ; sound_block + 6 (duration) ; play_end_of_level_sound_loop &2531 a2 00 LDX #&00 &2533 a0 09 LDY #&09 &2535 ad 07 2f LDA &2f07 ; player_fuel &2538 8d 04 09 STA &0904 ; sound_block + 4 (pitch) &253b a9 07 LDA #&07 ; Generate a sound &253d 20 f1 ff JSR &fff1 ; OSWORD # Play sound for end of level on three channels &2540 ee 00 09 INC &0900 ; sound_block (channel) &2543 a2 00 LDX #&00 &2545 a0 09 LDY #&09 &2547 a9 07 LDA #&07 ; Generate a sound &2549 20 f1 ff JSR &fff1 ; OSWORD &254c ee 00 09 INC &0900 ; sound_block (channel) &254f a2 00 LDX #&00 &2551 a0 09 LDY #&09 &2553 a9 07 LDA #&07 ; Generate a sound &2555 20 f1 ff JSR &fff1 ; OSWORD &2558 ce 00 09 DEC &0900 ; sound_block (channel) &255b ce 00 09 DEC &0900 ; sound_block (channel) &255e 20 55 14 JSR &1455 ; wait_for_vsync &2561 a9 01 LDA #&01 &2563 20 dd 18 JSR &18dd ; add_to_fuel # Gain 1 fuel per frame at end of level &2566 ad 07 2f LDA &2f07 ; player_fuel &2569 c9 60 CMP #&60 &256b 90 c4 BCC &2531 ; play_end_of_level_sound_loop # Continue until all fuel regained &256d f8 SED &256e ad 33 2f LDA &2f33 ; level_as_bcd &2571 18 CLC &2572 69 01 ADC #&01 &2574 8d 33 2f STA &2f33 ; level_as_bcd &2577 d8 CLD &2578 ee 34 2f INC &2f34 ; level &257b ad 34 2f LDA &2f34 ; level &257e a0 18 LDY #&18 # On level 1, enemies have 24 energy &2580 c9 02 CMP #&02 &2582 90 14 BCC &2598 ; set_initial_enemy_energy &2584 a0 20 LDY #&20 # On level 2 and 3, enemies have 32 energy &2586 c9 04 CMP #&04 &2588 90 0e BCC &2598 ; set_initial_enemy_energy &258a a0 30 LDY #&30 # On level 4 to 7, enemies have 48 energy &258c c9 08 CMP #&08 &258e 90 08 BCC &2598 ; set_initial_enemy_energy &2590 a0 3c LDY #&3c # On level 8 to 12, enemies have 60 energy &2592 c9 0d CMP #&0d &2594 90 02 BCC &2598 ; set_initial_enemy_energy &2596 a0 4c LDY #&4c # On level 13 onwards, enemies have 76 energy ; set_initial_enemy_energy &2598 8c 0e 2f STY &2f0e ; initial_enemy_energy &259b a0 04 LDY #&04 # On level 1 and 2, fuelpods move every 4 updates &259d c9 03 CMP #&03 &259f 90 06 BCC &25a7 ; set_maximum_fuelpod_update_cooldown &25a1 88 DEY ; 3 # On level 3 and 4, fuelpods move every 3 updates &25a2 c9 05 CMP #&05 &25a4 90 01 BCC &25a7 ; set_maximum_fuelpod_update_cooldown &25a6 88 DEY ; 2 # On level 5 onwards, fuelpods move every 2 updates ; set_maximum_fuelpod_update_cooldown &25a7 8c 30 2f STY &2f30 ; maximum_fuelpod_update_cooldown &25aa a0 01 LDY #&01 # Level 1 has 1 wave &25ac c9 01 CMP #&01 &25ae f0 10 BEQ &25c0 ; set_waves_remaining &25b0 c8 INY ; 2 # Levels 2 to 5 have 2 waves &25b1 c9 06 CMP #&06 &25b3 90 0b BCC &25c0 ; set_waves_remaining &25b5 c8 INY ; 3 # Levels 6 to 10 have 3 waves &25b6 c9 0b CMP #&0b &25b8 90 06 BCC &25c0 ; set_waves_remaining &25ba c8 INY ; 4 # Levels 11 to 15 have 4 waves &25bb c9 10 CMP #&10 &25bd 90 01 BCC &25c0 ; set_waves_remaining &25bf c8 INY ; 5 # Level 16 and onwards have 5 waves ; set_waves_remaining &25c0 8c 32 2f STY &2f32 ; waves_remaining &25c3 0a ASL A &25c4 85 70 STA &70 ; level_times_two &25c6 a9 2c LDA #&2c # Player loses fuel every (44 - (level * 2)) updates &25c8 38 SEC &25c9 e5 70 SBC &70 ; level_times_two &25cb c9 14 CMP #&14 # reaching a limit of every 20 updates on level 13 &25cd b0 02 BCS &25d1 ; skip_floor &25cf a9 14 LDA #&14 ; skip_floor &25d1 8d 2e 2f STA &2f2e ; player_fuel_drain_cooldown &25d4 8d 2f 2f STA &2f2f ; maximum_player_fuel_drain_cooldown &25d7 ad 11 2f LDA &2f11 ; probability_of_enemy_attacking &25da 18 CLC &25db 69 04 ADC #&04 # Enemies attack with base probability (56 + (level *4)) / 128 &25dd c9 50 CMP #&50 &25df b0 03 BCS &25e4 ; skip_ceiling # reaching a limit of 76 / 128 on level 6 &25e1 8d 11 2f STA &2f11 ; probability_of_enemy_attacking ; skip_ceiling &25e4 a9 08 LDA #&08 &25e6 8d 00 2f STA &2f00 ; number_of_enemies &25e9 8d 01 2f STA &2f01 ; enemies_remaining &25ec 20 3b 15 JSR &153b ; initialise_enemies &25ef a9 00 LDA #&00 &25f1 8d 31 2f STA &2f31 ; enemies_and_fuelpods_need_initialising # Set to zero to indicate initialising needed &25f4 4c c6 24 JMP &24c6 ; start_new_level ; lose_life &25f7 20 dc 20 JSR &20dc ; explode_player &25fa f8 SED &25fb ad 03 2f LDA &2f03 ; player_lives &25fe 38 SEC &25ff e9 01 SBC #&01 &2601 8d 03 2f STA &2f03 ; player_lives &2604 d8 CLD &2605 f0 0b BEQ &2612 ; end_of_game &2607 a2 32 LDX #&32 ; delay_before_new_life_loop &2609 20 55 14 JSR &1455 ; wait_for_vsync &260c ca DEX &260d d0 fa BNE &2609 ; delay_before_new_life_loop &260f 4c c3 24 JMP &24c3 ; start_new_life ; end_of_game &2612 20 6e 24 JSR &246e ; plot_lives &2615 a2 32 LDX #&32 ; delay_at_end_of_game_loop &2617 20 55 14 JSR &1455 ; wait_for_vsync &261a ca DEX &261b d0 fa BNE &2617 ; delay_at_end_of_game_loop &261d a2 00 LDX #&00 ; Flush all buffers &261f a9 0f LDA #&0f ; Flush buffers &2621 20 f4 ff JSR &fff4 ; OSBYTE &2624 20 c7 0e JSR &0ec7 ; check_for_high_score ; escape_pressed_in_game &2627 20 28 0e JSR &0e28 ; high_score_screen &262a 4c c0 24 JMP &24c0 ; start_game_without_resetting_unused_variable ; initialise_game &262d a9 03 LDA #&03 # Player starts with three lives &262f 8d 03 2f STA &2f03 ; player_lives &2632 8d 30 2f STA &2f30 ; maximum_fuelpod_update_cooldown &2635 a9 00 LDA #&00 &2637 8d 04 2f STA &2f04 ; score &263a 8d 05 2f STA &2f05 ; score + 1 &263d 8d 06 2f STA &2f06 ; score + 2 &2640 a9 08 LDA #&08 &2642 8d 00 2f STA &2f00 ; number_of_enemies &2645 8d 01 2f STA &2f01 ; enemies_remaining &2648 a9 01 LDA #&01 &264a 8d 33 2f STA &2f33 ; level_as_bcd &264d 8d 34 2f STA &2f34 ; level &2650 a9 18 LDA #&18 &2652 8d 0e 2f STA &2f0e ; initial_enemy_energy &2655 a9 08 LDA #&08 # Regular enemies drop bombs 8 in 256 times &2657 8d 0f 2f STA &2f0f ; probability_of_regular_enemy_dropping_bomb &265a a9 14 LDA #&14 # Regular enemies drop bombs 20 in 256 times &265c 8d 10 2f STA &2f10 ; probability_of_fuelled_enemy_dropping_bomb &265f a9 38 LDA #&38 # Enemies attack with probability 56 / 256 on level 1 &2661 8d 11 2f STA &2f11 ; probability_of_enemy_attacking &2664 a9 2c LDA #&2c # Player loses fuel every 44 updates on level 1 &2666 8d 2e 2f STA &2f2e ; player_fuel_drain_cooldown &2669 8d 2f 2f STA &2f2f ; maximum_player_fuel_drain_cooldown &266c a9 04 LDA #&04 # Fuelpods move every 4 updates on level 1 &266e 8d 30 2f STA &2f30 ; maximum_fuelpod_update_cooldown &2671 a9 00 LDA #&00 &2673 8d 31 2f STA &2f31 ; enemies_and_fuelpods_need_initialising # Set to zero to indicate initialising needed &2676 a9 01 LDA #&01 &2678 8d 32 2f STA &2f32 ; waves_remaining ; initialise_enemies_initial_type &267b a2 07 LDX #&07 ; initialise_enemies_initial_type_loop &267d 8a TXA &267e 29 03 AND #&03 &2680 18 CLC &2681 69 01 ADC #&01 &2683 9d f8 27 STA &27f8,X ; enemies_initial_type &2686 ca DEX &2687 10 f4 BPL &267d ; initialise_enemies_initial_type_loop &2689 60 RTS ; initialise_game_screen &268a 20 1e 15 JSR &151e ; initialise_screen &268d 20 2f 17 JSR &172f ; draw_screen &2690 ad 31 2f LDA &2f31 ; enemies_and_fuelpods_need_initialising # Zero at start of level &2693 f0 06 BEQ &269b ; enemies_need_initialising &2695 20 b5 26 JSR &26b5 ; reset_attacking_enemies &2698 4c af 26 JMP &26af ; skip_initialising_enemies ; enemies_need_initialising &269b 20 8e 27 JSR &278e ; remove_enemies_and_falling_fuelpods &269e ad 00 2f LDA &2f00 ; number_of_enemies &26a1 48 PHA ; number_of_enemies &26a2 ad 01 2f LDA &2f01 ; enemies_remaining &26a5 8d 00 2f STA &2f00 ; number_of_enemies &26a8 20 3b 15 JSR &153b ; initialise_enemies &26ab 68 PLA ; number_of_enemies &26ac 8d 00 2f STA &2f00 ; number_of_enemies ; skip_initialising_enemies &26af 20 7e 15 JSR &157e ; initialise_bombs_and_lasers &26b2 4c 6e 24 JMP &246e ; plot_lives ; reset_attacking_enemies &26b5 a2 00 LDX #&00 &26b7 a0 07 LDY #&07 ; reset_attacking_enemies_loop &26b9 b9 30 09 LDA &0930,Y ; enemies_type # Top bit clear if enemy not attacking &26bc 29 7f AND #&7f &26be f0 08 BEQ &26c8 ; consider_next_enemy &26c0 c9 0f CMP #&0f ; ENEMY_ROCKET &26c2 f0 04 BEQ &26c8 ; consider_next_enemy &26c4 9d f8 27 STA &27f8,X ; enemies_initial_type # Reset attacking enemies to travelling state &26c7 e8 INX ; consider_next_enemy &26c8 88 DEY &26c9 10 ee BPL &26b9 ; reset_attacking_enemies_loop &26cb 8e 01 2f STX &2f01 ; enemies_remaining &26ce 20 8e 27 JSR &278e ; remove_enemies_and_falling_fuelpods &26d1 ad 00 2f LDA &2f00 ; number_of_enemies &26d4 48 PHA ; number_of_enemies &26d5 ad 01 2f LDA &2f01 ; enemies_remaining &26d8 8d 00 2f STA &2f00 ; number_of_enemies &26db 20 3b 15 JSR &153b ; initialise_enemies &26de 68 PLA ; number_of_enemies &26df 8d 00 2f STA &2f00 ; number_of_enemies &26e2 4c 7b 26 JMP &267b ; initialise_enemies_initial_type ; reset_fuelpods_and_plot_level_and_waves_remaining &26e5 a2 00 LDX #&00 &26e7 ad 31 2f LDA &2f31 ; enemies_and_fuelpods_need_initialising # Zero at start of level &26ea d0 32 BNE &271e ; consider_next_fuelpod &26ec ad 34 2f LDA &2f34 ; level &26ef c9 01 CMP #&01 &26f1 f0 2b BEQ &271e ; consider_next_fuelpod # Don't unplot fuelpods at start of game &26f3 a2 03 LDX #&03 ; unplot_fuelpods_loop &26f5 bd b0 09 LDA &09b0,X ; fuelpods_state &26f8 f0 24 BEQ &271e ; consider_next_fuelpod &26fa 86 80 STX &80 ; fuelpod_slot &26fc bd b4 09 LDA &09b4,X ; fuelpods_screen_address_low &26ff 85 70 STA &70 ; screen_address_low &2701 bd b8 09 LDA &09b8,X ; fuelpods_screen_address_high &2704 85 71 STA &71 ; screen_address_high &2706 bd bc 09 LDA &09bc,X ; fuelpods_sprite_address_low &2709 85 72 STA &72 ; sprite_address_low &270b bd c0 09 LDA &09c0,X ; fuelpods_sprite_address_high &270e 85 73 STA &73 ; sprite_address_high &2710 bd c4 09 LDA &09c4,X ; fuelpods_sprite_width &2713 85 74 STA &74 ; sprite_width &2715 a9 06 LDA #&06 &2717 85 75 STA &75 ; sprite_height &2719 20 ad 14 JSR &14ad ; plot_sprite # Unplot fuelpod &271c a6 80 LDX &80 ; fuelpod_slot ; consider_next_fuelpod &271e ca DEX &271f 10 d4 BPL &26f5 ; unplot_fuelpods_loop &2721 20 70 23 JSR &2370 ; initialise_fuelpods # Reset fuelpods to initial positions &2724 a9 01 LDA #&01 &2726 8d 31 2f STA &2f31 ; enemies_and_fuelpods_need_initialising # Set to non-zero to skip initialisation &2729 a2 45 LDX #&45 &272b a0 df LDY #&df &272d 20 60 14 JSR &1460 ; calculate_screen_address &2730 a2 00 LDX #&00 &2732 8e 2d 2f STX &2f2d ; leading_zeros # Set to zero to skip leading zeros &2735 ad 33 2f LDA &2f33 ; level_as_bcd &2738 20 1a 24 JSR &241a ; plot_two_digit_number # Plot level number &273b a2 4a LDX #&4a &273d a0 df LDY #&df &273f 20 60 14 JSR &1460 ; calculate_screen_address &2742 a2 00 LDX #&00 &2744 8e 2d 2f STX &2f2d ; leading_zeros # Set to zero to skip leading zeros &2747 ad 32 2f LDA &2f32 ; waves_remaining &274a 38 SEC &274b e9 01 SBC #&01 &274d 4c 1a 24 JMP &241a ; plot_two_digit_number # Plot waves remaining ; play_game ; main_game_loop &2750 20 55 14 JSR &1455 ; wait_for_vsync &2753 20 2d 18 JSR &182d ; update_player # Leave with non-zero if collision occurred &2756 f0 03 BEQ &275b ; no_collision &2758 a9 00 LDA #&00 # Leave with zero to kill player &275a 60 RTS ; no_collision &275b 20 bb 1c JSR &1cbb ; update_bombs &275e 20 2f 1d JSR &1d2f ; consider_firing &2761 20 f8 15 JSR &15f8 ; update_enemies &2764 20 0a 22 JSR &220a ; consider_updating_fuelpod &2767 20 ce 20 JSR &20ce ; update_exploding_fuelpods &276a 20 80 24 JSR &2480 ; consider_draining_player_fuel &276d ad 07 2f LDA &2f07 ; player_fuel &2770 d0 03 BNE &2775 ; not_out_of_fuel &2772 a9 00 LDA #&00 # Leave with zero to kill player &2774 60 RTS ; not_out_of_fuel &2775 ad 01 2f LDA &2f01 ; enemies_remaining &2778 d0 03 BNE &277d ; not_complete # Have all the enemies in this wave been destroyed? &277a a9 01 LDA #&01 # Leave with one to indicate level complete &277c 60 RTS ; not_complete &277d a9 8f LDA #&8f ; ESCAPE &277f 20 14 15 JSR &1514 ; check_for_keypress &2782 08 PHP ; escape pressed &2783 a9 7e LDA #&7e ; Acknowledge ESCAPE condition &2785 20 f4 ff JSR &fff4 ; OSBYTE &2788 28 PLP ; escape pressed &2789 f0 c5 BEQ &2750 ; main_game_loop &278b a9 02 LDA #&02 # Leave with two to indicate ESCAPE pressed &278d 60 RTS ; remove_enemies_and_falling_fuelpods &278e a2 0b LDX #&0b ; remove_enemies_loop &2790 a9 80 LDA #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &2792 9d 30 09 STA &0930,X ; enemies_type &2795 a9 00 LDA #&00 &2797 9d 48 09 STA &0948,X ; enemies_explosion_state # Set to zero to suppress explosion &279a ca DEX &279b 10 f3 BPL &2790 ; remove_enemies_loop &279d a2 03 LDX #&03 ; remove_falling_fuelpods_loop &279f bd b0 09 LDA &09b0,X ; fuelpods_state &27a2 c9 04 CMP #&04 ; FUELPOD_NO_TUGS &27a4 d0 05 BNE &27ab ; consider_next_fuelpod # Is the fuelpod falling? &27a6 a9 00 LDA #&00 ; FUELPOD_NONE &27a8 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod ; consider_next_fuelpod &27ab ca DEX &27ac 10 f1 BPL &279f ; remove_falling_fuel &27af 09 ca ORA #&ca # Unnecessary code; &27af - &27b2 is a copy of &27a8 - &27ae &27b1 10 f1 BPL &27a4 # Never branches &27b3 60 RTS ; unused_remove_enemies_and_falling_fuelpods # Unused code; &27b4 - &27d2 is a copy of &278e - &27ad &27b4 a2 0b LDX #&0b ; unused_remove_enemies_loop &27b6 a9 80 LDA #&80 ; ENEMY_ATTACKING | ENEMY_EXPLODING &27b8 9d 30 09 STA &0930,X ; enemies_type &27bb a9 00 LDA #&00 &27bd 9d 48 09 STA &0948,X ; enemies_explosion_state # Set to zero to suppress explosion &27c0 ca DEX &27c1 10 f3 BPL &27b6 ; unused_remove_enemies_loop &27c3 a2 03 LDX #&03 ; unused_remove_falling_fuelpods_loop &27c5 bd b0 09 LDA &09b0,X ; fuelpods_state &27c8 c9 04 CMP #&04 ; FUELPOD_NO_TUGS &27ca d0 05 BNE &27d1 ; unused_consider_next_fuelpod &27cc a9 00 LDA #&00 ; FUELPOD_NONE &27ce 9d b0 09 STA &09b0,X ; fuelpods_state # Set to zero to remove fuelpod ; unused_consider_next_fuelpod &27d1 ca DEX &27d2 10 f1 BPL &27c5 ; unused_remove_falling_fuelpods_loop &27d4 60 RTS ; unused # Source code fragment corresponding to &1439 - &1445 &27d5 3a 84 41 31 3a 84 41 32 3a 42 4e 45 20 52 41 4e ; ... : &27e5 5a 3a 49 4e 43 31 3a 2e 52 41 4e 5a 20 50 4c 41 ; ORA1: &27f5 3a 54 41 ; ORA2: ; BNE RANZ: ; INC1: ; .RANZ ; PLA: ; TA ; enemies_initial_type &27f8 58 3a 4c 44 41 30 3a 52 ; X: ; LDA0: ; R ... ; high_scores &2800 00 00 01 ; 10000 &2803 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &2812 00 90 00 ; 9000 &2815 4d 61 74 20 4e 65 77 6d 61 6e 00 00 00 00 00 ; "Mat Newman" &2824 00 80 00 ; 8000 &2827 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &2836 00 70 00 ; 7000 &2839 4d 61 74 20 4e 65 77 6d 61 6e 00 00 00 00 00 ; "Mat Newman" &2848 00 60 00 ; 6000 &284b 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &285a 00 50 00 ; 5000 &285d 4d 61 74 20 4e 65 77 6d 61 6e 00 00 00 00 00 ; "Mat Newman" &286c 00 40 00 ; 4000 &286f 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &287e 00 30 00 ; 3000 &2881 4d 61 74 20 4e 65 77 6d 61 6e 00 00 00 00 00 ; "Mat Newman" &2890 00 20 00 ; 2000 &2893 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &28a2 00 10 00 ; 1000 &28a5 4d 61 74 20 4e 65 77 6d 61 6e 00 00 00 00 00 ; "Mat Newman" ; unused &28b4 0d 60 00 &28b7 41 6d 63 6f 6d 00 00 00 00 00 00 00 00 00 00 ; "Amcom" &28c6 0d ; unused # Source code fragment corresponding to &1475 - 147d &28c7 52 4f 52 41 3a 53 54 41 26 37 30 0d ; ... RORA: ; STA&70 &28d3 00 aa 70 54 58 41 3a 41 53 4c 41 3a 41 53 4c 41 ; 170TXA: &28e3 3a 52 4f 4c 26 37 32 3a 41 53 4c 41 3a ; ASLA: ; ASLA: ; ROL&72: ; ASLA: ; fuelpod_state_x_offsets ; 0 1 2 3 ; LR L- -R -- tugs present &28f0 08 08 05 05 ; initial_fuelpod_sprite_addresses_low_table ; 0 1 2 3 ; LR L- -R -- tugs present &28f4 fe fe 10 10 ; initial_fuelpod_sprite_addresses_high_table ; 0 1 2 3 ; LR L- -R -- tugs present &28f8 2a 2a 2b 2b ; initial_fuelpod_sprite_widths_table ; 0 1 2 3 ; LR L- -R -- tugs present &28fc 0b 08 08 05 ; sound_data ; chan vol pitch dur &2900 12 00 01 00 4a 00 06 00 ; &00 # Firing laser &2908 13 00 02 00 1e 00 0a 00 ; &01 # Collecting fuel &2910 11 01 03 00 aa ff 08 00 ; &02 # Exploding enemy &2918 10 01 f3 ff 07 00 08 00 &2920 11 01 03 00 ff ff 2d 00 ; &04 # Exploding player &2928 10 01 f1 ff 07 00 2d 00 &2930 11 01 03 00 c8 ff 0c 00 ; &06 # Exploding fuelpod &2938 10 01 f1 ff 07 00 0c 00 &2940 10 00 f1 ff 05 00 01 00 ; &08 # Laser hitting enemy ; unused # Source code fragment corresponding to &1439 - &143c &2948 3a 84 41 31 3a 84 41 32 ; (unused) ; :ORA1:ORA2 ; sound_data + &50 ; chan vol pitch dur &2950 12 00 04 00 14 00 0c 00 ; &0a # Extra life ; unused # Source code fragment corresponding to &1498 - &14be &2958 54 4e 41 44 4c 2c 58 3a 53 54 41 26 37 32 0d ; ... TNADL,X: ; STA&72 &2967 00 be 46 4c 44 41 20 50 41 54 4e 41 44 48 2c 58 ; 190LDA PATNADH,X: &2977 3a 53 54 41 26 37 33 3a 4c 44 41 20 50 41 54 4e ; STA&73: &2987 57 54 48 2c 58 3a 53 54 41 26 37 34 3a 4c 44 41 ; LDA PATNWTH,X: &2997 20 50 41 54 4e 48 49 54 2c 58 3a 53 54 41 26 37 ; STA&74: &29a7 35 3a 52 54 53 0d ; LDA PATNHIT,X: ; STA&75: ; RTS &29ad 00 c8 5e 2e 50 4c 54 20 4c 44 41 26 37 31 3a 42 ; 200.PLT &29bd 4e 45 20 50 4c 54 4f 4b 3a 52 54 53 3a 2e 50 4c ; LDA&71: &29cd 54 4f 4b 20 4c 44 59 23 30 3a 53 54 59 26 37 38 ; BNE PLTOK: &29dd 3a 2e 4c 4f 4e 4c 50 20 4c 44 41 26 37 31 3a 50 ; RTS: &29ed 48 41 3a 4c 44 41 26 37 30 3a 50 48 41 3a 80 23 ; .PLTOK &29fd 37 3a 53 ; LDY#0: ; STY&78: ; .LONLP ; LDA&71: ; PHA: ; LDA&70: ; PHA: ; AND#7: ; S ... ; digit_sprites &2a00 3f 2a 2a 2a 2a 2a 3f 00 2a 2a 2a 2a 2a 2a 2a 00 ; "0" &2a10 15 3f 15 15 15 15 3f 00 00 00 00 00 00 00 2a 00 ; "1" &2a20 3f 2a 00 3f 2a 2a 3f 00 2a 2a 2a 2a 00 2a 2a 00 ; "2" &2a30 3f 2a 00 15 00 2a 3f 00 2a 2a 2a 2a 2a 2a 2a 00 ; "3" &2a40 2a 2a 2a 3f 00 00 00 00 00 2a 2a 2a 2a 2a 2a 00 ; "4" &2a50 3f 2a 2a 3f 00 2a 3f 00 2a 2a 00 2a 2a 2a 2a 00 ; "5" &2a60 3f 2a 2a 3f 2a 2a 3f 00 2a 2a 00 2a 2a 2a 2a 00 ; "6" &2a70 3f 2a 00 15 00 00 00 00 2a 2a 2a 2a 2a 2a 2a 00 ; "7" &2a80 3f 2a 2a 3f 2a 2a 3f 00 2a 2a 2a 2a 2a 2a 2a 00 ; "8" &2a90 3f 2a 2a 3f 00 2a 3f 00 2a 2a 2a 2a 2a 2a 2a 00 ; "9" ; unused # Source code fragment corresponding to &141e - &142c &2aa0 4d 50 20 4f 53 57 4c 4f 4f 50 0d ; ... MP OSWLOOP &2aab 00 78 0f 2e 4f 53 57 45 4e 44 20 52 54 53 0d ; 120.OSWEND ; RTS &2aba 00 82 29 2e 52 41 4e 44 20 54 58 41 3a 50 48 41 ; 130.RAND &2aca 3a 4c 44 58 23 38 3a 2e 52 41 4e 4c 50 20 4c 44 ; TXA: &2ada 41 30 3a 80 23 26 34 38 0d ; PHA: ; LDX#8: ; .RANLP ; LDA0: ; AND#&48 &2ae3 00 8c 24 41 44 43 23 26 33 38 3a 41 53 ; 140ADC#&38: ; AS ... ; unused &2af0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; sprite_fuel &2afe 00 04 09 09 04 00 00 0c 09 09 0c 00 00 00 0d 0d &2b0e 00 00 00 00 1e 1e 00 00 14 3c 3c 3c 3c 14 3c 30 &2b1e 34 30 34 3c 28 3c 3c 3c 3c 28 00 00 2d 2d 00 00 &2b2e 00 00 0e 0e 00 00 00 0c 06 06 0c 00 00 08 06 06 &2b3e 08 00 ; sprite_0f (SPRITE_EXPLOSION_FRAGMENT) &2b40 55 55 ff 55 00 aa 00 00 ; sprite_0e (SPRITE_ENEMY_ROCKET_FUELLED) &2b48 00 00 00 05 14 1e 1e 1e 0a 0a 0a 2d 16 16 16 16 &2b58 00 00 00 00 00 0a 0a 0a ; sprite_0d (SPRITE_ENEMY_ROCKET_UNFUELLED) &2b60 00 00 00 05 14 1e 1e 1e 0a 0a 0a 2d 14 14 14 14 &2b70 00 00 00 00 00 0a 0a 0a ; sprite_0b (SPRITE_LASER_GUIDE_RIGHT) &2b78 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ; sprite_0a (SPRITE_LASER_GAUGE_MIDDLE) &2b82 3f 03 03 03 03 03 03 03 03 3f ; ground_string &2b8c 19 04 30 00 74 00 ; MOVE &0030, &0074 # Draw ground &2b92 19 05 c0 04 74 00 ; DRAW &04c0, &0074 &2b98 fe ; end of string ; sprite_0c (SPRITE_PLAYER) &2b99 00 00 00 00 00 00 04 18 09 04 00 00 00 01 01 09 &2ba9 30 12 0f 00 00 00 00 00 00 11 23 12 24 08 05 05 &2bb9 05 1c 23 16 2c 08 00 00 00 00 00 08 22 13 29 18 &2bc9 04 00 00 00 00 01 01 01 32 12 25 08 00 00 00 00 &2bd9 00 08 24 12 0b 04 00 00 00 00 00 00 00 08 08 00 ; unused &2be9 fe ; sprite_04 (SPRITE_FUEL_GAUGE) &2bea 15 15 15 15 15 3f 3f 15 3f 03 03 03 03 03 03 3f &2bfa 3f 03 03 03 03 03 03 3f 2a 2a 2a 2a 2a 3f 3f 2a ; sprite_05 (SPRITE_PILLAR) &2c0a 05 03 04 04 33 14 14 03 03 10 0f 03 0c 0c 33 3c &2c1a 3c 03 03 30 00 02 00 00 22 00 00 02 02 00 ; sprite_06 (SPRITE_FUEL_LINE_VERTICAL_LEFT) &2c28 88 82 80 88 82 80 88 82 80 88 82 80 88 82 80 88 &2c38 82 80 88 82 c4 ; sprite_07 (SPRITE_FUEL_LINE_HORIZONTAL) &2c3d c2 c9 c4 c2 c9 ; sprite_08 (SPRITE_FUEL_LINE_VERTICAL_RIGHT) &2c42 82 88 80 82 88 80 82 88 80 82 88 80 82 88 80 82 &2c52 88 80 82 88 80 ; sprite_09 (SPRITE_LASER_GAUGE_LEFT) &2c57 15 15 15 15 15 15 15 15 15 15 ; unused &2c61 3f 03 03 03 03 ; sprite_03 (SPRITE_ENEMY_WHITE) &2c66 15 15 00 00 15 15 2e 15 00 00 2a 3f 19 19 17 2a &2c76 00 00 15 3f 26 26 2b 15 2a 2a 00 00 2a 2a 1d 2a ; sprite_02 (SPRITE_ENEMY_GREEN) &2c86 08 05 00 04 0c 04 00 04 04 05 0f 04 0c 0c 0c 04 &2c96 00 05 0a 04 0c 0c 08 04 08 00 00 00 08 00 00 00 ; sprite_01 (SPRITE_ENEMY_RED) &2ca6 17 00 00 01 02 02 02 01 02 01 07 1e 1e 05 00 00 &2cb6 01 02 0b 2d 2d 0a 00 00 2b 00 00 02 01 01 01 02 ; sprite_00 (SPRITE_ENEMY_CYAN) &2cc6 00 05 00 00 14 14 29 14 3c 14 14 3c 16 16 29 3c &2cd6 28 05 00 28 16 16 29 3c 00 00 00 00 00 00 28 00 ; enemy_types_pixel_value ; 1 2 3 4 ; C R G W &2ce6 14 01 04 15 ; initialise_game_screen_string &2cea 16 02 ; MODE 2 &2cec 12 00 03 ; GCOL 0, 3 &2cef 19 04 38 01 e8 03 ; MOVE &0138, &03e8 # Draw outside of hiway &2cf5 19 05 d8 01 e8 03 ; DRAW &01d8, &03e8 &2cfb 19 05 d8 01 98 03 ; DRAW &01d8, &0398 &2d01 19 05 18 03 98 03 ; DRAW &0318, &0398 &2d07 19 05 18 03 e8 03 ; DRAW &0318, &03e8 &2d0d 19 05 b8 03 e8 03 ; DRAW &03b8, &03e8 &2d13 19 05 b8 03 48 03 ; DRAW &03b8, &0348 &2d19 19 05 38 03 48 03 ; DRAW &0338, &0348 &2d1f 19 05 38 03 20 03 ; DRAW &0338, &0320 &2d25 19 05 b8 01 20 03 ; DRAW &01b8, &0320 &2d2b 19 05 b8 01 48 03 ; DRAW &01b8, &0348 &2d31 19 05 38 01 48 03 ; DRAW &0138, &0348 &2d37 19 05 38 01 e8 03 ; DRAW &0138, &03e8 &2d3d 19 04 48 01 dc 03 ; MOVE &0148, &03dc # Draw inside of hiway &2d43 19 05 c8 01 dc 03 ; DRAW &01c8, &03dc &2d49 19 05 c8 01 8c 03 ; DRAW &01c8, &038c &2d4f 19 05 28 03 8c 03 ; DRAW &0328, &038c &2d55 19 05 28 03 dc 03 ; DRAW &0328, &03dc &2d5b 19 05 a8 03 dc 03 ; DRAW &03a8, &03dc &2d61 19 05 a8 03 54 03 ; DRAW &03a8, &0354 &2d67 19 05 28 03 54 03 ; DRAW &0328, &0354 &2d6d 19 05 28 03 2c 03 ; DRAW &0328, &032c &2d73 19 05 c8 01 2c 03 ; DRAW &01c8, &032c &2d79 19 05 c8 01 54 03 ; DRAW &01c8, &0354 &2d7f 19 05 48 01 54 03 ; DRAW &0148, &0354 &2d85 19 05 48 01 dc 03 ; DRAW &0148, &03dc &2d8b 12 00 04 ; GCOL 0, 4 &2d8e 19 04 d8 01 2c 03 ; MOVE &01d8, &032c # Draw blue line on hiway &2d94 19 05 18 03 2c 03 ; DRAW &0318, &032c &2d9a 12 00 04 ; GCOL 0, 4 &2d9d 19 04 f8 ff 00 03 ; MOVE &fff8, &0300 # Draw blue line on screen &2da3 19 05 f0 04 00 03 ; DRAW &04f0, &0300 &2da9 19 04 f8 ff 04 03 ; MOVE &fff8, &0304 &2daf 19 05 f0 04 04 03 ; DRAW &04f0, &0304 &2db5 19 04 f8 ff 08 03 ; MOVE &fff8, &0308 &2dbb 19 05 f0 04 08 03 ; DRAW &04f0, &0308 &2dc1 12 00 00 ; GCOL 0, 0 &2dc4 19 04 d8 01 20 03 ; MOVE &01d8, &0320 # Remove bottom opening on hiway &2dca 19 05 18 03 20 03 ; DRAW &0318, &0320 &2dd0 12 00 05 ; GCOL 0, 5 &2dd3 19 04 e8 01 20 03 ; MOVE &01e8, &0320 # Draw magenta lines on hiway &2dd9 19 05 08 02 20 03 ; DRAW &0208, &0320 &2ddf 19 04 28 02 20 03 ; MOVE &0228, &0320 &2de5 19 05 48 02 20 03 ; DRAW &0248, &0320 &2deb 19 04 68 02 20 03 ; MOVE &0268, &0320 &2df1 19 05 88 02 20 03 ; DRAW &0288, &0320 &2df7 19 04 a8 02 20 03 ; MOVE &02a8, &0320 &2dfd 19 05 c8 02 20 03 ; DRAW &02c8, &0320 &2e03 19 04 e8 02 20 03 ; MOVE &02e8, &0320 &2e09 19 05 08 03 20 03 ; DRAW &0308, &0320 &2e0f 19 04 38 00 d0 02 ; MOVE &0038, &02d0 # Draw magenta lines on screen &2e15 19 05 b0 00 d0 02 ; DRAW &00b0, &02d0 &2e1b 19 04 30 01 d0 02 ; MOVE &0130, &02d0 &2e21 19 05 b0 01 d0 02 ; DRAW &01b0, &02d0 &2e27 19 04 30 02 d0 02 ; MOVE &0230, &02d0 &2e2d 19 05 b0 02 d0 02 ; DRAW &02b0, &02d0 &2e33 19 04 30 03 d0 02 ; MOVE &0330, &02d0 &2e39 19 05 b0 03 d0 02 ; DRAW &03b0, &02d0 &2e3f 19 04 30 04 d0 02 ; MOVE &0430, &02d0 &2e45 19 05 b0 04 d0 02 ; DRAW &04b0, &02d0 &2e4b 19 04 38 00 d4 02 ; MOVE &0038, &02d4 &2e51 19 05 b0 00 d4 02 ; DRAW &00b0, &02d4 &2e57 19 04 30 01 d4 02 ; MOVE &0130, &02d4 &2e5d 19 05 b0 01 d4 02 ; DRAW &01b0, &02d4 &2e63 19 04 30 02 d4 02 ; MOVE &0230, &02d4 &2e69 19 05 b0 02 d4 02 ; DRAW &02b0, &02d4 &2e6f 19 04 30 03 d4 02 ; MOVE &0330, &02d4 &2e75 19 05 b0 03 d4 02 ; DRAW &03b0, &02d4 &2e7b 19 04 30 04 d4 02 ; MOVE &0430, &02d4 &2e81 19 05 b0 04 d4 02 ; DRAW &04b0, &02d4 &2e87 19 04 38 00 cc 02 ; MOVE &0038, &02cc &2e8d 19 05 b0 00 cc 02 ; DRAW &00b0, &02cc &2e93 19 04 30 01 cc 02 ; MOVE &0130, &02cc &2e99 19 05 b0 01 cc 02 ; DRAW &01b0, &02cc &2e9f 19 04 30 02 cc 02 ; MOVE &0230, &02cc &2ea5 19 05 b0 02 cc 02 ; DRAW &02b0, &02cc &2eab 19 04 30 03 cc 02 ; MOVE &0330, &02cc &2eb1 19 05 b0 03 cc 02 ; DRAW &03b0, &02cc &2eb7 19 04 30 04 cc 02 ; MOVE &0430, &02cc &2ebd 19 05 b0 04 cc 02 ; DRAW &04b0, &02cc &2ec3 fe ; end of string ; hiway_sections_start_x # 667 9aa ; 0 1 2 3 4 5 6 7 8 9 a b # 5 788889 b &2ec4 3b 33 33 1c 1c 14 14 1d 1d 32 32 3b # 5 b # 44 00 ; hiway_sections_start_y # 32222221 ; 0 1 2 3 4 5 6 7 8 9 a b &2ed0 d3 d3 c9 c9 d3 d3 f8 f8 e4 e4 f8 f8 ; hiway_sections_direction_x ; 0 1 2 3 4 5 6 7 8 9 a b &2edc ff 00 ff 00 ff 00 01 00 01 00 01 00 ; hiway_sections_direction_y ; 0 1 2 3 4 5 6 7 8 9 a b &2ee8 00 ff 00 01 00 01 00 ff 00 01 00 ff ; hiway_sections_length ; 0 1 2 3 4 5 6 7 8 9 a b &2ef4 20 0a 5c 0a 20 25 24 14 54 14 24 25 ; number_of_enemies &2f00 0c ; enemies_remaining &2f01 09 ; player_x &2f02 37 ; player_lives &2f03 00 ; score &2f04 44 c9 c9 ; player_fuel &2f07 2f ; player_fuel_x &2f08 25 ; player_fuel_y &2f09 08 ; player_laser_energy &2f0a 02 ; laser_gauge_screen_address_low &2f0b d0 ; laser_gauge_screen_address_high &2f0c 78 ; fuel_line_colour &2f0d 90 ; initial_enemy_energy &2f0e 30 ; probability_of_regular_enemy_dropping_bomb &2f0f 07 ; probability_of_fuelled_enemy_dropping_bomb &2f10 10 ; probability_of_enemy_attacking &2f11 28 ; player_can_fire &2f12 ff ; explosion_x_deltas &2f13 02 01 00 ff fe ff 00 01 ; explosion_y_deltas &2f1b 00 03 04 03 00 fd fc fd ; explosion_colours ; W M Y R G R Y M &2f23 f7 f5 f3 f1 f2 f1 f3 f5 # Set colour 15 ; explosion_colour_offset &2f2b 56 ; unused &2f2c fc ; leading_zeros &2f2d cc ; player_fuel_drain_cooldown &2f2e 88 ; maximum_player_fuel_drain_cooldown &2f2f 28 ; maximum_fuelpod_update_cooldown &2f30 a2 ; enemies_and_fuelpods_need_initialising &2f31 a2 ; waves_remaining &2f32 a2 ; level_as_bcd &2f33 00 ; level &2f34 00 ; unused_variable &2f35 88 d8 e4 ; enemy_types_score_high ; hiway screen ; C R G W C R G W &2f38 01 01 01 01 02 01 02 03 ; enemy_types_score_low ; hiway screen ; C R G W C R G W &2f40 00 00 00 00 00 50 50 00 ; unused &2f48 88 88 00 00 00 00 00 00 a2 a2 a2 00 00 00 00 41 &2f58 c3 c3 c3 c3 c3 c3 41 51 41 c3 c3 41 00 41 00 41 &2f68 e3 e3 e3 e3 e3 41 41 00 00 82 82 00 c3 c3 e9 c3 &2f78 c7 cf cf da da da da c3 ; string_addresses_low_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2f80 ea 8c c3 41 82 c3 a8 c3 e1 e1 e1 e1 e1 e1 c3 82 # Only &00 and &01 are used ; string_addresses_high_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2f90 2c 2b 82 00 00 00 00 41 e3 e3 e3 e3 e3 41 41 51 # Only &00 and &01 are used ; sprite_addresses_low_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2fa0 c6 a6 86 66 ea 0a 28 3d 42 57 82 78 99 60 48 40 ; &00 # Only &00 - &0f are used &2fb0 00 82 82 00 44 cc c9 c9 ; &10 ; sprite_addresses_high_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2fb8 2c 2c 2c 2c 2b 2c 2c 2c 2c 2c 2b 2b 2b 2b 2b 2b ; &00 # Only &00 - &0f are used &2fc8 00 01 01 07 03 17 01 00 ; &10 ; sprite_widths_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2fd0 04 04 04 04 04 03 01 05 01 01 01 01 08 03 03 02 ; &00 # Only &00 - &0f are used &2fe0 03 03 3f 03 00 02 2b 0f ; &10 ; sprite_heights_table ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &2fe8 08 08 08 08 08 0a 15 01 15 0a 0a 0a 0a 08 08 04 ; &00 # Only &00 - &0f are used &2ff8 05 00 03 3f 0b 2f 02 00 ; &10 # &3000 - &31ff is moved to &0e00 - &0fff at &3202 ; write_number &0e00 48 PHA &0e01 4a LSR A &0e02 4a LSR A &0e03 4a LSR A &0e04 4a LSR A &0e05 aa TAX &0e06 05 73 ORA &73 ; leading_zeros &0e08 85 73 STA &73 ; leading_zeros &0e0a d0 02 BNE &0e0e ; not_leading_zero &0e0c a2 f0 LDX #&f0 ; " " - "0" ; not_leading_zero &0e0e 8a TXA &0e0f 18 CLC &0e10 69 30 ADC #&30 ; "0" &0e12 20 ee ff JSR &ffee ; OSWRCH &0e15 68 PLA &0e16 29 0f AND #&0f &0e18 aa TAX &0e19 05 73 ORA &73 ; leading_zeros &0e1b 85 73 STA &73 ; leading_zeros &0e1d d0 02 BNE &0e21 ; not_leading_zero &0e1f a2 f0 LDX #&f0 ; " " - "0" ; not_leading_zero &0e21 8a TXA &0e22 18 CLC &0e23 69 30 ADC #&30 ; "0" &0e25 4c ee ff JMP &ffee ; OSWRCH ; high_score_screen &0e28 a2 69 LDX #&69 &0e2a a0 00 LDY #&00 ; write_high_score_screen_loop &0e2c b9 00 10 LDA &1000,Y ; high_score_screen_string &0e2f 20 e3 ff JSR &ffe3 ; OSASCI # Display high score screen &0e32 c8 INY &0e33 ca DEX &0e34 d0 f6 BNE &0e2c ; write_high_score_screen_loop &0e36 a9 0b LDA #&0b ; R11: Cursor end register &0e38 8d 00 fe STA &fe00 ; video register number &0e3b a9 00 LDA #&00 # Disable cursor &0e3d 8d 01 fe STA &fe01 ; video register value &0e40 a9 00 LDA #&00 &0e42 85 70 STA &70 ; high_score_address_low &0e44 a9 28 LDA #&28 ; &2800 = high_scores &0e46 85 71 STA &71 ; high_score_address_high &0e48 a9 01 LDA #&01 &0e4a 85 72 STA &72 ; rank ; write_high_scores_rank_loop # For each rank, &0e4c a9 1f LDA #&1f # TAB(&05, (rank * 2) + 1) &0e4e 20 ee ff JSR &ffee ; OSWRCH &0e51 a9 05 LDA #&05 &0e53 20 ee ff JSR &ffee ; OSWRCH &0e56 a5 72 LDA &72 ; rank &0e58 0a ASL A &0e59 69 01 ADC #&01 &0e5b 20 ee ff JSR &ffee ; OSWRCH &0e5e a5 72 LDA &72 ; rank &0e60 c9 0a CMP #&0a &0e62 90 12 BCC &0e76 ; not_rank_ten &0e64 a9 08 LDA #&08 ; BACKSPACE # Write "10" &0e66 20 ee ff JSR &ffee ; OSWRCH &0e69 a9 31 LDA #&31 ; "1" &0e6b 20 ee ff JSR &ffee ; OSWRCH &0e6e a9 30 LDA #&30 ; "0" &0e70 20 ee ff JSR &ffee ; OSWRCH &0e73 4c 7b 0e JMP &0e7b ; write_dots ; not_rank_ten &0e76 69 30 ADC #&30 ; "0" &0e78 20 ee ff JSR &ffee ; OSWRCH # Write rank ; write_dots &0e7b a2 03 LDX #&03 &0e7d a9 2e LDA #&2e ; "." ; write_dots_loop &0e7f 20 ee ff JSR &ffee ; OSWRCH # Write "..." &0e82 ca DEX &0e83 d0 fa BNE &0e7f ; write_dots_loop &0e85 a0 03 LDY #&03 ; write_name_loop &0e87 b1 70 LDA (&70),Y ; high_score_address &0e89 d0 02 BNE &0e8d ; not_null &0e8b a9 20 LDA #&20 ; not_null &0e8d 20 ee ff JSR &ffee ; OSWRCH # Write name &0e90 c8 INY &0e91 c0 12 CPY #&12 &0e93 90 f2 BCC &0e87 ; write_name_loop &0e95 a2 03 LDX #&03 &0e97 a9 2e LDA #&2e ; "." ; write_following_dots_loop &0e99 20 ee ff JSR &ffee ; OSWRCH # Write "..." &0e9c ca DEX &0e9d d0 fa BNE &0e99 ; write_following_dots_loop &0e9f a9 00 LDA #&00 &0ea1 85 73 STA &73 ; leading_zeros # Set to zero to skip leading zeros &0ea3 a0 02 LDY #&02 ; write_score_loop &0ea5 b1 70 LDA (&70),Y ; high_score_address &0ea7 20 00 0e JSR &0e00 ; write_number # Write score &0eaa 88 DEY &0eab 10 f8 BPL &0ea5 ; write_score_loop &0ead e6 72 INC &72 ; rank &0eaf a5 70 LDA &70 ; high_score_address_low &0eb1 18 CLC &0eb2 69 12 ADC #&12 &0eb4 85 70 STA &70 ; high_score_address_low &0eb6 c9 a3 CMP #&a3 ; 9 * &12 + 1 &0eb8 90 92 BCC &0e4c ; write_high_scores_rank_loop ; wait_for_space &0eba a9 7e LDA #&7e ; Acknowledge ESCAPE condition &0ebc 20 f4 ff JSR &fff4 ; OSBYTE &0ebf 20 e0 ff JSR &ffe0 ; OSRDCH &0ec2 c9 20 CMP #&20 ; " " &0ec4 d0 f4 BNE &0eba ; wait_for_space &0ec6 60 RTS ; check_for_high_score &0ec7 a9 00 LDA #&00 &0ec9 85 70 STA &70 ; high_score_address_low &0ecb a9 28 LDA #&28 ; &2800 = high_scores &0ecd 85 71 STA &71 ; high_score_address_high &0ecf a2 01 LDX #&01 ; check_for_high_score_rank_loop &0ed1 a0 02 LDY #&02 ; check_for_high_score_byte_loop &0ed3 b9 04 2f LDA &2f04,Y ; score &0ed6 d1 70 CMP (&70),Y ; high_score_address &0ed8 90 08 BCC &0ee2 ; consider_next_rank &0eda d0 13 BNE &0eef ; new_high_score &0edc 88 DEY &0edd 10 f4 BPL &0ed3 ; check_for_high_score_byte_loop &0edf 4c ef 0e JMP &0eef ; new_high_score ; consider_next_rank &0ee2 e8 INX &0ee3 a5 70 LDA &70 ; high_score_address_low &0ee5 18 CLC &0ee6 69 12 ADC #&12 &0ee8 85 70 STA &70 ; high_score_address_low &0eea c9 a3 CMP #&a3 ; 9 * &12 + 1 &0eec 90 e3 BCC &0ed1 ; check_for_high_score_rank_loop &0eee 60 RTS ; new_high_score &0eef 86 88 STX &88 ; player_rank &0ef1 e0 0a CPX #&0a &0ef3 f0 2d BEQ &0f22 ; skip_shuffling_scores &0ef5 a9 a2 LDA #&a2 ; &28a2 = high_scores + 9 * &12 &0ef7 85 72 STA &72 ; target_address_low &0ef9 a9 28 LDA #&28 &0efb 85 73 STA &73 ; target_address_high &0efd 85 75 STA &75 ; source_address_high &0eff a9 90 LDA #&90 ; &2890 = high_scores + 8 * &12 &0f01 85 74 STA &74 ; source_address_low ; shuffle_scores_rank_loop &0f03 a0 00 LDY #&00 ; shuffle_scores_byte_loop &0f05 b1 74 LDA (&74),Y ; source_address_high &0f07 91 72 STA (&72),Y ; target_address_high &0f09 c8 INY &0f0a c0 12 CPY #&12 &0f0c 90 f7 BCC &0f05 ; shuffle_scores_byte_loop &0f0e a5 72 LDA &72 ; target_address_low &0f10 38 SEC &0f11 e9 12 SBC #&12 &0f13 85 72 STA &72 ; target_address_low &0f15 a5 74 LDA &74 ; source_address_low &0f17 38 SEC &0f18 e9 12 SBC #&12 &0f1a 85 74 STA &74 ; source_address_low &0f1c 90 04 BCC &0f22 ; skip_shuffling_scores &0f1e c5 70 CMP &70 ; high_score_address_low &0f20 b0 e1 BCS &0f03 ; shuffle_scores_rank_loop ; skip_shuffling_scores &0f22 a0 00 LDY #&00 &0f24 a2 9c LDX #&9c ; write_congratulations_loop &0f26 b9 69 10 LDA &1069,Y ; congratulations_string # Display congratulations screen &0f29 20 e3 ff JSR &ffe3 ; OSASCI &0f2c c8 INY &0f2d ca DEX &0f2e d0 f6 BNE &0f26 ; write_congratulations_loop &0f30 a0 02 LDY #&02 ; copy_score_into_high_scores_loop &0f32 b9 04 2f LDA &2f04,Y ; score &0f35 91 70 STA (&70),Y ; high_score_address &0f37 88 DEY &0f38 10 f8 BPL &0f32 ; copy_score_into_high_scores_loop &0f3a a9 00 LDA #&00 &0f3c 85 80 STA &80 ; input_block &0f3e a9 09 LDA #&09 ; &0900 = name_buffer &0f40 85 81 STA &81 ; input_block + 1 &0f42 a9 0f LDA #&0f ; 15 characters maximum &0f44 85 82 STA &82 ; input_block + 2 &0f46 a9 20 LDA #&20 ; " " &0f48 85 83 STA &83 ; input_block + 3 &0f4a a9 7f LDA #&7f ; DELETE &0f4c 85 84 STA &84 ; input_block + 4 &0f4e a9 04 LDA #&04 ; Define action of cursor editing keys &0f50 a2 01 LDX #&01 ; Cursor keys return ASCII values 135-139 &0f52 20 f4 ff JSR &fff4 ; OSBYTE &0f55 a2 80 LDX #&80 &0f57 a0 00 LDY #&00 &0f59 98 TYA ; 0 ; Input line &0f5a 20 f1 ff JSR &fff1 ; OSWORD # Get name into name_buffer &0f5d 90 34 BCC &0f93 ; escape_not_pressed &0f5f a9 41 LDA #&41 ; "A" # Use "Amcom(!)" if ESCAPE pressed &0f61 8d 00 09 STA &0900 ; name_buffer &0f64 a9 6d LDA #&6d ; "m" &0f66 8d 01 09 STA &0901 ; name_buffer + 1 &0f69 a9 63 LDA #&63 ; "c" &0f6b 8d 02 09 STA &0902 ; name_buffer + 2 &0f6e a9 6f LDA #&6f ; "o" &0f70 8d 03 09 STA &0903 ; name_buffer + 3 &0f73 a9 6d LDA #&6d ; "m" &0f75 8d 04 09 STA &0904 ; name_buffer + 4 &0f78 a9 28 LDA #&28 ; "(" &0f7a 8d 05 09 STA &0905 ; name_buffer + 5 &0f7d a9 21 LDA #&21 ; "!" &0f7f 8d 06 09 STA &0906 ; name_buffer + 6 &0f82 a9 29 LDA #&29 ; ")" &0f84 8d 07 09 STA &0907 ; name_buffer + 7 &0f87 a9 0d LDA #&0d ; CR &0f89 8d 08 09 STA &0908 ; name_buffer + 8 &0f8c a9 7e LDA #&7e ; Acknowledge ESCAPE condition &0f8e 20 f4 ff JSR &fff4 ; OSBYTE &0f91 a0 08 LDY #&08 ; escape_not_pressed &0f93 a9 00 LDA #&00 ; wipe_unused_part_of_input_block_loop &0f95 99 00 09 STA &0900,Y ; input_block &0f98 c8 INY &0f99 c0 0f CPY #&0f &0f9b 90 f8 BCC &0f95 ; wipe_unused_part_of_input_block_loop &0f9d a0 03 LDY #&03 ; copy_name_into_high_scores_loop &0f9f b9 fd 08 LDA &08fd,Y ; input_block - 3 &0fa2 91 70 STA (&70),Y ; high_score_address &0fa4 c8 INY &0fa5 c0 12 CPY #&12 &0fa7 d0 f6 BNE &0f9f ; copy_name_into_high_scores_loop &0fa9 60 RTS ; unused &0faa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fba 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fca 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fda 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0fea 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ffa 00 00 00 00 00 ; entry_point &31ff 58 CLI &3200 a0 00 LDY #&00 ; move_memory_loop &3202 b9 00 30 LDA &3000,Y # Move &3000 - &31ff to &0e00 - &0fff &3205 99 00 0e STA &0e00,Y &3208 b9 00 31 LDA &3100,Y &320b 99 00 0f STA &0f00,Y &320e b9 00 33 LDA &3300,Y # Move &3300 - &34ff to &1000 - &11ff &3211 99 00 10 STA &1000,Y &3214 b9 00 34 LDA &3400,Y &3217 99 00 11 STA &1100,Y &321a 88 DEY &321b d0 e5 BNE &3202 ; move_memory_loop &321d 4c 00 14 JMP &1400 ; entry_point_after_relocation ; unused &3220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &32f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &3300 - &34ff is moved to &1000 - &11ff at &3202 ; high_score_screen_string &1000 16 07 ; MODE 7 &1002 81 9d 84 8d ; RED, NEW_BACKGROUND, BLUE, DOUBLE_HEIGHT &1006 0d &1007 81 9d 84 8d ; RED, NEW_BACKGROUND, BLUE, DOUBLE_HEIGHT &100b 1f 08 00 ; TAB(&08, &00) &100e 53 50 41 43 45 20 48 49 2d 57 41 59 20 48 41 4c ; "SPACE HI-WAY HALL OF FAME" &101e 4c 20 4f 46 20 46 41 4d 45 &1027 1f 08 01 ; TAB(&08, &01) &102a 53 50 41 43 45 20 48 49 2d 57 41 59 20 48 41 4c ; "SPACE HI-WAY HALL OF FAME" &103a 4c 20 4f 46 20 46 41 4d 45 &1043 1f 03 18 ; TAB(&03, &18) &1046 50 72 65 73 73 20 74 68 65 20 73 70 61 63 65 20 ; "Press the space bar for a new game." &1056 62 61 72 20 66 6f 72 20 61 20 6e 65 77 20 67 61 &1066 6d 65 2e ; congratulations_string &1069 16 07 ; MODE 7 &106b 1f 07 05 ; TAB(&07, &05) &106e 82 9d 81 8d ; GREEN, NEW_BACKGROUND, RED, DOUBLE_HEIGHT &1072 43 6f 6e 67 72 61 74 75 6c 61 74 69 6f 6e 73 21 ; "Congratulations!!! " &1082 21 21 20 20 20 &1087 9c ; BLACK_BACKGROUND &1088 1f 07 06 ; TAB(&07, &06) &108b 82 9d 81 8d ; GREEN, NEW_BACKGROUND, RED, DOUBLE_HEIGHT &108f 43 6f 6e 67 72 61 74 75 6c 61 74 69 6f 6e 73 21 ; "Congratulations!!! " &109f 21 21 20 20 20 &10a4 9c ; BLACK_BACKGROUND &10a5 1f 03 0a ; TAB(&03, &0a) &10a8 59 6f 75 72 20 73 63 6f 72 65 20 69 73 20 69 6e ; "Your score is in the Hall Of Fame!" &10b8 20 74 68 65 20 48 61 6c 6c 20 4f 66 20 46 61 6d &10c8 65 21 &10ca 1f 04 0c ; TAB(&04, &0c) &10cd 50 6c 65 61 73 65 20 74 79 70 65 20 79 6f 75 72 ; "Please type your name,then press" &10dd 20 6e 61 6d 65 2c 74 68 65 6e 20 70 72 65 73 73 &10ed 1f 11 0e ; TAB(&11, &0e) &10f0 52 45 54 55 52 4e 2e ; "RETURN." &10f7 1f 09 12 ; TAB(&09, &12) &10fa 84 9d 86 ; BLUE, NEW_BACKGROUND, CYAN &10fd 1f 1d 12 ; TAB(&1d, &12) &1100 9c ; BLACK_BACKGROUND &1101 1f 0c 12 ; TAB(&0c, &12) &1104 00 ; unused &1105 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1115 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1135 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1145 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1155 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1165 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1175 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1185 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1195 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11a5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11b5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11c5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11d5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11e5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &11f5 00 00 00 00 00 00 00 00 00 00 00