Fortress disassembly ==================== Fortress was written by Mat Newman, and was published by PACE for the BBC Micro in 1983. It is an unofficial conversion of Sega's 1982 arcade game, Zaxxon. 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. Technical notes =============== Two BASIC loaders run the main binary, which loads further code from a stream. The first BASIC loader, FORTRESS, sets up a break handler which is called when the second BASIC loader, FORTRESS1, ends with a Bad Program error. FORTRESS1 uses embedded backspace characters in a REM statement as misdirection. If key codes are poked into zero page, the main binary can be *RUN separately. The diagonal scrolling is achieved by setting the scan lines per character register (R9) to display only four rows per group. Half the screen memory is therefore unused. The game uses part of this memory to store other data. A side effect of this is that the 6845 CRTC no longer refreshes all 128 rows of the machine's DRAM. To prevent values in the undisplayed half from decaying, a NOP cascade is called from an interrupt handler, which refreshes the other rows. Static sprites are plotted to one of two buffers. When the screen is scrolled, a vertical buffer is copied to the right of the screen, and a horizontal buffer is copied to the top of the screen. In this analysis, the vertical buffer will be referred to as the foreground, and the horizontal buffer as the background. The coordinate systems are as follows: world screen foreground background y+ x- z+ y+ y- | \ / | | | x x- --x-- x+ x x+ --x-- x- | / \ | | y- z- x+ y- y+ Interesting pokes ================= &2c55 = &a5 infinite lives &29b3 = &ad infinite fuel &2044 = &60 invulnerability &0efe = &07 display hidden rows Loader analysis =============== ; FORTRESS ; 00001500 00008023 047E &1500 0d # Start of BASIC program &1501 00 0a 0d 50 3d 31 32 3a 41 3d 31 33 0d ; 10P=12:A=13 &150e 00 14 19 eb 37 3a 3f 26 46 45 30 30 3d 31 31 3a ; 20MODE7: &151e 3f 26 46 45 30 31 3d 30 0d ; ?&FE00=11:?&FE01=0 # Disable cursor &1527 00 1e 15 f1 27 89 28 50 2b 41 29 3b bd 26 39 37 ; 30PRINT'SPC(P+A);CHR$&97;"p" &1537 3b 22 70 22 0d &153c 00 28 1c f1 89 28 50 29 3b bd 26 39 37 3b c4 31 ; 40PRINTSPC(P);CHR$&97;STRING$(13,"|");"~}" &154c 33 2c 22 7c 22 29 3b 22 7e 7d 22 0d &1558 00 32 1e f1 89 28 50 29 3b bd 26 39 37 3b bd 32 ; 50PRINTSPC(P);CHR$&97;CHR$255;SPC(12);".!" &1568 35 35 3b 89 28 31 32 29 3b 22 2e 21 22 0d &1576 00 3c 24 f1 89 28 50 29 3b bd 26 39 37 3b bd 32 ; 60PRINTSPC(P);CHR$&97;CHR$255;" 7i 8)0_&` 7`!" &1586 35 35 3b 22 91 37 69 20 38 29 30 5f 26 60 20 37 ; &1596 60 21 22 0d &159a 00 46 23 f1 89 28 50 29 3b bd 26 39 37 3b bd 32 ; 70PRINTSPC(P);CHR$&97;CHR$255;" =& =,5j =$" &15aa 35 35 3b 22 92 3d 26 20 3d 2c 35 6a 20 20 20 3d ; &15ba 24 22 0d &15bd 00 50 25 f1 89 28 50 29 3b bd 26 39 37 3b bd 32 ; 80PRINTSPC(P);CHR$&97;CHR$255;" 5 5 5""dp up0" &15cd 35 35 3b 22 93 35 20 20 35 20 35 22 22 64 70 20 ; &15dd 75 70 30 22 0d &15e2 00 5a 20 f1 89 28 50 29 3b bd 26 39 37 3b bd 32 ; 90PRINTSPC(P);CHR$&97;CHR$255;STRING$(13,"p");"0" &15f2 35 35 3b c4 31 33 2c 22 70 22 29 3b 22 30 22 0d ; &1602 00 64 1b f1 89 28 50 29 3b bd 26 39 37 3b c4 31 ; 100PRINTSPC(P);CHR$&97;STRING$(14,"`");"!" &1612 34 2c 22 60 22 29 3b 22 21 22 0d &161d 00 6e 1b f1 27 89 28 36 29 3b 22 82 42 72 69 6e ; 110PRINT'SPC(6);" Brings you..." &162d 67 73 20 79 6f 75 2e 2e 2e 22 0d &1638 00 78 17 f1 89 28 31 38 29 3b 22 8d 86 46 6f 72 ; 120PRINTSPC(18);" Fortress" &1648 74 72 65 73 73 22 0d &164f 00 82 17 f1 89 28 31 38 29 3b 22 8d 86 46 6f 72 ; 130PRINTSPC(18);" Fortress" &165f 74 72 65 73 73 22 0d &1666 00 8c 13 f1 89 28 32 37 29 3b 22 82 62 79 2e 2e ; 140PRINTSPC(27);" by..." &1676 2e 22 0d &1679 00 96 11 f1 27 27 89 28 41 29 3b 22 91 5f 6e 22 ; 150PRINT''SPC(A);" _n" &1689 0d &168a 00 a0 1b f1 89 28 41 29 3b 22 95 3a 6a 68 6b 69 ; 160PRINTSPC(A);" :jhki8`!h`ihki" &169a 38 60 21 68 60 69 68 6b 69 22 0d &16a5 00 aa 1b f1 89 28 41 29 3b 22 92 75 72 6a 6a 6a ; 170PRINTSPC(A);" urjjjeppzp:jjj" &16b5 65 70 70 7a 70 3a 6a 6a 6a 22 0d &16c0 00 b4 14 f1 89 28 41 2b 39 29 3b 22 96 70 70 70 ; 180PRINTSPC(A+9);" pppp:" &16d0 70 3a 22 0d &16d4 00 be 14 f1 89 28 41 2b 39 29 3b 22 93 70 70 70 ; 190PRINTSPC(A+9);" ppppp" &16e4 70 70 22 0d &16e8 00 c8 14 f1 89 28 41 2b 39 29 3b 22 97 70 70 70 ; 200PRINTSPC(A+9);" ppppp" &16f8 70 70 22 0d &16fc 00 d2 1d e3 59 3d 30 b8 32 34 3a ef 33 31 2c 30 ; 210FORY=0TO24 &170c 2c 59 2c 26 38 34 2c 31 35 37 3a ed 0d ; VDU31,0,Y,&84,157: # TAB(0, Y), BLUE, NEW_BACKGROUND ; NEXT &1719 00 dc 1c 3f 26 37 30 3d 26 37 34 3a 3f 26 37 31 ; 220?&70=&74: # unrelocated_break_handler_address_low &1729 3d 28 90 20 81 32 35 36 29 2b 34 0d ; ?&71=(PAGE DIV256)+4 # unrelocated_break_handler_address_high &1735 00 e6 2a e2 31 2c 35 2c 2d 31 2c 30 2c 30 2c 32 ; 230ENVELOPE1,5,-1,0,0,255,0,0,127,0,0,-5,127,127 &1745 35 35 2c 30 2c 30 2c 31 32 37 2c 30 2c 30 2c 2d ; &1755 35 2c 31 32 37 2c 31 32 37 0d &175f 00 f0 11 d4 26 31 31 2c 31 2c 32 30 30 2c 33 30 ; 240SOUND&11,1,200,30 &176f 0d &1770 00 fa 11 d4 26 31 32 2c 31 2c 31 39 38 2c 33 30 ; 250SOUND&12,1,198,30 &1780 0d &1781 01 04 11 d4 26 31 33 2c 31 2c 31 39 36 2c 33 30 ; 260SOUND&13,1,196,30 &1791 0d &1792 01 0e 0f d1 3d 30 3a f5 fd 91 3e 32 35 30 0d ; 270TIME=0:REPEATUNTILTIME>250 &17a1 01 18 27 e2 32 2c 33 2c 2d 35 2c 2d 32 2c 2d 31 ; 280ENVELOPE2,3,-5,-2,-1,10,15,255,0,0,0,0,0,0 &17b1 2c 31 30 2c 31 35 2c 32 35 35 2c 30 2c 30 2c 30 ; &17c1 2c 30 2c 30 2c 30 0d &17c8 01 22 12 d4 26 31 31 2c 32 2c 32 35 30 2c 32 35 ; 290SOUND&11,2,250,255 &17d8 35 0d &17da 01 2c 11 d4 26 31 30 2c 2d 31 35 2c 37 2c 34 30 ; 300SOUND&10,-15,7,40 &17ea 0d &17eb 01 36 0f d1 3d 30 3a f5 fd 91 3e 34 30 30 0d ; 310TIME=0:REPEATUNTILTIME>400 &17fa 01 40 1d ef 32 38 2c 30 2c 32 34 2c 33 39 2c 32 ; 320VDU28,0,24,39,22,12: # Define text window &180a 32 2c 31 32 3a 2a 46 58 31 35 20 30 0d ; *FX15 0 # Flush buffers &1817 01 4a 1f d6 28 90 2b 26 34 34 36 29 3a 2a 4c 2e ; 330CALL(PAGE+&446): # Call initialise_break_handler &1827 46 4f 52 54 52 45 53 53 31 20 36 38 30 30 0d ; *L.FORTRESS1 6800 &1836 01 54 0d d0 3d 26 36 38 30 30 3a f9 0d ; 340PAGE=&6800:RUN # Run FORTRESS1 &1843 ff # End of BASIC program ; unused &1844 00 0a 00 14 00 1e 00 28 00 32 00 3c 00 46 00 50 &1854 00 5a 00 64 00 6e 00 78 00 82 00 8c 00 96 00 a0 &1864 00 aa 00 b4 00 be 00 c8 00 d2 03 e8 03 f2 03 fc &1874 04 06 04 10 04 1a 04 24 04 2e 04 38 04 42 04 4c &1884 04 56 04 60 ff 30 30 3a f9 0d ff 90 8c 00 96 00 &1894 a0 00 aa 00 b4 00 be 00 c8 00 d2 00 dc 00 e6 00 &18a4 f0 00 fa 01 04 01 0e 01 0e 01 18 01 22 01 2c 01 &18b4 36 01 40 01 4a 01 54 01 5e 01 68 01 72 01 7c 00 &18c4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &18d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &18e4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &18f4 00 00 00 00 00 00 00 00 00 00 00 00 36 00 00 00 &1904 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1914 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1924 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1934 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &1944 00 00 ; initialise_break_handler &1946 a9 61 LDA #&61 ; &6100 &1948 8d 03 02 STA &0203 ; brk_vector_high &194b a0 00 LDY #&00 &194d 8c 02 02 STY &0202 ; brk_vector_low &1950 a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect &1952 a2 02 LDX #&02 ; memory cleared on next reset &1954 20 f4 ff JSR &fff4 ; OSBYTE &1957 a9 f7 LDA #&f7 ; Read/Write BREAK interceptor jump instruction &1959 a0 ff LDY #&ff &195b a2 00 LDX #&00 ; clear break interceptor &195d 20 f4 ff JSR &fff4 ; OSBYTE &1960 a9 e5 LDA #&e5 ; Read/Write ESCAPE key status &1962 a2 0d LDX #&0d ; ESCAPE inserts ASCII value &1964 a0 ff LDY #&ff &1966 20 f4 ff JSR &fff4 ; OSBYTE &1969 a0 13 LDY #&13 ; copy_break_handler_loop &196b b1 70 LDA (&70),Y ; unrelocated_break_handler_address &196d 99 00 61 STA &6100,Y ; break_handler &1970 88 DEY &1971 10 f8 BPL &126b ; copy_break_handler_loop &1973 60 RTS ; unrelocated_break_handler &1974 a9 04 LDA #&04 ; *RUN &1976 a2 09 LDX #&09 ; &6109 = run_string &1978 a0 61 LDY #&61 &197a 6c 1e 02 JMP (&021e) ; file_system_control_vector ; unrelocated_run_string &197d 0d ; FORTRESS1 ; 00001500 00007824 1048 &6800 0d # Start of BASIC program &6801 00 0a 35 ee 85 e7 9f 3c 3e 31 37 f1 22 4f 53 20 ; 10ONERROR &6811 31 2e 30 20 6f 72 20 61 62 6f 76 65 20 72 65 71 ; IFERR<>17 # If not Escape error, &6821 75 69 72 65 64 2e 22 3a f5 fd 30 20 8b d8 3a e5 ; PRINT"OS 1.0 or above required.": &6831 8d 54 68 40 0d ; REPEATUNTIL0: ; ELSE ; CLEAR: ; GOTO40 &6836 00 14 0c 2a 46 58 32 32 39 20 31 0d ; 20*FX229 1 # ESCAPE inserts ASCII value &6842 00 1e 98 e3 46 25 3d 26 37 30 b8 26 38 46 3a 3f ; 30FORF%=&70TO&8F: &6852 46 25 3d 28 46 25 83 26 34 38 29 2b 26 31 37 3a ; ?F%=(F%MOD&48)+&17: # Unused &6862 ed 3a 3f 26 35 30 3d 46 25 2a 28 3f 26 32 44 44 ; NEXT; &6872 2b 3f 26 33 42 41 29 3a e7 28 28 3f 26 32 35 38 ; ?&50=F%*(?&2DD+?&3BA): # Unused &6882 20 82 20 3f 26 32 37 33 29 80 28 3f 26 32 37 33 ; IF((?&258 EOR ?&273) # &0258 = os_escape_break_effect &6892 20 80 20 3f 26 32 35 38 29 29 3d 30 20 41 25 3d ; AND(?&273 AND ?&258))=0 # &0273 = os_ctrl_function_key_status &68a2 26 43 38 3a 58 25 3d 32 3a 59 25 3d 30 3a d6 26 ; A%=&C8:X%=2:Y%=0: # Clear memory on break, disable ESCAPE &68b2 46 46 46 34 20 8b 20 41 25 3d 26 43 38 3a 58 25 ; CALL&FFF4 &68c2 3d 33 3a 59 25 3d 30 3a d6 26 46 46 46 34 3a 3f ; ELSE &68d2 26 37 33 3d 26 34 31 0d ; A%=&C8:X%=3:Y%=0: # Clear memory on break, normal ESCAPE ; CALL&FFF4: ; ?&73=&41 # Unused &68da 00 28 26 4b 31 3d 26 34 31 3a 4b 32 3d 26 36 31 ; 40K1=&41: # Default keycodes: A &68ea 3a 4b 33 3d 26 36 36 3a 4b 34 3d 26 36 37 3a 4b ; K2=&61: # Z &68fa 35 3d 26 36 32 0d ; K3=&66: # , ; K4=&67: # . ; K5=&62 # SPACE &6900 00 32 33 4b 31 24 3d 22 41 22 3a 4b 32 24 3d 22 ; 50K1$="A": # Default keys &6910 5a 22 3a 4b 33 24 3d 22 2c 22 3a 4b 34 24 3d 22 ; K2$="Z": &6920 2e 22 3a 4b 35 24 3d 22 53 50 41 43 45 20 42 41 ; K3$=",": &6930 52 22 0d ; K4$=".": ; K5$="SPACE BAR" &6933 00 3c 0d 4f 3d 35 3a 2a 46 58 31 35 0d ; 60O=5: ; *FX15 # Flush buffers &6940 00 46 16 eb 37 3a ef 32 33 3b 31 31 3b 30 3b 30 ; 70MODE7: &6950 3b 30 3b 3a f1 0d ; VDU23;11;0;0;0; # Disable cursor ; PRINT &6956 00 50 0a 2a 46 58 30 20 31 0d ; 80*FX0 1 # Return host/OS in X &6960 00 5a 37 ef 26 38 33 2c 31 35 37 2c 31 34 31 3a ; 90VDU&83,157,141:PRINT" PACE brings you - Amcom's Fortress" &6970 f1 22 82 50 41 43 45 20 62 72 69 6e 67 73 20 79 &6980 6f 75 20 2d 20 41 6d 63 6f 6d 27 73 84 46 6f 72 &6990 74 72 65 73 73 22 0d &6997 00 64 37 ef 26 38 33 2c 31 35 37 2c 31 34 31 3a ; 100VDU&83,157,141:RINT" PACE brings you - Amcom's Fortress" &69a7 f1 22 82 50 41 43 45 20 62 72 69 6e 67 73 20 79 &69b7 6f 75 20 2d 20 41 6d 63 6f 6d 27 73 84 46 6f 72 &69c7 74 72 65 73 73 22 0d &69ce 00 6e 11 ef 32 38 2c 30 2c 32 34 2c 33 39 2c 33 ; 110VDU28,0,24,39,3 # Define text window &69de 0d &69df 00 78 0d f2 43 3a f2 49 4e 53 54 31 0d ; 120PROCC: # Clear screen ; PROCINST1 # Write instructions &69ec 00 82 2d f1 8a 4f 2d 31 29 bd 31 34 31 3b bd 26 ; 130PRINTTAB(O-1)CHR$141;CHR$&86;CHR$157;CHR$&84;"Keys... ";CHR$156 &69fc 38 36 3b bd 31 35 37 3b bd 26 38 34 3b 22 4b 65 &6a0c 79 73 2e 2e 2e 20 22 3b bd 31 35 36 0d &6a19 00 8c 2d f1 8a 4f 2d 31 29 bd 31 34 31 3b bd 26 ; 140PRINTTAB(O-1)CHR$141;CHR$&86;CHR$157;CHR$&84;"Keys... ";CHR$156 &6a29 38 36 3b bd 31 35 37 3b bd 26 38 34 3b 22 4b 65 &6a39 79 73 2e 2e 2e 20 22 3b bd 31 35 36 0d &6a46 00 96 32 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 150PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(12+O)"Up - ";K1$;TAB(35);CHR$156 &6a56 3b bd 26 38 37 3b 8a 31 32 2b 4f 29 22 55 70 20 &6a66 2d 20 22 3b 4b 31 24 3b 8a 33 35 29 3b bd 31 35 &6a76 36 0d &6a78 00 a0 34 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 160PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(10+O)"Down - ";K2$;TAB(35);CHR$156 &6a88 3b bd 26 38 37 3b 8a 31 30 2b 4f 29 22 44 6f 77 &6a98 6e 20 2d 20 22 3b 4b 32 24 3b 8a 33 35 29 3b bd &6aa8 31 35 36 0d &6aac 00 aa 34 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 170PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(10+O)"Left - ";K3$;TAB(35);CHR$156 &6abc 3b bd 26 38 37 3b 8a 31 30 2b 4f 29 22 4c 65 66 &6acc 74 20 2d 20 22 3b 4b 33 24 3b 8a 33 35 29 3b bd &6adc 31 35 36 0d &6ae0 00 b4 34 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 180PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(9+O)"Right - ";K4$;TAB(35);CHR$156 &6af0 3b bd 26 38 37 3b 8a 39 2b 4f 29 22 52 69 67 68 &6b00 74 20 2d 20 22 3b 4b 34 24 3b 8a 33 35 29 3b bd &6b10 31 35 36 0d &6b14 00 be 34 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 190PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(10+O)"Fire - ";K5$;TAB(35);CHR$156 &6b24 3b bd 26 38 37 3b 8a 31 30 2b 4f 29 22 46 69 72 &6b34 65 20 2d 20 22 3b 4b 35 24 3b 8a 33 35 29 3b bd &6b44 31 35 36 0d &6b48 00 c8 20 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 200PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(35);CHR$156 &6b58 3b bd 26 38 37 3b 8a 33 35 29 3b bd 31 35 36 0d &6b68 00 d2 36 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 210PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(9+O)" Quit - ESCAPE";TAB(35);CHR$156 &6b78 3b bd 26 38 37 3b 8a 39 2b 4f 29 22 83 51 75 69 &6b88 74 20 2d 20 45 53 43 41 50 45 22 3b 8a 33 35 29 &6b98 3b bd 31 35 36 0d &6b9e 00 dc 33 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 220PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(7+O)" Freeze - F";TAB(35);CHR$156 &6bae 3b bd 26 38 37 3b 8a 37 2b 4f 29 22 83 46 72 65 &6bbe 65 7a 65 20 2d 20 46 22 3b 8a 33 35 29 3b bd 31 &6bce 35 36 0d &6bd1 00 e6 34 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 230PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(6+O)" Restart - R";TAB(35);CHR$156 &6be1 3b bd 26 38 37 3b 8a 36 2b 4f 29 22 83 52 65 73 &6bf1 74 61 72 74 20 2d 20 52 22 3b 8a 33 35 29 3b bd &6c01 31 35 36 0d &6c05 00 f0 20 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 240PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(35);CHR$156 &6c15 3b bd 26 38 37 3b 8a 33 35 29 3b bd 31 35 36 0d &6c25 00 fa 30 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 250PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(5+O)" Sound :";TAB(35);CHR$156 &6c35 3b bd 26 38 37 3b 8a 35 2b 4f 29 22 86 53 6f 75 &6c45 6e 64 20 3a 22 3b 8a 33 35 29 3b bd 31 35 36 0d &6c55 01 04 30 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 260PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(11+O)" on - S";TAB(35);CHR$156 &6c65 3b bd 26 38 37 3b 8a 31 31 2b 4f 29 22 86 6f 6e &6c75 20 2d 20 53 22 3b 8a 33 35 29 3b bd 31 35 36 0d &6c85 01 0e 31 f1 8a 35 29 bd 26 38 34 3b bd 31 35 37 ; 270PRINTTAB(5)CHR$&84;CHR$157;CHR$&87;TAB(10+O)" off - Q";TAB(35);CHR$156 &6c95 3b bd 26 38 37 3b 8a 31 30 2b 4f 29 22 86 6f 66 &6ca5 66 20 2d 20 51 22 3b 8a 33 35 29 3b bd 31 35 36 &6cb5 0d &6cb6 01 18 2a f1 27 8a 4f 29 22 83 50 72 65 73 73 20 ; 280PRINT'TAB(O)" Press the SPACE bar or (FIRE)"; &6cc6 74 68 65 86 53 50 41 43 45 83 62 61 72 20 6f 72 &6cd6 86 28 46 49 52 45 29 22 3b 0d &6ce0 01 22 28 f1 8a 4f 2b 31 29 22 83 6f 6e 20 6a 6f ; 290PRINTTAB(O+1)" on joystick #1 to continue." &6cf0 79 73 74 69 63 6b 20 23 31 20 74 6f 20 63 6f 6e &6d00 74 69 6e 75 65 2e 22 0d &6d08 01 2c 30 f1 8a 4f 2b 31 29 22 88 50 72 65 73 73 ; 300PRINTTAB(O+1)" Press C to change controls.": &6d18 20 43 20 74 6f 20 63 68 61 6e 67 65 20 63 6f 6e ; *FX15 0 # Flush buffers &6d28 74 72 6f 6c 73 2e 22 3a 2a 46 58 31 35 20 30 0d &6d38 01 36 4f 41 25 3d 30 3a 42 25 3d 30 3a d1 3d 30 ; 310A%=0: # Input method &6d48 3a f5 3a 49 3d a6 28 30 29 3a e7 49 3d 33 32 8c ; B%=0: # Non-zero if SPACE, C or fire pressed &6d58 20 42 25 3d 31 8b e7 96 28 30 29 80 31 8c 41 25 ; TIME=0: &6d68 3d 31 3a 42 25 3d 31 8b e7 28 49 20 80 26 44 46 ; REPEAT: &6d78 29 3d 36 37 8c 42 25 3d 31 3a 41 25 3d 32 0d ; I=INKEY(0): ; IFI=32THEN B%=1 ; ELSEIFADVAL(0)AND1THENA%=1:B%=1 ; ELSEIF(I AND&DF)=67THENB%=1:A%=2 &6d87 01 40 39 fd 28 42 25 3d 31 29 84 28 91 3e 36 30 ; 320UNTIL(B%=1)OR(TIME>6000): &6d97 30 30 29 3a e7 42 25 3d 30 e5 8d 44 78 40 8b e7 ; IFB%=0 &6da7 41 25 3c 32 20 3f 26 37 30 3d 41 25 20 8b 20 f2 ; GOTO120 &6db7 43 43 3a e5 8d 74 42 40 0d ; ELSEIFA%<2 ; ?&70=A% # loader_keyboard_or_joystick ; ELSE ; PROCCC: # Set keys ; GOTO130 &6dc0 01 4a 2b 3f 26 38 30 3d 4b 31 3a 3f 26 38 31 3d ; 330?&80=K1: # loader_keys &6dd0 4b 32 3a 3f 26 38 32 3d 4b 33 3a 3f 26 38 33 3d ; ?&81=K2: # loader_keys + 1 &6de0 4b 34 3a 3f 26 38 34 3d 4b 35 0d ; ?&82=K3: # loader_keys + 2 ; ?&83=K4: # loader_keys + 3 ; ?&84=K5 # loader_keys + 4 &6deb 01 54 2b ef 32 38 2c 30 2c 32 33 2c 33 39 2c 32 ; 340VDU28,0,23,39,21: # Define text window &6dfb 31 3a db 3a f1 22 86 53 74 61 72 74 20 74 61 70 ; CLS: &6e0b 65 20 70 6c 61 79 65 72 2e 22 0d ; PRINT" Start tape player." &6e16 01 5e 10 ee 85 87 3a 2a 46 58 32 32 39 20 30 0d ; 350ONERROROFF: ; *FX229 0 # ESCAPE causes escape condition &6e26 01 68 34 f4 7f 7f 7f 15 21 26 32 44 44 3d 26 36 ; 360REM... # Embedded backspaces hide REM &6e36 30 35 39 33 34 33 33 3a 43 41 2e 21 26 32 31 45 ; !&2DD=&60593433: # &02dd = os_buffer_start_indices + 5 &6e46 20 41 4e 44 20 26 46 46 46 46 3a 43 41 2e 26 31 ; CA.!&21E AND &FFFF: # Would call filing system control vector &6e56 39 37 35 0d ; CA.&1975 # Misdirection &6e5a 01 72 25 53 6e 61 70 20 73 6e 61 70 20 2c 20 49 ; 370Snap snap , I've finally cracked. &6e6a 27 76 65 20 66 69 6e 61 6c 6c 79 20 63 72 61 63 # Error causes bad program, &6e7a 6b 65 64 2e 0d # triggering break_handler &6e7f 01 7c 14 dd f2 49 4e 53 54 31 3a ef 33 31 2c 30 ; 380DEFPROCINST1: &6e8f 2c 32 31 0d ; VDU31,0,21 # TAB(&00, &15) &6e93 01 86 2c f1 22 83 59 6f 75 20 6d 75 73 74 20 70 ; 390PRINT" You must pilot your starfighter over" &6ea3 69 6c 6f 74 20 79 6f 75 72 20 73 74 61 72 66 69 &6eb3 67 68 74 65 72 20 6f 76 65 72 22 0d &6ebf 01 90 2b f1 22 83 74 68 65 20 65 6e 65 6d 79 20 ; 400PRINT" the enemy defences, and destroy the" &6ecf 64 65 66 65 6e 63 65 73 2c 20 61 6e 64 20 64 65 &6edf 73 74 72 6f 79 20 74 68 65 22 0d &6eea 01 9a 28 f1 22 83 65 6e 65 6d 79 20 48 51 20 77 ; 410PRINT" enemy HQ with four direct hits."' &6efa 69 74 68 20 66 6f 75 72 20 64 69 72 65 63 74 20 &6f0a 68 69 74 73 2e 22 27 0d &6f12 01 a4 2b f1 22 81 47 75 6e 20 74 75 72 72 65 74 ; 420PRINT" Gun turrets will fire at you if you" &6f22 73 20 77 69 6c 6c 20 66 69 72 65 20 61 74 20 79 &6f32 6f 75 20 69 66 20 79 6f 75 22 0d &6f3d 01 ae 2a f1 22 81 67 65 74 20 69 6e 20 6c 69 6e ; 430PRINT" get in line with them, as will the" &6f4d 65 20 77 69 74 68 20 74 68 65 6d 2c 20 61 73 20 &6f5d 77 69 6c 6c 20 74 68 65 22 0d &6f67 01 b8 2a f1 22 81 65 6e 65 6d 79 20 70 6c 61 6e ; 440PRINT" enemy planes. The planes will also" &6f77 65 73 2e 20 54 68 65 20 70 6c 61 6e 65 73 20 77 &6f87 69 6c 6c 20 61 6c 73 6f 22 0d &6f91 01 c2 17 f1 22 81 68 6f 6d 65 20 69 6e 20 6f 6e ; 450PRINT" home in on you." &6fa1 20 79 6f 75 2e 22 0d &6fa8 01 cc 2c f1 27 22 82 59 6f 75 20 6d 75 73 74 20 ; 460PRINT'" You must replenish your fuel supply" &6fb8 72 65 70 6c 65 6e 69 73 68 20 79 6f 75 72 20 66 &6fc8 75 65 6c 20 73 75 70 70 6c 79 22 0d &6fd4 01 d6 29 f1 22 82 62 79 20 64 65 73 74 72 6f 79 ; 470PRINT" by destroying enemy fuel barrels." &6fe4 69 6e 67 20 65 6e 65 6d 79 20 66 75 65 6c 20 62 &6ff4 61 72 72 65 6c 73 2e 22 0d &6ffd 01 e0 31 f1 27 22 86 59 6f 75 72 20 74 61 73 6b ; 480PRINT'" Your task will not be easy, as you will"; &700d 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20 65 61 73 &701d 79 2c 20 61 73 20 79 6f 75 20 77 69 6c 6c 22 3b &702d 0d &702e 01 ea 2d f1 22 86 68 61 76 65 20 74 6f 20 61 76 ; 490PRINT" have to avoid rockets, negotiate over" &703e 6f 69 64 20 72 6f 63 6b 65 74 73 2c 20 6e 65 67 &704e 6f 74 69 61 74 65 20 6f 76 65 72 22 0d &705b 01 f4 26 f1 22 86 77 61 6c 6c 73 2c 20 61 6e 64 ; 500PRINT" walls, and under force fields," &706b 20 75 6e 64 65 72 20 66 6f 72 63 65 20 66 69 65 &707b 6c 64 73 2c 22 0d &7081 01 fe 1e f1 22 86 62 75 74 20 61 6c 77 61 79 73 ; 510PRINT" but always remember..." &7091 20 72 65 6d 65 6d 62 65 72 2e 2e 2e 22 0d &709f 02 08 28 f1 27 bd 31 34 31 2b bd 31 33 36 3b 89 ; 520PRINT'CHR$141+CHR$136;SPC(O+5);"IT IS POSSIBLE!" &70af 28 4f 2b 35 29 3b 22 49 54 20 49 53 20 50 4f 53 &70bf 53 49 42 4c 45 21 22 0d &70c7 02 12 27 f1 bd 31 34 31 2b bd 31 33 36 3b 89 28 ; 530PRINTCHR$141+CHR$136;SPC(O+5);"IT IS POSSIBLE!" &70d7 4f 2b 35 29 3b 22 49 54 20 49 53 20 50 4f 53 53 &70e7 49 42 4c 45 21 22 0d &70ee 02 1c 2a f1 27 8a 4f 29 22 83 50 72 65 73 73 20 ; 540PRINT'TAB(O)" Press the SPACE bar or (FIRE)"; &70fe 74 68 65 86 53 50 41 43 45 83 62 61 72 20 6f 72 &710e 86 28 46 49 52 45 29 22 3b 0d &7118 02 26 29 f1 8a 4f 2b 31 29 22 83 6f 6e 20 6a 6f ; 550PRINTTAB(O+1)" on joystick #1 to continue."; &7128 79 73 74 69 63 6b 20 23 31 20 74 6f 20 63 6f 6e &7138 74 69 6e 75 65 2e 22 3b 0d &7141 02 30 0f d1 3d 30 3a 2a 46 58 31 35 20 30 0d ; 560TIME=0: ; *FX15 0 # Flush buffers &7150 02 3a 29 f5 fd 28 a6 28 30 29 3d 33 32 29 20 84 ; 570REPEATUNTIL(INKEY(0)=32) OR (TIME>4500) OR (ADVAL(0)AND1)=1: &7160 20 28 91 3e 34 35 30 30 29 20 84 20 28 96 28 30 ; PRINT &7170 29 80 31 29 3d 31 3a f1 0d &7179 02 44 3e e3 54 25 3d 30 b8 35 30 3a f1 89 28 28 ; 580FORT%=0TO50: &7189 54 25 20 80 20 31 29 2a 32 30 29 3b bd 28 26 38 ; PRINTSPC((T% AND 1)*20);CHR$(&80+RND(7));"Amcom's Fortress.": &7199 30 2b b3 28 37 29 29 3b 22 41 6d 63 6f 6d 27 73 ; NEXT &71a9 20 46 6f 72 74 72 65 73 73 2e 22 3a ed 0d &71b7 02 4e 08 f1 27 3a e1 0d ; 590PRINT': ; ENDPROC &71bf 02 58 10 dd f2 43 3a ef 33 31 2c 30 2c 32 31 0d ; 600DEFPROCC: ; VDU31,0,21 # TAB(&00, &15) &71cf 02 62 37 e7 46 25 3d 26 39 30 20 f1 27 22 88 53 ; 610IFF%=&90 &71df 74 6f 70 20 74 61 70 65 20 70 6c 61 79 65 72 2e ; PRINT'" Stop tape player.": &71ef 22 3a 46 25 3d 26 31 36 3a 3f 26 35 30 3d 46 25 ; F%=&16: &71ff 3a 8b 20 f1 27 27 0d ; ?&50=F%: # Unused ; ELSE ; PRINT'' &7206 02 6c 34 f1 27 8a 4f 2d 33 29 bd 31 34 31 3b 22 ; 620PRINT'TAB(O-3)CHR$141;" Written for Amcom by Mat Newman."; &7216 82 57 72 69 74 74 65 6e 20 66 6f 72 20 41 6d 63 &7226 6f 6d 20 62 79 20 4d 61 74 20 4e 65 77 6d 61 6e &7236 2e 22 3b 0d &723a 02 76 33 f1 8a 4f 2d 33 29 bd 31 34 31 3b 22 86 ; 630PRINTTAB(O-3)CHR$141;" Written for Amcom by Mat Newman."; &724a 57 72 69 74 74 65 6e 20 66 6f 72 20 41 6d 63 6f &725a 6d 20 62 79 20 4d 61 74 20 4e 65 77 6d 61 6e 2e &726a 22 3b 0d &726d 02 80 3e f4 20 20 20 20 20 20 20 20 20 20 20 20 ; 640REM &727d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &728d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &729d 20 20 20 20 20 20 20 20 20 20 20 20 20 0d &72ab 02 8a 27 d1 3d 30 3a f5 fd 28 a6 28 30 29 3d 33 ; 650TIME=0: &72bb 32 29 84 28 96 28 30 29 80 31 29 84 28 91 3e 31 ; REPEATUNTIL(INKEY(0)=32)OR(ADVAL(0)AND1)OR(TIME>1000): &72cb 30 30 30 29 3a e1 0d ; ENDPROC &72d2 02 94 0e dd f2 47 4b 45 59 28 46 24 29 0d ; 660DEFPROCGKEY(F$) &72e0 02 9e 21 f1 22 50 52 45 53 53 20 4b 45 59 20 46 ; 670PRINT"PRESS KEY FOR ";F$;" ... "; &72f0 4f 52 20 22 3b 46 24 3b 22 20 2e 2e 2e 20 22 3b &7300 0d &7301 02 a8 22 f2 47 4b 45 59 31 28 46 24 29 3a e7 52 ; 680PROCGKEY1(F$): &7311 24 3d 22 22 8c 8d 74 68 42 20 8b 20 f1 52 24 3a ; IFR$=""THEN680 &7321 e1 0d ; ELSE PRINTR$:ENDPROC &7323 02 b2 0f dd f2 47 4b 45 59 31 28 46 24 29 0d ; 690DEFPROCGKEY1(F$) &7332 02 bc 0b 2a 46 58 31 35 20 30 0d ; 700*FX15 0 # Flush buffers &733d 02 c6 0e d1 3d 30 3a f5 fd 91 3e 31 35 0d ; 710TIME=0: ; REPEATUNTILTIME>15 &734b 02 d0 11 e3 54 25 3d 2d 31 32 38 20 b8 20 2d 31 ; 720FORT%=-128 TO -1 &735b 0d &735c 02 da 11 e7 54 25 3d 2d 31 30 20 54 25 3d 2d 32 ; 730IFT%=-10 T%=-2 &736c 0d &736d 02 e4 18 e7 a6 28 54 25 29 20 8c 20 41 25 3d 54 ; 740IFINKEY(T%) THEN A%=T%:T%=10 &737d 25 3a 54 25 3d 31 30 0d &7385 02 ee 1d ed 3a e7 54 25 3d 30 20 8c 20 8d 74 7c ; 750NEXT:IFT%=0 THEN 700 &7395 42 20 8b 20 41 25 3d 2d 31 2d 41 25 0d ; IFT%=0 THEN 700 ; ELSE A%=-1-A% &73a2 02 f8 29 49 3d a6 28 30 29 3a 49 31 3d a6 28 30 ; 760I=INKEY(0):I1=INKEY(0): &73b2 29 3a e7 49 31 3c 3e 49 20 80 20 49 31 3c 3e 2d ; I1=INKEY(0): &73c2 31 20 8c 20 49 3d 49 31 0d ; IFI1<>I AND I1<>-1 THEN I=I1 &73cb 03 02 18 e7 49 3d 31 32 37 20 52 24 3d 22 44 45 ; 770IFI=127 R$="DELETE":ENDPROC &73db 4c 45 54 45 22 3a e1 0d &73e3 03 0c 13 e7 49 3d 39 20 52 24 3d 22 54 41 42 22 ; 780IFI=9 R$="TAB":ENDPROC &73f3 3a e1 0d &73f6 03 16 1a e7 49 3d 33 32 20 52 24 3d 22 53 50 41 ; 790IFI=32 R$="SPACE BAR":ENDPROC &7406 43 45 20 42 41 52 22 3a e1 0d &7410 03 20 13 e7 49 3d 32 37 20 8c 20 d8 3a e5 8d 54 ; 800IFI=27 THEN CLEAR:GOTO40 &7420 68 40 0d &7423 03 2a 0a f7 20 8d 44 66 43 0d ; 810RESTORE 870 &742d 03 34 27 e3 44 25 3d 30 b8 31 39 3a f3 42 25 2c ; 820FORD%=0TO19: &743d 41 24 3a e7 41 25 3d 42 25 20 52 24 3d 41 24 3a ; READB%,A$: &744d 44 25 3d 31 30 30 0d ; IFA%=B% R$=A$: ; D%=100 &7454 03 3e 0f ed 3a e7 44 25 3d 31 30 31 20 e1 0d ; 830NEXT: ; IFD%=101 ENDPROC &7463 03 48 14 e7 20 49 3e 39 36 20 49 3d 49 20 80 20 ; 840IF I>96 I=I AND &DF &7473 26 44 46 0d &7477 03 52 1a e7 49 3e 33 31 20 80 49 3c 31 32 37 20 ; 850IFI>31 ANDI<127 R$=CHR$(I):ENDPROC &7487 52 24 3d bd 28 49 29 3a e1 0d &7491 03 5c 0b 52 24 3d 22 22 3a e1 0d ; 860R$="":ENDPROC &749c 03 66 3f dc 26 33 39 2c 55 50 20 41 52 52 4f 57 ; 870DATA&39,UP ARROW,&29,DOWN ARROW,&19,LEFT ARROW,&79,RIGHT ARROW &74ac 2c 26 32 39 2c 44 4f 57 4e 20 41 52 52 4f 57 2c &74bc 26 31 39 2c 4c 45 46 54 20 41 52 52 4f 57 2c 26 &74cc 37 39 2c 52 49 47 48 54 20 41 52 52 4f 57 0d &74db 03 70 64 dc 26 34 39 2c 52 45 54 55 52 4e 2c 26 ; 880DATA&49,RETURN,&20,f0,&40,CAPS LOCK,&50,SHIFT LOCK,&71,f1,&72, &74eb 32 30 2c 66 30 2c 26 34 30 2c 43 41 50 53 20 4c ; f2,&73,f3,&74,f5,&75,f6,&76,f8,&77,f9 &74fb 4f 43 4b 2c 26 35 30 2c 53 48 49 46 54 20 4c 4f &750b 43 4b 2c 26 37 31 2c 66 31 2c 26 37 32 2c 66 32 &751b 2c 26 37 33 2c 66 33 2c 26 37 34 2c 66 35 2c 26 &752b 37 35 2c 66 36 2c 26 37 36 2c 66 38 2c 26 37 37 &753b 2c 66 39 0d &753f 03 7a 2a dc 26 36 39 2c 43 4f 50 59 2c 30 2c 53 ; 890DATA&69,COPY,0,SHIFT,1,CTRL,&14,f4,&16,f7 &754f 48 49 46 54 2c 31 2c 43 54 52 4c 2c 26 31 34 2c &755f 66 34 2c 26 31 36 2c 66 37 0d &7569 03 84 33 dd f2 43 43 3a db 3a f1 27 22 86 4b 65 ; 900DEFPROCCC: &7579 79 20 64 65 66 69 6e 65 72 2e 20 50 72 65 73 73 ; CLS: &7589 20 45 53 43 41 50 45 20 74 6f 20 72 65 73 65 74 ; PRINT'" Key definer. Press ESCAPE to reset." &7599 2e 22 0d &759c 03 8e 20 f1 22 85 44 65 70 72 65 73 73 20 65 61 ; 910PRINT" Depress each key firmly." &75ac 63 68 20 6b 65 79 20 66 69 72 6d 6c 79 2e 22 0d &75bc 03 98 11 ef 32 38 2c 30 2c 32 34 2c 33 39 2c 37 ; 920VDU28,0,24,39,7 # Define text window &75cc 0d &75cd 03 a2 1f f2 47 4b 45 59 28 22 55 50 20 20 20 22 ; 930PROCGKEY("UP "): &75dd 29 3a 4b 31 3d 41 25 3a 4b 31 24 3d 52 24 0d ; K1=A%:K1$=R$ &75ec 03 ac 64 f2 47 4b 45 59 28 22 44 4f 57 4e 20 22 ; 940PROCGKEY("DOWN "): &75fc 29 3a e7 41 25 3c 3e 4b 31 20 4b 32 3d 41 25 3a ; IFA%<>K1 &760c 4b 32 24 3d 52 24 20 8b 20 f1 22 53 69 6c 6c 79 ; K2=A%:K2$=R$ &761c 2e 2e 2e 61 6c 72 65 61 64 79 20 75 73 65 64 21 ; ELSE &762c 21 22 3a 41 25 3d 31 35 3a 58 25 3d 30 3a d6 26 ; PRINT"Silly...already used!!": &763c 46 46 46 34 3a 49 3d a6 28 32 30 30 29 3a e5 8d ; A%=15:X%=0:CALL&FFF4: # Flush buffers &764c 74 6c 43 0d ; I=INKEY(200): ; GOTO940 &7650 03 b6 6d f2 47 4b 45 59 28 22 4c 45 46 54 20 22 ; 950PROCGKEY("LEFT "): &7660 29 3a e7 41 25 3c 3e 4b 31 20 80 20 41 25 3c 3e ; IFA%<>K1 AND A%<>K2 &7670 4b 32 20 4b 33 3d 41 25 3a 4b 33 24 3d 52 24 20 ; K3=A%:K3$=R$ &7680 8b 20 f1 22 53 69 6c 6c 79 2e 2e 2e 61 6c 72 65 ; ELSE &7690 61 64 79 20 75 73 65 64 21 21 22 3a 41 25 3d 31 ; PRINT"Silly...already used!!": &76a0 35 3a 58 25 3d 30 3a d6 26 46 46 46 34 3a 49 3d ; A%=15:X%=0:CALL&FFF4: # Flush buffers &76b0 a6 28 32 30 30 29 3a e5 8d 74 76 43 0d ; I=INKEY(200): ; GOTO950 &76bd 03 c0 76 f2 47 4b 45 59 28 22 52 49 47 48 54 22 ; 960PROCGKEY("RIGHT"): &76cd 29 3a e7 41 25 3c 3e 4b 31 20 80 20 41 25 3c 3e ; IFA%<>K1 AND A%<>K2 AND A%<>K3 &76dd 4b 32 20 80 20 41 25 3c 3e 4b 33 20 4b 34 3d 41 ; K4=A%:K4$=R$ &76ed 25 3a 4b 34 24 3d 52 24 20 8b 20 f1 22 53 69 6c ; ELSE &76fd 6c 79 2e 2e 2e 61 6c 72 65 61 64 79 20 75 73 65 ; PRINT"Silly...already used!!": &770d 64 21 21 22 3a 41 25 3d 31 35 3a 58 25 3d 30 3a ; A%=15:X%=0:CALL&FFF4: # Flush buffers &771d d6 26 46 46 46 34 3a 49 3d a6 28 32 30 30 29 3a ; I=INKEY(200): &772d e5 8d 64 40 43 0d ; GOTO960 &7733 03 ca 7f f2 47 4b 45 59 28 22 46 49 52 45 20 22 ; 970PROCGKEY("FIRE "): &7743 29 3a e7 41 25 3c 3e 4b 31 20 80 20 41 25 3c 3e ; IFA%<>K1 AND A%<>K2 AND A%<>K3 AND A%<>K4 &7753 4b 32 20 80 20 41 25 3c 3e 4b 33 20 80 20 41 25 ; K5=A%:K5$=R$: &7763 3c 3e 4b 34 20 4b 35 3d 41 25 3a 4b 35 24 3d 52 ; ELSE &7773 24 3a 8b 20 f1 22 53 69 6c 6c 79 2e 2e 2e 61 6c ; PRINT"Silly...already used!!": &7783 72 65 61 64 79 20 75 73 65 64 21 21 22 3a 41 25 ; A%=15:X%=0:CALL&FFF4: # Flush buffers &7793 3d 31 35 3a 58 25 3d 30 3a d6 26 46 46 46 34 3a ; I=INKEY(200): &77a3 49 3d a6 28 32 30 30 29 3a e5 8d 64 4a 43 0d ; GOTO970 &77b2 03 d4 1b f1 27 27 22 4b 65 79 73 20 73 65 74 2e ; 980PRINT''"Keys set."; &77c2 22 3b 3a 2a 46 58 31 35 20 30 0d ; *FX15 0 # Flush buffers &77cd 03 de 14 49 3d a6 28 35 30 30 29 3a 2a 46 58 31 ; 990I=INKEY(500): &77dd 35 20 30 0d ; *FX15 0 # Flush buffers &77e1 03 e8 31 ef 32 38 2c 30 2c 32 34 2c 33 39 2c 33 ; 1000VDU28,0,24,39,3: # Define text window &77f1 3a f1 27 27 27 3a e1 3a 20 22 20 20 83 88 8d 20 ; PRINT''': &7801 20 20 20 48 45 4c 4c 4f 20 54 48 45 52 45 20 21 ENDPROC: &7811 0d ; " ... HELLO THERE ! # Embedded double height # wraps onto new line in 40 columns &7812 03 f2 15 22 86 88 8d 48 45 4c 4c 4f 20 54 48 45 ; 1010" HELLO THERE ! # Embedded double height &7822 52 45 20 21 ; &7826 47 6f 20 61 77 61 79 20 21 0d ; Go away ! # 6f 20 should be 0d ff for valid program ; unused &7830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7840 00 00 00 00 00 00 00 00 Game disassembly ================ ; ? ; 00001f90 00006100 4370 &1f90 a0 04 LDY #&04 # &1f90 - &1fff is identical to &1f90 - &1fff in stream ; plot_shadow_pixel_loop &1f92 18 CLC &1f93 2c 0d 16 BIT &160d ; #&88 &1f96 d0 01 BNE &1f99 ; pixel_not_colour_0 &1f98 38 SEC # Set bit of mask if pixel is colour 0 ; pixel_not_colour_0 &1f99 26 7a ROL &7a ; mask &1f9b 0a ASL A &1f9c 88 DEY &1f9d d0 f3 BNE &1f92 ; plot_shadow_pixel_loop &1f9f a5 7a LDA &7a ; mask &1fa1 0a ASL A &1fa2 0a ASL A &1fa3 0a ASL A &1fa4 0a ASL A &1fa5 05 7a ORA &7a ; mask # Convert mask to colour 3 &1fa7 85 7a STA &7a ; mask &1fa9 29 f0 AND #&f0 # Convert colour 3 to colour 2 (black) &1fab 49 f0 EOR #&f0 # Invert &1fad 85 79 STA &79 ; shadow &1faf a5 7a LDA &7a ; mask &1fb1 a4 76 LDY &76 ; row_in_group &1fb3 31 70 AND (&70),Y ; screen_address &1fb5 05 79 ORA &79 ; shadow &1fb7 91 70 STA (&70),Y ; screen_address &1fb9 c8 INY # Move down a row &1fba c0 04 CPY #&04 &1fbc d0 13 BNE &1fd1 ; not_group &1fbe a0 00 LDY #&00 &1fc0 a5 70 LDA &70 ; screen_address_low &1fc2 18 CLC &1fc3 69 40 ADC #&40 # Move down a group &1fc5 85 70 STA &70 ; screen_address_low &1fc7 a5 71 LDA &71 ; screen_address_high &1fc9 69 01 ADC #&01 &1fcb 10 02 BPL &1fcf ; skip_wraparound &1fcd e9 3f SBC #&3f ; skip_wraparound &1fcf 85 71 STA &71 ; screen_address_high ; not_group &1fd1 c6 78 DEC &78 ; rows &1fd3 d0 8a BNE &1f5f ; plot_shadow_row_loop &1fd5 68 PLA ; screen_address_low &1fd6 18 CLC &1fd7 69 08 ADC #&08 # Move right four pixels &1fd9 85 70 STA &70 ; screen_address_low &1fdb 68 PLA ; screen_address_high &1fdc 69 00 ADC #&00 &1fde 10 02 BPL &1fe2 ; skip_wraparound &1fe0 e9 3f SBC #&3f ; skip_wraparound &1fe2 85 71 STA &71 ; screen_address_high &1fe4 a5 72 LDA &72 ; sprite_address_low &1fe6 18 CLC &1fe7 65 75 ADC &75 ; sprite_height &1fe9 85 72 STA &72 ; sprite_address_low &1feb 90 02 BCC &1fef ; skip_page &1fed e6 73 INC &73 ; sprite_address_high ; skip_page &1fef c6 74 DEC &74 ; sprite_width &1ff1 d0 01 BNE &1ff4 ; to_plot_shadow_column_loop &1ff3 60 RTS ; to_plot_shadow_column_loop &1ff4 4c 4a 1f JMP &1f4a ; plot_shadow_column_loop ; check_for_player_collision_with_objects &1ff7 a9 00 LDA #&00 &1ff9 85 70 STA &70 ; player_hit_wall &1ffb 85 71 STA &71 ; player_passed_wall &1ffd a2 09 LDX #&09 ; check_for_player_collision_with_objects_loop &1fff 86 7f STX &7f ; object_slot &2001 bd 00 3e LDA &3e00,X ; objects_z &2004 d0 03 BNE &2009 ; consider_next_object # Is the object level with the player? &2006 20 22 20 JSR &2022 ; check_for_player_collision_with_object # If so, check for collision with player ; consider_next_object &2009 a6 7f LDX &7f ; object_slot &200b ca DEX &200c 10 f1 BPL &1fff ; find_free_slot_for_object_loop &200e a5 70 LDA &70 ; player_hit_wall # Non-zero if player hit wall &2010 0d 6c 3f ORA &3f6c ; player_destroyed # Non-zero if player hit by missile or let fighter through &2013 d0 2f BNE &2044 ; kill_player &2015 ad 6d 3f LDA &3f6d ; player_fuel &2018 d0 07 BNE &2021 ; leave # Has the player run out of fuel? &201a ad 02 3f LDA &3f02 ; player_y &201d c9 93 CMP #&93 # If so, has the player hit the ground? &201f 90 23 BCC &2044 ; kill_player # If so, kill the player ; leave &2021 60 RTS ; check_for_player_collision_with_object &2022 bd 60 3e LDA &3e60,X ; objects_type # Top bit set if large or electric wall &2025 30 28 BMI &204f ; check_for_player_collision_with_large_wall &2027 ad 02 3f LDA &3f02 ; player_y &202a 38 SEC &202b e9 90 SBC #&90 &202d dd 50 3e CMP &3e50,X ; objects_max_y # Has the player hit the object? &2030 b0 ef BCS &2021 ; leave &2032 dd 40 3e CMP &3e40,X ; objects_min_y &2035 90 ea BCC &2021 ; leave &2037 ad 03 3f LDA &3f03 ; player_x &203a dd 30 3e CMP &3e30,X ; objects_max_x &203d b0 e2 BCS &2021 ; leave &203f dd 20 3e CMP &3e20,X ; objects_min_x &2042 90 dd BCC &2021 ; leave ; kill_player &2044 a9 03 LDA #&03 &2046 8d 6e 3f STA &3f6e ; player_fuel_drain_cooldown # Set to non-zero to skip fuel drain &2049 20 82 29 JSR &2982 ; to_update_fuel &204c 4c 91 29 JMP &2991 ; to_explode_player ; check_for_player_collision_with_large_wall &204f ad 02 3f LDA &3f02 ; player_y &2052 38 SEC &2053 e9 90 SBC #&90 &2055 dd 50 3e CMP &3e50,X ; objects_max_y # Has the player hit the opening in the wall? &2058 b0 1b BCS &2075 ; consider_setting_player_hit_wall &205a dd 40 3e CMP &3e40,X ; objects_min_y &205d 90 16 BCC &2075 ; consider_setting_player_hit_wall &205f ad 03 3f LDA &3f03 ; player_x &2062 dd 30 3e CMP &3e30,X ; objects_max_x &2065 b0 0e BCS &2075 ; consider_setting_player_hit_wall &2067 dd 20 3e CMP &3e20,X ; objects_min_x &206a 90 09 BCC &2075 ; consider_setting_player_hit_wall &206c a9 00 LDA #&00 # If so, &206e 85 70 STA &70 ; player_hit_wall # Set to zero to indicate player hasn't hit wall &2070 a9 01 LDA #&01 &2072 85 71 STA &71 ; player_passed_wall # Set to non-zero to indicate player passed wall &2074 60 RTS ; consider_setting_player_hit_wall # Otherwise, &2075 a5 71 LDA &71 ; player_passed_wall # Zero if player hasn't passed through opening in wall &2077 f0 01 BEQ &207a ; set_player_hit_wall &2079 60 RTS ; set_player_hit_wall &207a a9 01 LDA #&01 &207c 85 70 STA &70 ; player_hit_wall # Set to non-zero to indicate player hit wall &207e 60 RTS ; missile_sprite &207f 33 33 44 88 ; update_missiles &2083 a2 00 LDX #&00 ; unplot_missiles_loop &2085 bd 0b 3f LDA &3f0b,X ; missiles_state # Zero if no missile in slot &2088 f0 20 BEQ &20aa ; consider_next_missile &208a bd 17 3f LDA &3f17,X ; missiles_screen_address_low &208d 85 70 STA &70 ; screen_address_low &208f bd 1b 3f LDA &3f1b,X ; missiles_screen_address_high # Zero if missile not plotted &2092 f0 16 BEQ &20aa ; consider_next_missile &2094 85 71 STA &71 ; screen_address_high &2096 a9 06 LDA #&06 ; &0668 = missile_buffers &2098 85 73 STA &73 ; buffer_address_high &209a 8a TXA &209b 0a ASL A &209c 0a ASL A &209d 69 68 ADC #&68 &209f 85 72 STA &72 ; buffer_address_low &20a1 a0 03 LDY #&03 ; unplot_missile_loop &20a3 b1 72 LDA (&72),Y ; buffer_address_low &20a5 91 70 STA (&70),Y ; screen_address_high # Unplot missile &20a7 88 DEY &20a8 10 f9 BPL &20a3 ; unplot_missile_loop ; consider_next_missile &20aa e8 INX &20ab e0 04 CPX #&04 &20ad d0 d6 BNE &2085 ; unplot_missiles_loop &20af 20 76 21 JSR &2176 ; check_for_missile_collisions &20b2 a2 03 LDX #&03 ; update_missiles_loop &20b4 bd 0b 3f LDA &3f0b,X ; missiles_state # Zero if no missile in slot &20b7 f0 62 BEQ &211b ; consider_next_missile &20b9 18 CLC &20ba 69 03 ADC #&03 &20bc c9 20 CMP #&20 &20be 90 07 BCC &20c7 ; skip_removing_missile &20c0 a9 00 LDA #&00 &20c2 9d 0b 3f STA &3f0b,X ; missiles_state # Set to zero to indicate no missile in slot &20c5 f0 54 BEQ &211b ; consider_next_missile # Always branches ; skip_removing_missile &20c7 9d 0b 3f STA &3f0b,X ; missiles_state &20ca 0a ASL A &20cb 0a ASL A &20cc 85 73 STA &73 ; missile_state &20ce bd 0f 3f LDA &3f0f,X ; missiles_y # Calculate y screen coordinate for missile &20d1 38 SEC &20d2 fd 13 3f SBC &3f13,X ; missiles_x # screen_y = world_y - world_x &20d5 18 CLC &20d6 65 73 ADC &73 ; missile_state &20d8 09 03 ORA #&03 &20da a8 TAY &20db 90 07 BCC &20e4 ; skip_removing_missile # Has the missile gone off-screen vertically? ; remove_missile &20dd a9 00 LDA #&00 &20df 9d 0b 3f STA &3f0b,X ; missiles_state # Set to zero to indicate no missile in slot &20e2 f0 37 BEQ &211b ; consider_next_missile # Always branches ; skip_removing_missile &20e4 bd 13 3f LDA &3f13,X ; missiles_x # Calculate x screen coordinate for missile &20e7 86 7f STX &7f ; missile_slot &20e9 18 CLC &20ea 65 73 ADC &73 ; missile_state &20ec c9 8c CMP #&8c &20ee b0 ed BCS &20dd ; remove_missile # Has the missile gone off-screen horizontally? &20f0 aa TAX &20f1 20 5f 12 JSR &125f ; calculate_screen_address &20f4 a6 7f LDX &7f ; missile_slot &20f6 a5 70 LDA &70 ; screen_address_low &20f8 9d 17 3f STA &3f17,X ; missiles_screen_address_low &20fb a5 71 LDA &71 ; screen_address_high &20fd 9d 1b 3f STA &3f1b,X ; missiles_screen_address_high &2100 a9 06 LDA #&06 ; &0668 = missile_buffers &2102 85 73 STA &73 ; buffer_address_high &2104 8a TXA &2105 0a ASL A &2106 0a ASL A &2107 69 68 ADC #&68 &2109 85 72 STA &72 ; buffer_address_low &210b a0 03 LDY #&03 ; plot_missile_loop &210d b1 70 LDA (&70),Y ; screen_address &210f 91 72 STA (&72),Y ; buffer_address # Buffer missile &2111 b9 7f 20 LDA &207f,Y ; missile_sprite &2114 11 70 ORA (&70),Y ; screen_address &2116 91 70 STA (&70),Y ; screen_address # Plot missile &2118 88 DEY &2119 10 f2 BPL &210d ; plot_missile_loop ; consider_next_missile &211b ca DEX &211c 10 96 BPL &20b4 ; update_missiles_loop &211e ad 6d 3f LDA &3f6d ; player_fuel &2121 d0 01 BNE &2124 ; consider_firing # Don't allow player to fire if out of fuel &2123 60 RTS ; consider_firing &2124 a6 34 LDX &34 ; key_fire &2126 20 a2 12 JSR &12a2 ; check_for_keypress &2129 a6 20 LDX &20 ; joystick_fire &212b f0 02 BEQ &212f ; fire_not_pressed &212d 09 80 ORA #&80 ; fire_not_pressed &212f 0a ASL A # Set carry if keyboard or joystick fire pressed &2130 6e 1f 3f ROR &3f1f ; suppress_firing_roller &2133 2c 1f 3f BIT &3f1f ; suppress_firing_roller &2136 70 0c BVS &2144 ; leave # If fire wasn't pressed last time, &2138 10 0a BPL &2144 ; leave # but is pressed this time, then add missile &213a a2 03 LDX #&03 ; find_free_slot_for_missile_loop &213c bd 0b 3f LDA &3f0b,X ; missiles_state # Zero if no missile in slot &213f f0 04 BEQ &2145 ; add_missile &2141 ca DEX &2142 10 f8 BPL &213c ; find_free_slot_for_missile_loop &2144 60 RTS ; add_missile &2145 a9 01 LDA #&01 &2147 9d 0b 3f STA &3f0b,X ; missiles_state # Set to non-zero to indicate missile in slot &214a ad 02 3f LDA &3f02 ; player_y &214d 38 SEC &214e e9 02 SBC #&02 &2150 9d 0f 3f STA &3f0f,X ; missiles_y &2153 ad 03 3f LDA &3f03 ; player_x &2156 18 CLC &2157 69 05 ADC #&05 &2159 9d 13 3f STA &3f13,X ; missiles_x &215c a9 00 LDA #&00 &215e 9d 1b 3f STA &3f1b,X ; missiles_screen_address_high # Set to zero to indicate missile not plotted ; start_firing_sound &2161 a9 01 LDA #&01 &2163 8d 4d 3f STA &3f4d ; firing_sound_state # Set to non-zero to start firing sound &2166 a9 32 LDA #&32 &2168 8d 4e 3f STA &3f4e ; firing_sound_duration &216b a9 0d LDA #&0d &216d 8d 4f 3f STA &3f4f ; firing_sound_volume &2170 a9 02 LDA #&02 &2172 8d 50 3f STA &3f50 ; firing_sound_cooldown &2175 60 RTS ; check_for_missile_collisions &2176 20 89 21 JSR &2189 ; update_explosions &2179 a2 03 LDX #&03 ; check_for_missile_collisions_loop &217b bd 0b 3f LDA &3f0b,X ; missiles_state # Zero if no missile in slot &217e f0 05 BEQ &2185 ; consider_next_missile &2180 20 c3 21 JSR &21c3 ; check_for_missile_collision &2183 a6 7f LDX &7f ; missile_slot ; consider_next_missile &2185 ca DEX &2186 10 f3 BPL &217b ; check_for_missile_collisions_loop &2188 60 RTS ; update_explosions &2189 a2 03 LDX #&03 ; update_explosions_loop &218b bd 34 3f LDA &3f34,X ; explosions_sprite_address_low # Zero if no explosion in slot &218e f0 05 BEQ &2195 ; consider_next_explosion &2190 20 9b 21 JSR &219b ; update_explosion &2193 a6 7f LDX &7f ; explosion_slot ; consider_next_explosion &2195 ca DEX &2196 10 f3 BPL &218b ; update_explosions_loop &2198 4c 11 24 JMP &2411 ; unplot_wall_explosions ; update_explosion &219b 86 7f STX &7f ; explosion_slot &219d 85 72 STA &72 ; sprite_address_low &219f a0 14 LDY #&14 &21a1 c9 50 CMP #&50 ; &3a50 = sprite_destroyed_large &21a3 f0 02 BEQ &21a7 ; set_sprite_height &21a5 a0 10 LDY #&10 ; set_sprite_height &21a7 84 75 STY &75 ; sprite_height &21a9 bd 38 3f LDA &3f38,X ; explosions_screen_address_low &21ac 85 70 STA &70 ; screen_address_low &21ae bd 3c 3f LDA &3f3c,X ; explosions_screen_address_high &21b1 85 71 STA &71 ; screen_address_high &21b3 a9 3a LDA #&3a &21b5 85 73 STA &73 ; sprite_address_high &21b7 a9 03 LDA #&03 &21b9 85 74 STA &74 ; sprite_width &21bb a9 00 LDA #&00 &21bd 9d 34 3f STA &3f34,X ; explosions_sprite_address_low # Set to zero to indicate no explosion in slot &21c0 4c a1 1e JMP &1ea1 ; plot_sprite # Plot explosion ; check_for_missile_collision &21c3 86 7f STX &7f ; missile_slot &21c5 85 7e STA &7e ; missile_z &21c7 85 70 STA &70 ; z_max # Check for collision with missile &21c9 38 SEC &21ca e9 04 SBC #&04 &21cc 85 73 STA &73 ; z_min &21ce bd 0f 3f LDA &3f0f,X ; missiles_y &21d1 85 71 STA &71 ; y &21d3 bd 13 3f LDA &3f13,X ; missiles_x &21d6 85 72 STA &72 ; x &21d8 20 9a 29 JSR &299a ; check_for_collision_with_fighter # Returns carry clear if collision occurred &21db b0 0e BCS &21eb ; check_for_missile_collision_with_objects ; missile_collided_with_fighter &21dd 20 92 25 JSR &2592 ; start_explosion_sound &21e0 a9 00 LDA #&00 &21e2 9d 0b 3f STA &3f0b,X ; missiles_state # Set to zero to indicate no missile in slot &21e5 a9 02 LDA #&02 &21e7 8d 7e 3f STA &3f7e ; fighter_explosion_state # Set to two to start explosion &21ea 60 RTS ; check_for_missile_collision_with_objects &21eb a2 00 LDX #&00 &21ed 86 70 STX &70 ; missile_hit_wall # Set to zero to indicate missile hasn't hit wall &21ef 86 71 STX &71 ; missile_passed_wall # Set to zero to indicate missile hasn't passed wall &21f1 a2 09 LDX #&09 ; check_for_missile_collision_objects_loop &21f3 a5 7e LDA &7e ; missile_z &21f5 a0 01 LDY #&01 # Set to non-zero to check collision by default &21f7 dd 00 3e CMP &3e00,X ; objects_z &21fa b0 02 BCS &21fe ; is_equal_or_greater # Is the missile at or beyond the object? &21fc a0 00 LDY #&00 # If not, set to zero to skip collision ; is_equal_or_greater &21fe bd 10 3e LDA &3e10,X ; objects_width_remaining &2201 18 CLC &2202 7d 00 3e ADC &3e00,X ; objects_z &2205 69 01 ADC #&01 &2207 c5 7e CMP &7e ; missile_z &2209 b0 02 BCS &220d ; is_less # Is the missile too far beyond the object? &220b a0 00 LDY #&00 # If so, set to zero to skip collision ; is_less &220d 98 TYA &220e f0 05 BEQ &2215 ; skip_collision_check &2210 20 1d 22 JSR &221d ; check_for_missile_collision_with_object &2213 a6 7d LDX &7d ; object_slot ; skip_collision_check &2215 ca DEX &2216 10 db BPL &21f3 ; check_for_missile_collision_objects_loop &2218 a5 70 LDA &70 ; missile_hit_wall # Non-zero if missile hit wall &221a d0 35 BNE &2251 ; missile_hit_object ; leave &221c 60 RTS ; check_for_missile_collision_with_object &221d 86 7d STX &7d ; object_slot &221f bd 60 3e LDA &3e60,X ; objects_type # Top bit set if large or electric wall &2222 10 03 BPL &2227 ; is_object &2224 4c 1a 23 JMP &231a ; check_for_missile_collision_with_large_wall ; is_object &2227 a6 7f LDX &7f ; missile_slot &2229 bd 0f 3f LDA &3f0f,X ; missiles_y &222c 38 SEC &222d e9 8e SBC #&8e &222f a6 7d LDX &7d ; object_slot &2231 dd 40 3e CMP &3e40,X ; objects_min_y # Has the missile hit the object? &2234 90 e6 BCC &221c ; leave &2236 dd 50 3e CMP &3e50,X ; objects_max_y &2239 b0 e1 BCS &221c ; leave &223b a6 7f LDX &7f ; missile_slot &223d bd 13 3f LDA &3f13,X ; missiles_x &2240 38 SEC &2241 e9 04 SBC #&04 &2243 a6 7d LDX &7d ; object_slot &2245 dd 20 3e CMP &3e20,X ; objects_min_x &2248 90 d2 BCC &221c ; leave &224a dd 30 3e CMP &3e30,X ; objects_max_x &224d b0 cd BCS &221c ; leave &224f 68 PLA # Leave check_for_missile_collisions on next return &2250 68 PLA ; missile_hit_object &2251 20 92 25 JSR &2592 ; start_explosion_sound &2254 a6 7f LDX &7f ; missile_slot &2256 a9 00 LDA #&00 &2258 9d 0b 3f STA &3f0b,X ; missiles_state # Set to zero to indicate no missile in slot &225b bd 17 3f LDA &3f17,X ; missiles_screen_address_low &225e 85 70 STA &70 ; screen_address_low &2260 bd 1b 3f LDA &3f1b,X ; missiles_screen_address_high # Zero if missile not plotted &2263 f0 16 BEQ &227b ; skip_unplotting_missile &2265 85 71 STA &71 ; screen_address_high &2267 a9 06 LDA #&06 ; &0668 = missile_buffers &2269 85 73 STA &73 ; buffer_address_high &226b 8a TXA &226c 0a ASL A &226d 0a ASL A &226e 69 68 ADC #&68 &2270 85 72 STA &72 ; buffer_address_low &2272 a0 03 LDY #&03 ; unplot_missile_loop &2274 b1 72 LDA (&72),Y ; buffer_address &2276 91 70 STA (&70),Y ; screen_address # Unplot missile &2278 88 DEY &2279 10 f9 BPL &2274 ; unplot_missile_loop ; skip_unplotting_missile &227b a6 7d LDX &7d ; object_slot &227d bd 60 3e LDA &3e60,X ; objects_type &2280 d0 01 BNE &2283 ; consider_object &2282 60 RTS ; consider_object &2283 c9 03 CMP #&03 ; OBJECT_SILO &2285 90 10 BCC &2297 ; is_fuel_turret_or_silo &2287 c9 08 CMP #&08 ; OBJECT_BOSS &2289 d0 09 BNE &2294 ; not_boss &228b ce 81 3f DEC &3f81 ; boss_energy &228e a0 50 LDY #&50 # Score 5000 for destroying boss &2290 c6 09 DEC &09 ; initial_boss_energy &2292 f0 21 BEQ &22b5 ; increase_score_for_missile_hit ; not_boss &2294 4c b6 23 JMP &23b6 ; consider_missile_hitting_rocket_wall_or_fighter ; is_fuel_turret_or_silo &2297 a0 03 LDY #&03 # Score 300 for destroying turret or silo &2299 c9 01 CMP #&01 ; OBJECT_FUEL &229b d0 18 BNE &22b5 ; not_fuel ; missile_hit_fuel &229d a9 0c LDA #&0c # Gain 12 (or 11) fuel for destroying fuel &229f ac 8a 3f LDY &3f8a ; difficulty # Non-zero on level 3 and onwards &22a2 f0 02 BEQ &22a6 ; add_fuel &22a4 a9 0b LDA #&0b ; add_fuel &22a6 18 CLC &22a7 6d 6d 3f ADC &3f6d ; player_fuel &22aa c9 3c CMP #&3c &22ac 90 02 BCC &22b0 ; skip_ceiling &22ae a9 3c LDA #&3c ; skip_ceiling &22b0 8d 6d 3f STA &3f6d ; player_fuel &22b3 a0 02 LDY #&02 # Score 200 for destroying fuel ; not_fuel &22b5 a2 00 LDX #&00 &22b7 20 85 29 JSR &2985 ; to_add_XY_to_score &22ba a6 7d LDX &7d ; object_slot &22bc bd 70 3e LDA &3e70,X ; objects_screen_address_low &22bf 85 70 STA &70 ; screen_address_low &22c1 bd 80 3e LDA &3e80,X ; objects_screen_address_high &22c4 85 71 STA &71 ; screen_address_high &22c6 a9 3a LDA #&3a &22c8 85 73 STA &73 ; sprite_address_high &22ca a9 03 LDA #&03 &22cc 85 74 STA &74 ; sprite_width &22ce a6 7d LDX &7d ; object_slot &22d0 a9 ff LDA #&ff &22d2 9d 00 3e STA &3e00,X ; objects_z # Set to &ff to remove object &22d5 bd 60 3e LDA &3e60,X ; objects_type &22d8 a0 14 LDY #&14 &22da c9 01 CMP #&01 ; OBJECT_FUEL &22dc f0 02 BEQ &22e0 ; set_sprite_height &22de a0 10 LDY #&10 ; set_sprite_height &22e0 84 75 STY &75 ; sprite_height &22e2 48 PHA ; object_type &22e3 a2 03 LDX #&03 ; find_free_slot_for_explosion_loop &22e5 bd 34 3f LDA &3f34,X ; explosions_sprite_address_low # Zero if no explosion in slot &22e8 f0 03 BEQ &22ed ; add_explosion &22ea ca DEX &22eb 10 f8 BPL &22e5 ;find_free_slot_for_explosion_loop ; add_explosion &22ed 68 PLA ; object_type &22ee 48 PHA ; object_type &22ef a0 50 LDY #&50 ; &3a50 = sprite_destroyed_large # Use large explosion for fuel &22f1 c9 01 CMP #&01 ; OBJECT_FUEL &22f3 f0 02 BEQ &22f7 ; set_explosions_sprite_address_low &22f5 a0 8c LDY #&8c ; &3a8c = sprite_destroyed_small # Use small explosion otherwise ; set_explosions_sprite_address_low &22f7 98 TYA &22f8 9d 34 3f STA &3f34,X ; explosions_sprite_address_low # Set to non-zero to indicate explosion in slot &22fb a5 70 LDA &70 ; screen_address_low &22fd 9d 38 3f STA &3f38,X ; explosions_screen_address_low &2300 68 PLA ; object_type &2301 c9 08 CMP #&08 ; OBJECT_BOSS &2303 d0 03 BNE &2308 ; not_boss &2305 ee 80 3f INC &3f80 ; level_completed # Set to non-zero to indicate boss has been destroyed ; not_boss &2308 a5 71 LDA &71 ; screen_address_high &230a 9d 3c 3f STA &3f3c,X ; explosions_screen_address_high &230d a9 bc LDA #&bc ; &3abc = sprite_explosion_large &230f c0 50 CPY #&50 ; &3a50 = sprite_destroyed_large &2311 f0 02 BEQ &2315 ; set_sprite_address_low &2313 a9 f8 LDA #&f8 ; &3af8 = sprite_explosion_small ; set_sprite_address_low &2315 85 72 STA &72 ; sprite_address_low &2317 4c a1 1e JMP &1ea1 ; plot_sprite # Plot destroyed object ; check_for_missile_collision_with_large_wall &231a a6 7f LDX &7f ; missile_slot &231c bd 0f 3f LDA &3f0f,X ; missiles_y &231f 38 SEC &2320 e9 8e SBC #&8e &2322 a6 7d LDX &7d ; object_slot &2324 dd 50 3e CMP &3e50,X ; objects_max_y # Has the missile hit the opening in the wall? &2327 b0 22 BCS &234b ; consider_setting_missile_hit_wall &2329 dd 40 3e CMP &3e40,X ; objects_min_y &232c 90 1d BCC &234b ; consider_setting_missile_hit_wall &232e a6 7f LDX &7f ; missile_slot &2330 bd 13 3f LDA &3f13,X ; missiles_x &2333 38 SEC &2334 e9 05 SBC #&05 &2336 a6 7d LDX &7d ; object_slot &2338 dd 20 3e CMP &3e20,X ; objects_min_x &233b 90 0e BCC &234b ; consider_setting_missile_hit_wall &233d dd 30 3e CMP &3e30,X ; objects_max_x &2340 b0 09 BCS &234b ; consider_setting_missile_hit_wall &2342 a9 00 LDA #&00 &2344 85 70 STA &70 ; missile_hit_wall # Set to zero to indicate missile hasn't hit wall &2346 a9 01 LDA #&01 &2348 85 71 STA &71 ; missile_passed_wall # Set to non-zero to indicate missile passed wall &234a 60 RTS ; consider_setting_missile_hit_wall &234b a5 71 LDA &71 ; missile_passed_wall # Zero if missile hasn't passed through opening in wall &234d f0 01 BEQ &2350 ; set_missile_hit_wall &234f 60 RTS ; set_missile_hit_wall &2350 a9 01 LDA #&01 &2352 85 70 STA &70 ; missile_hit_wall # Set to non-zero to indicate missile hit wall &2354 60 RTS ; set_palette &2355 49 07 EOR #&07 &2357 8d 21 fe STA &fe21 ; video ULA palette register &235a 09 10 ORA #&10 &235c 8d 21 fe STA &fe21 ; video ULA palette register &235f 09 40 ORA #&40 &2361 8d 21 fe STA &fe21 ; video ULA palette register &2364 49 10 EOR #&10 &2366 8d 21 fe STA &fe21 ; video ULA palette register &2369 60 RTS ; write_to_sound_chip &236a 08 PHP ; processor status &236b a0 ff LDY #&ff # Set all bits to output &236d 78 SEI &236e 8c 43 fe STY &fe43 ; System VIA data direction register A &2371 8d 4f fe STA &fe4f ; System VIA input/output register A &2374 c8 INY ; 0 # Set sound chip write pin low &2375 8c 40 fe STY &fe40 ; System VIA port B input/output register &2378 a0 0a LDY #&0a ; delay_loop &237a 88 DEY &237b d0 fd BNE &237a ; delay_loop &237d a0 08 LDY #&08 # Set sound chip write pin high &237f 8c 40 fe STY &fe40 ; System VIA port B input/output register &2382 28 PLP ; processor status &2383 60 RTS ; set_sound_channel_volume # Called with X = (3 - channel), A = volume &2384 25 12 AND &12 ; sound_enabled &2386 85 70 STA &70 ; volume &2388 a9 9f LDA #&9f ; 1001 1111 # Would set channel 3 volume to 0 (silence) &238a 38 SEC &238b e5 70 SBC &70 ; volume &238d 85 70 STA &70 ; volume &238f 8a TXA &2390 0a ASL A &2391 0a ASL A &2392 0a ASL A &2393 0a ASL A &2394 0a ASL A &2395 05 70 ORA &70 ; volume &2397 4c 6a 23 JMP &236a ; write_to_sound_chip ; set_sound_channel_frequency # Called with X = (3 - channel), A = frequency &239a 85 70 STA &70 ; frequency &239c 0a ASL A &239d 0a ASL A &239e 29 0c AND #&0c &23a0 09 80 ORA #&80 &23a2 85 71 STA &71 ; frequency_high &23a4 8a TXA &23a5 0a ASL A &23a6 0a ASL A &23a7 0a ASL A &23a8 0a ASL A &23a9 0a ASL A &23aa 05 71 ORA &71 ; frequency_high &23ac 20 6a 23 JSR &236a ; write_to_sound_chip &23af a5 70 LDA &70 ; frequency &23b1 4a LSR A &23b2 4a LSR A &23b3 4c 6a 23 JMP &236a ; write_to_sound_chip ; consider_missile_hitting_rocket_wall_or_fighter # A = type of object hit by missile &23b6 c9 07 CMP #&07 ; OBJECT_ROCKET &23b8 d0 03 BNE &23bd ; missile_hit_wall_or_fighter &23ba 4c 4a 24 JMP &244a ; missile_hit_rocket ; missile_hit_wall_or_fighter &23bd a2 03 LDX #&03 ; find_free_slot_for_wall_explosion_loop &23bf bd 41 3f LDA &3f41,X ; wall_explosions_state # Zero if no explosion in slot &23c2 f0 03 BEQ &23c7 ; add_wall_explosion &23c4 ca DEX &23c5 10 f8 BPL &23bf ; find_free_slot_for_wall_explosion_loop ; add_wall_explosion &23c7 a9 01 LDA #&01 &23c9 9d 41 3f STA &3f41,X ; wall_explosions_state # Set to non-zero to indicate explosion in slot &23cc a4 7f LDY &7f ; missile_slot &23ce b9 17 3f LDA &3f17,Y ; missiles_screen_address_low &23d1 9d 45 3f STA &3f45,X ; wall_explosions_screen_address_low &23d4 85 70 STA &70 ; screen_address_low &23d6 48 PHA ; screen_address_low &23d7 b9 1b 3f LDA &3f1b,Y ; missiles_screen_address_high &23da 9d 49 3f STA &3f49,X ; wall_explosions_screen_address_high &23dd 85 71 STA &71 ; screen_address_high &23df 48 PHA ; screen_address_high &23e0 a9 06 LDA #&06 ; &0678 = wall_explosion_buffers &23e2 85 73 STA &73 ; buffer_address_high &23e4 a9 02 LDA #&02 &23e6 85 74 STA &74 ; sprite_width &23e8 a9 08 LDA #&08 &23ea 85 75 STA &75 ; sprite_height &23ec 8a TXA &23ed 0a ASL A &23ee 0a ASL A &23ef 0a ASL A &23f0 0a ASL A &23f1 69 78 ADC #&78 &23f3 85 72 STA &72 ; buffer_address_low &23f5 20 bd 1d JSR &1dbd ; buffer_sprite # Buffer wall explosion &23f8 68 PLA ; screen_address_high &23f9 85 71 STA &71 ; screen_address_high &23fb 68 PLA ; screen_address_low &23fc 85 70 STA &70 ; screen_address_low &23fe a9 3b LDA #&3b ; &3ba0 = sprite_wall_explosion &2400 85 73 STA &73 ; sprite_address_high &2402 a9 a0 LDA #&a0 &2404 85 72 STA &72 ; sprite_address_low &2406 a9 02 LDA #&02 &2408 85 74 STA &74 ; sprite_width &240a a9 08 LDA #&08 &240c 85 75 STA &75 ; sprite_height &240e 4c 1b 1e JMP &1e1b ; plot_masked_sprite # Plot wall explosion ; unplot_wall_explosions &2411 a2 03 LDX #&03 ; unplot_wall_explosions_loop &2413 bd 41 3f LDA &3f41,X ; wall_explosions_state # Zero if no explosion in slot &2416 f0 05 BEQ &241d ; consider_next_wall_explosion &2418 20 21 24 JSR &2421 ; unplot_wall_explosion &241b a6 7f LDX &7f ; wall_explosion_slot ; consider_next_wall_explosion &241d ca DEX &241e 10 f3 BPL &2413 ; unplot_wall_explosions_loop &2420 60 RTS ; unplot_wall_explosion &2421 bd 49 3f LDA &3f49,X ; wall_explosions_screen_address_high &2424 85 71 STA &71 ; screen_address_high &2426 bd 45 3f LDA &3f45,X ; wall_explosions_screen_address_low &2429 85 70 STA &70 ; screen_address_low &242b 86 7f STX &7f ; wall_explosion_slot &242d a9 06 LDA #&06 ; &0678 = wall_explosion_buffers &242f 85 73 STA &73 ; sprite_address_high &2431 8a TXA &2432 0a ASL A &2433 0a ASL A &2434 0a ASL A &2435 0a ASL A &2436 69 78 ADC #&78 &2438 85 72 STA &72 ; sprite_address_low &243a a9 00 LDA #&00 &243c 9d 41 3f STA &3f41,X ; wall_explosions_state # Set to zero to indicate no explosion in slot &243f a9 02 LDA #&02 &2441 85 74 STA &74 ; sprite_width &2443 a9 08 LDA #&08 &2445 85 75 STA &75 ; sprite_height &2447 4c a1 1e JMP &1ea1 ; plot_sprite # Unplot wall explosion ; missile_hit_rocket &244a bd 90 3e LDA &3e90,X ; objects_rocket_ttl # Non-zero if rocket not exploding &244d d0 01 BNE &2450 ; not_rocket_explosion &244f 60 RTS ; not_rocket_explosion &2450 a9 01 LDA #&01 &2452 9d 90 3e STA &3e90,X ; objects_rocket_ttl # Set to one to explode rocket on next update &2455 a2 00 LDX #&00 &2457 a0 01 LDY #&01 # Score 100 for destroying rocket &2459 4c 85 29 JMP &2985 ; to_add_XY_to_score ; update_sounds &245c 8a TXA &245d 48 PHA ; tmp_x &245e 98 TYA &245f 48 PHA ; tmp_y &2460 a5 70 LDA &70 ; screen_address_low # &70 and &71 are used in set_sound_channel_volume &2462 48 PHA ; screen_address_low # and set_sound_channel_frequency &2463 a5 71 LDA &71 ; screen_address_high &2465 48 PHA ; screen_address_high &2466 ad 84 3f LDA &3f84 ; electric_sound_state &2469 f0 03 BEQ &246e ; skip_updating_electric_sound &246b 20 12 25 JSR &2512 ; consider_updating_electric_sound ; skip_updating_electric_sound &246e ad 4d 3f LDA &3f4d ; firing_sound_state # Non-zero if firing sound playing &2471 f0 03 BEQ &2476 ; skip_updating_firing_sound &2473 20 5a 25 JSR &255a ; consider_updating_firing_sound ; skip_updating_firing_sound &2476 ad 5b 3f LDA &3f5b ; warning_sound_state # Non-zero if warning sound playing &2479 f0 03 BEQ &247e ; skip_updating_warning_sound &247b 20 b8 24 JSR &24b8 ; consider_updating_warning_sound ; skip_updating_warning_sound &247e ad 70 3f LDA &3f70 ; death_sound_state # Non-zero if death sound playing &2481 f0 06 BEQ &2489 ; skip_updating_death_sound &2483 20 db 24 JSR &24db ; consider_updating_death_sound &2486 4c a5 24 JMP &24a5 ; skip_updating_background_sound ; skip_updating_death_sound &2489 ad 80 3f LDA &3f80 ; level_completed # Non-zero if boss has been destroyed &248c f0 03 BEQ &2491 ; update_background_sound &248e 4c a5 24 JMP &24a5 ; skip_updating_background_sound ; update_background_sound &2491 a2 02 LDX #&02 # Use channel 1 &2493 ad 40 3f LDA &3f40 ; background_sound_frequency &2496 20 9a 23 JSR &239a ; set_sound_channel_frequency &2499 a9 00 LDA #&00 &249b 20 84 23 JSR &2384 ; set_sound_channel_volume &249e a2 03 LDX #&03 # Use channel 0 &24a0 a9 0a LDA #&0a &24a2 20 84 23 JSR &2384 ; set_sound_channel_volume ; skip_updating_background_sound &24a5 ad 51 3f LDA &3f51 ; explosion_sound_state # Non-zero if explosion sound playing &24a8 f0 03 BEQ &24ad ; skip_updating_explosion_sound &24aa 20 a7 25 JSR &25a7 ; consider_updating_explosion_sound ; skip_updating_explosion_sound &24ad 68 PLA ; screen_address_high &24ae 85 71 STA &71 ; screen_address_high &24b0 68 PLA ; screen_address_low &24b1 85 70 STA &70 ; screen_address_low &24b3 68 PLA ; tmp_y &24b4 a8 TAY &24b5 68 PLA ; tmp_x &24b6 aa TAX &24b7 60 RTS ; consider_updating_warning_sound &24b8 ce 5e 3f DEC &3f5e ; warning_sound_cooldown &24bb f0 01 BEQ &24be ; update_warning_sound &24bd 60 RTS ; update_warning_sound &24be a9 03 LDA #&03 &24c0 8d 5e 3f STA &3f5e ; warning_sound_cooldown &24c3 ce 5d 3f DEC &3f5d ; warning_sound_duration &24c6 d0 05 BNE &24cd ; not_end_of_warning_sound &24c8 a9 00 LDA #&00 &24ca 8d 5b 3f STA &3f5b ; warning_sound_state # Set to zero to stop warning sound ; not_end_of_warning_sound &24cd a2 00 LDX #&00 # Use channel 3 &24cf ad 5d 3f LDA &3f5d ; warning_sound_duration &24d2 20 84 23 JSR &2384 ; set_sound_channel_volume &24d5 ad 5c 3f LDA &3f5c ; warning_sound_frequency &24d8 4c 9a 23 JMP &239a ; set_sound_channel_frequency ; consider_updating_death_sound &24db ce 73 3f DEC &3f73 ; death_sound_cooldown &24de f0 01 BEQ &24e1 ; update_death_sound &24e0 60 RTS ; update_death_sound &24e1 a9 03 LDA #&03 &24e3 8d 73 3f STA &3f73 ; death_sound_cooldown &24e6 ee 71 3f INC &3f71 ; death_sound_frequency &24e9 ee 74 3f INC &3f74 ; death_sound_timer &24ec ad 74 3f LDA &3f74 ; death_sound_timer &24ef 29 03 AND #&03 &24f1 d0 0a BNE &24fd ; not_end_of_death_sound &24f3 ce 72 3f DEC &3f72 ; death_sound_volume &24f6 10 05 BPL &24fd ; not_end_of_death_sound &24f8 a9 00 LDA #&00 &24fa 8d 72 3f STA &3f72 ; death_sound_volume ; not_end_of_death_sound &24fd a2 02 LDX #&02 # Use channel 1 &24ff ad 71 3f LDA &3f71 ; death_sound_frequency &2502 20 9a 23 JSR &239a ; set_sound_channel_frequency &2505 a9 00 LDA #&00 &2507 20 84 23 JSR &2384 ; set_sound_channel_volume &250a a2 03 LDX #&03 # Use channel 0 &250c ad 72 3f LDA &3f72 ; death_sound_volume &250f 4c 84 23 JMP &2384 ; set_sound_channel_volume ; consider_updating_electric_sound &2512 ce 86 3f DEC &3f86 ; electric_sound_cooldown &2515 f0 01 BEQ &2518 ; update_electric_sound &2517 60 RTS ; update_electric_sound &2518 a9 03 LDA #&03 &251a 8d 86 3f STA &3f86 ; electric_sound_cooldown &251d ce 88 3f DEC &3f88 ; electric_sound_duration &2520 d0 0a BNE &252c ; not_end_of_electric_sound &2522 a9 00 LDA #&00 &2524 8d 84 3f STA &3f84 ; electric_sound_state # Set to zero to stop electric sound &2527 a2 00 LDX #&00 # Use channel 3 &2529 4c 84 23 JMP &2384 ; set_sound_channel_volume ; not_end_of_electric_sound &252c ce 89 3f DEC &3f89 ; electric_sound_frequency_delta_cooldown &252f d0 0d BNE &253e ; skip_changing_frequency_delta &2531 a9 0a LDA #&0a &2533 8d 89 3f STA &3f89 ; electric_sound_frequency_delta_cooldown &2536 ad 87 3f LDA &3f87 ; electric_sound_frequency_delta &2539 49 fe EOR #&fe &253b 8d 87 3f STA &3f87 ; electric_sound_frequency_delta ; skip_changing_frequency_delta &253e ad 85 3f LDA &3f85 ; electric_sound_frequency &2541 18 CLC &2542 6d 87 3f ADC &3f87 ; electric_sound_frequency_delta &2545 8d 85 3f STA &3f85 ; electric_sound_frequency &2548 a2 00 LDX #&00 # Use channel 3 &254a 20 9a 23 JSR &239a ; set_sound_channel_frequency &254d ad 88 3f LDA &3f88 ; electric_sound_volume &2550 4a LSR A &2551 c9 0f CMP #&0f &2553 90 02 BCC &2557 ; skip_ceiling &2555 a9 0f LDA #&0f ; skip_ceiling &2557 4c 84 23 JMP &2384 ; set_sound_channel_volume ; consider_updating_firing_sound &255a ce 50 3f DEC &3f50 ; firing_sound_cooldown &255d f0 01 BEQ &2560 ; update_firing_sound &255f 60 RTS ; update_firing_sound &2560 a9 02 LDA #&02 &2562 8d 50 3f STA &3f50 ; firing_sound_cooldown &2565 ce 4e 3f DEC &3f4e ; firing_sound_duration &2568 ce 4e 3f DEC &3f4e ; firing_sound_duration &256b 10 0a BPL &2577 ; not_end_of_firing_sound &256d a9 00 LDA #&00 &256f 8d 4d 3f STA &3f4d ; firing_sound_state # Set to zero to stop firing sound &2572 a2 01 LDX #&01 # Use channel 2 &2574 4c 84 23 JMP &2384 ; set_sound_channel_volume ; not_end_of_firing_sound &2577 ad 4e 3f LDA &3f4e ; firing_sound_duration &257a 29 07 AND #&07 &257c d0 03 BNE &2581 ; skip_reducing_volume &257e ce 4f 3f DEC &3f4f ; firing_sound_volume ; skip_reducing_volume &2581 a9 80 LDA #&80 &2583 38 SEC &2584 ed 4e 3f SBC &3f4e ; firing_sound_duration &2587 a2 01 LDX #&01 # Use channel 2 &2589 20 9a 23 JSR &239a ; set_sound_channel_frequency &258c ad 4f 3f LDA &3f4f ; firing_sound_volume &258f 4c 84 23 JMP &2384 ; set_sound_channel_volume ; start_explosion_sound &2592 a9 01 LDA #&01 &2594 8d 51 3f STA &3f51 ; explosion_sound_state # Set to non-zero to start explosion sound &2597 a9 0f LDA #&0f &2599 8d 52 3f STA &3f52 ; explosion_sound_frequency &259c a9 0f LDA #&0f &259e 8d 53 3f STA &3f53 ; explosion_sound_volume &25a1 a9 03 LDA #&03 &25a3 8d 54 3f STA &3f54 ; explosion_sound_cooldown &25a6 60 RTS ; consider_updating_explosion_sound &25a7 ce 54 3f DEC &3f54 ; explosion_sound_cooldown &25aa f0 01 BEQ &25ad ; update_explosion_sound &25ac 60 RTS ; update_explosion_sound &25ad a9 01 LDA #&01 &25af 8d 54 3f STA &3f54 ; explosion_sound_cooldown &25b2 ad 52 3f LDA &3f52 ; explosion_sound_frequency &25b5 38 SEC &25b6 e9 01 SBC #&01 &25b8 8d 52 3f STA &3f52 ; explosion_sound_frequency &25bb 10 15 BPL &25d2 ; skip_changing_volume &25bd ad 53 3f LDA &3f53 ; explosion_sound_volume &25c0 38 SEC &25c1 e9 03 SBC #&03 &25c3 10 0a BPL &25cf ; not_end_of_explosion_sound &25c5 a9 00 LDA #&00 &25c7 8d 51 3f STA &3f51 ; explosion_sound_state # Set to zero to stop explosion sound &25ca a2 03 LDX #&03 # Use channel 0 &25cc 4c 84 23 JMP &2384 ; set_sound_channel_volume ; not_end_of_explosion_sound &25cf 8d 53 3f STA &3f53 ; explosion_sound_volume ; skip_changing_volume &25d2 a2 02 LDX #&02 # Use channel 1 &25d4 ad 52 3f LDA &3f52 ; explosion_sound_frequency &25d7 20 9a 23 JSR &239a ; set_sound_channel_frequency &25da a2 03 LDX #&03 # Use channel 0 &25dc ad 53 3f LDA &3f53 ; explosion_sound_volume &25df 4c 84 23 JMP &2384 ; set_sound_channel_volume ; update_silos_and_rockets &25e2 a2 09 LDX #&09 ; update_silos_loop &25e4 bd d0 3e LDA &3ed0,X ; objects_silo_centre_screen_address_high &25e7 f0 1e BEQ &2607 ; consider_next_object # Zero if silo never fires rocket &25e9 bd b0 3e LDA &3eb0,X ; objects_silo_firing_position # Zero to check player's position before firing rocket &25ec f0 0d BEQ &25fb ; update_silo &25ee 29 1f AND #&1f # Otherwise, lowest five bits set z for rocket firing &25f0 85 70 STA &70 ; z &25f2 bd 00 3e LDA &3e00,X ; objects_z &25f5 c5 70 CMP &70 ; z &25f7 f0 02 BEQ &25fb ; update_silo &25f9 b0 0c BCS &2607 ; consider_next_object ; update_silo &25fb bd 60 3e LDA &3e60,X ; objects_type &25fe c9 03 CMP #&03 ; OBJECT_SILO &2600 d0 05 BNE &2607 ; consider_next_object &2602 20 32 26 JSR &2632 ; consider_adding_rocket &2605 a6 7f LDX &7f ; object_slot ; consider_next_object &2607 ca DEX &2608 10 da BPL &25e4 ; update_silos_loop ; unplot_rockets &260a a2 09 LDX #&09 ; unplot_rockets_loop &260c bd 60 3e LDA &3e60,X ; objects_type &260f c9 07 CMP #&07 ; OBJECT_ROCKET &2611 d0 05 BNE &2618 ; consider_next_object &2613 20 a3 26 JSR &26a3 ; unplot_rocket &2616 a6 7f LDX &7f ; object_slot ; consider_next_object &2618 ca DEX &2619 10 f1 BPL &260c ; unplot_rockets_loop &261b 20 02 1f JSR &1f02 ; update_player_shadow ; plot_rockets &261e a2 00 LDX #&00 ; plot_rockets_loop &2620 bd 60 3e LDA &3e60,X ; objects_type &2623 c9 07 CMP #&07 ; OBJECT_ROCKET &2625 d0 05 BNE &262c ; consider_next_object &2627 20 01 27 JSR &2701 ; plot_rocket &262a a6 7f LDX &7f ; object_slot ; consider_next_object &262c e8 INX &262d e0 0a CPX #&0a &262f d0 ef BNE &2620 ; plot_rockets_loop &2631 60 RTS ; consider_adding_rocket &2632 86 7f STX &7f ; object_slot &2634 bd b0 3e LDA &3eb0,X ; objects_silo_firing_position # Top bit set to always fire rocket at specified z &2637 30 2a BMI &2663 ; add_rocket &2639 ad 03 3f LDA &3f03 ; player_x # Otherwise, &263c dd 20 3e CMP &3e20,X ; objects_min_x # is the player aligned horizontally with the silo? &263f 90 05 BCC &2646 ; leave &2641 dd 30 3e CMP &3e30,X ; objects_max_x &2644 90 01 BCC &2647 ; check_y ; leave &2646 60 RTS ; check_y &2647 ad 02 3f LDA &3f02 ; player_y # If so, consider player's height &264a 38 SEC &264b e9 96 SBC #&96 &264d 4a LSR A &264e 4a LSR A &264f 48 PHA ; z &2650 38 SEC &2651 e9 07 SBC #&07 &2653 30 07 BMI &265c ; check_z &2655 dd 00 3e CMP &3e00,X ; objects_z &2658 90 02 BCC &265c ; check_z &265a 68 PLA ; z &265b 60 RTS ; check_z &265c 68 PLA ; z &265d dd 00 3e CMP &3e00,X ; objects_z &2660 b0 01 BCS &2663 ; add_rocket # Fire rocket if z <= (player_y - 96) / 4 < z + 7 &2662 60 RTS ; add_rocket &2663 a9 07 LDA #&07 ; OBJECT_ROCKET &2665 9d 60 3e STA &3e60,X ; objects_type &2668 a0 00 LDY #&00 &266a a2 00 LDX #&00 ; find_free_buffer_for_rocket_loop &266c b9 00 07 LDA &0700,Y ; rocket_buffers # Zero if buffer is not in use &266f f0 08 BEQ &2679 ; found_free_buffer &2671 98 TYA &2672 18 CLC &2673 69 29 ADC #&29 # Rocket buffer x is at &0700 + (&29 * x) &2675 a8 TAY &2676 e8 INX &2677 d0 f3 BNE &266c ; find_free_buffer_for_rocket_loop ; found_free_buffer &2679 a9 01 LDA #&01 &267b 99 00 07 STA &0700,Y ; rocket_buffers # Set to non-zero to indicate buffer in use &267e c8 INY &267f a6 7f LDX &7f ; object_slot &2681 98 TYA &2682 9d a0 3e STA &3ea0,X ; objects_rocket_buffer_address_low &2685 a9 0e LDA #&0e &2687 9d 90 3e STA &3e90,X ; objects_rocket_ttl &268a bd 70 3e LDA &3e70,X ; objects_screen_address_low &268d 38 SEC &268e e9 b8 SBC #&b8 &2690 9d 70 3e STA &3e70,X ; objects_screen_address_low &2693 bd 80 3e LDA &3e80,X ; objects_screen_address_high &2696 e9 03 SBC #&03 &2698 09 40 ORA #&40 &269a 9d 80 3e STA &3e80,X ; objects_screen_address_high &269d a9 14 LDA #&14 &269f 9d 50 3e STA &3e50,X ; objects_max_y &26a2 60 RTS ; unplot_rocket &26a3 86 7f STX &7f ; object_slot &26a5 bd 90 3e LDA &3e90,X ; objects_rocket_ttl &26a8 c9 0e CMP #&0e &26aa f0 1e BEQ &26ca ; unplot_new_rocket # Branch if rocket hasn't been plotted ; unplot_rocket_using_buffer &26ac bd 70 3e LDA &3e70,X ; objects_screen_address_low &26af 85 70 STA &70 ; screen_address_low &26b1 bd 80 3e LDA &3e80,X ; objects_screen_address_high &26b4 85 71 STA &71 ; screen_address_high &26b6 a9 07 LDA #&07 &26b8 85 73 STA &73 ; sprite_address_high &26ba bd a0 3e LDA &3ea0,X ; objects_rocket_buffer_address_low &26bd 85 72 STA &72 ; sprite_address_low &26bf a9 02 LDA #&02 &26c1 85 74 STA &74 ; sprite_width &26c3 a9 14 LDA #&14 &26c5 85 75 STA &75 ; sprite_height &26c7 4c a1 1e JMP &1ea1 ; plot_sprite # Unplot rocket ; unplot_new_rocket &26ca bd c0 3e LDA &3ec0,X ; objects_silo_centre_screen_address_low &26cd 85 70 STA &70 ; screen_address_low &26cf bd d0 3e LDA &3ed0,X ; objects_silo_centre_screen_address_high &26d2 85 71 STA &71 ; screen_address_high &26d4 a0 00 LDY #&00 &26d6 a2 03 LDX #&03 ; unplot_new_rocket_loop &26d8 a9 f0 LDA #&f0 ; 2222 &26da 91 70 STA (&70),Y ; screen_address # Unplot centre of silo &26dc e6 70 INC &70 ; screen_address_low &26de a5 70 LDA &70 ; screen_address_low &26e0 29 04 AND #&04 &26e2 f0 12 BEQ &26f6 ; not_group &26e4 a5 70 LDA &70 ; screen_address_high &26e6 18 CLC &26e7 69 3c ADC #&3c &26e9 85 70 STA &70 ; screen_address_low &26eb a5 71 LDA &71 ; screen_address_high &26ed 69 01 ADC #&01 &26ef 10 03 BPL &26f4 ; skip_wraparound &26f1 38 SEC &26f2 e9 40 SBC #&40 ; skip_wraparound &26f4 85 71 STA &71 ; screen_address_high ; not_group &26f6 ca DEX &26f7 10 df BPL &26d8 ; unplot_new_rocket_loop &26f9 a9 00 LDA #&00 &26fb a6 7f LDX &7f ; object_slot &26fd 9d d0 3e STA &3ed0,X ; objects_silo_centre_screen_address_high &2700 60 RTS ; plot_rocket &2701 86 7f STX &7f ; object_slot &2703 de 90 3e DEC &3e90,X ; objects_rocket_ttl &2706 10 14 BPL &271c ; plot_active_rocket &2708 a9 03 LDA #&03 ; OBJECT_SILO &270a 9d 60 3e STA &3e60,X ; objects_type # Don't update as rocket &270d a9 ff LDA #&ff &270f 9d 00 3e STA &3e00,X ; objects_z # Set to &ff to remove object &2712 bc a0 3e LDY &3ea0,X ; objects_rocket_buffer_address_low &2715 88 DEY &2716 a9 00 LDA #&00 &2718 99 00 07 STA &0700,Y ; rocket_buffers # Set to zero to indicate buffer is not in use &271b 60 RTS ; plot_active_rocket &271c bd 00 3e LDA &3e00,X ; objects_z &271f 10 08 BPL &2729 ; skip_floor &2721 a9 00 LDA #&00 &2723 9d 90 3e STA &3e90,X ; objects_rocket_ttl &2726 9d 00 3e STA &3e00,X ; objects_z ; skip_floor &2729 bd 50 3e LDA &3e50,X ; objects_max_y &272c 18 CLC &272d 69 04 ADC #&04 # Move rocket upwards &272f 9d 50 3e STA &3e50,X ; objects_max_y &2732 38 SEC &2733 e9 14 SBC #&14 &2735 9d 40 3e STA &3e40,X ; objects_min_y &2738 bd 70 3e LDA &3e70,X ; objects_screen_address_low &273b 38 SEC &273c e9 40 SBC #&40 &273e 9d 70 3e STA &3e70,X ; objects_screen_address_low &2741 85 70 STA &70 ; screen_address_low &2743 48 PHA ; screen_address_low &2744 bd 80 3e LDA &3e80,X ; objects_screen_address_high &2747 e9 01 SBC #&01 &2749 09 40 ORA #&40 &274b 9d 80 3e STA &3e80,X ; objects_screen_address_high &274e 85 71 STA &71 ; screen_address_high &2750 48 PHA ; screen_address_high &2751 bd a0 3e LDA &3ea0,X ; objects_rocket_buffer_address_low &2754 85 72 STA &72 ; buffer_address_low &2756 a9 07 LDA #&07 ; &0700 = rocket_buffers &2758 85 73 STA &73 ; buffer_address_high &275a a9 02 LDA #&02 &275c 48 PHA ; sprite_width &275d 85 74 STA &74 ; sprite_width &275f a9 14 LDA #&14 &2761 48 PHA ; sprite_height &2762 85 75 STA &75 ; sprite_height &2764 20 bd 1d JSR &1dbd ; buffer_sprite # Buffer rocket &2767 a6 7f LDX &7f ; object_slot &2769 68 PLA ; sprite_height &276a 85 75 STA &75 ; sprite_height &276c 68 PLA ; sprite_width &276d 85 74 STA &74 ; sprite_width &276f 68 PLA ; screen_address_high &2770 85 71 STA &71 ; screen_address_high &2772 68 PLA ; screen_address_low &2773 85 70 STA &70 ; screen_address_low &2775 a9 3b LDA #&3b &2777 85 73 STA &73 ; sprite_address_high &2779 bd 90 3e LDA &3e90,X ; objects_rocket_ttl &277c 08 PHP ; ttl &277d a0 78 LDY #&78 ; &3b78 = sprite_rocket_explosion # Use explosion if rocket is about to expire &277f 28 PLP ; ttl &2780 f0 07 BEQ &2789 ; set_sprite_address_low &2782 a0 50 LDY #&50 ; &3b50 = sprite_rocket_two # Otherwise animate rocket &2784 4a LSR A &2785 90 02 BCC &2789 ; set_sprite_address_low &2787 a0 28 LDY #&28 ; &3b28 = sprite_rocket_one ; set_sprite_address_low &2789 84 72 STY &72 ; sprite_address_low &278b 4c 1b 1e JMP &1e1b ; plot_masked_sprite # Plot rocket or rocket explosion ; update_turrets &278e a2 09 LDX #&09 ; update_turrets_loop &2790 bd 00 3e LDA &3e00,X ; objects_z # Negative if turret is behind player or removed &2793 30 15 BMI &27aa ; consider_next_object &2795 c9 04 CMP #&04 # Don't fire if turret is very near to player &2797 90 11 BCC &27aa ; consider_next_object &2799 bd a0 3e LDA &3ea0,X ; objects_turret_can_fire # Zero if turret has already fired &279c f0 0c BEQ &27aa ; consider_next_object &279e bd 60 3e LDA &3e60,X ; objects_type &27a1 c9 02 CMP #&02 ; OBJECT_TURRET &27a3 d0 05 BNE &27aa ; consider_next_object &27a5 20 c2 27 JSR &27c2 ; consider_adding_enemy_missile &27a8 a6 7f LDX &7f ; object_slot ; consider_next_object &27aa ca DEX &27ab 10 e3 BPL &2790 ; update_turrets_loop &27ad a2 01 LDX #&01 ; unplot_enemy_missiles_loop &27af bd 6a 3f LDA &3f6a,X ; enemy_missiles_state # Zero if no missile in slot &27b2 f0 05 BEQ &27b9 ; consider_next_enemy_missile &27b4 20 2c 28 JSR &282c ; unplot_enemy_missile &27b7 a6 7f LDX &7f ; enemy_missile_slot ; consider_next_enemy_missile &27b9 ca DEX &27ba 10 f3 BPL &27af ; unplot_enemy_missiles_loop &27bc 20 e2 25 JSR &25e2 ; update_silos_and_rockets &27bf 4c 52 28 JMP &2852 ; update_enemy_missiles ; consider_adding_enemy_missile &27c2 86 7f STX &7f ; object_slot &27c4 ad 03 3f LDA &3f03 ; player_x &27c7 dd 20 3e CMP &3e20,X ; objects_min_x # Is the player horizontally aligned with the turret? &27ca 90 1a BCC &27e6 ; leave &27cc dd 30 3e CMP &3e30,X ; objects_max_x &27cf b0 15 BCS &27e6 ; leave &27d1 ad 02 3f LDA &3f02 ; player_y &27d4 c9 a6 CMP #&a6 # Is the player low enough to be hit? &27d6 b0 0e BCS &27e6 ; leave &27d8 a0 00 LDY #&00 &27da ad 6a 3f LDA &3f6a ; enemy_missiles_state # Zero if no missile in first slot &27dd f0 08 BEQ &27e7 ; add_enemy_missile &27df a0 01 LDY #&01 &27e1 ad 6b 3f LDA &3f6b ; enemy_missiles_state + 1 # Zero if no missile in second slot &27e4 f0 01 BEQ &27e7 ; add_enemy_missile ; leave &27e6 60 RTS ; add_enemy_missile &27e7 bd 20 3e LDA &3e20,X ; objects_min_x &27ea 18 CLC &27eb 69 0a ADC #&0a &27ed 99 62 3f STA &3f62,Y ; enemy_missiles_target_screen_x &27f0 bd c0 3e LDA &3ec0,X ; objects_turret_initial_z &27f3 38 SEC &27f4 fd 00 3e SBC &3e00,X ; objects_z &27f7 0a ASL A &27f8 0a ASL A &27f9 85 70 STA &70 ; z_difference_times_four &27fb bd b0 3e LDA &3eb0,X ; objects_turret_initial_screen_y &27fe 38 SEC &27ff e5 70 SBC &70 ; z_difference_times_four &2801 85 70 STA &70 ; screen_y &2803 bd 00 3e LDA &3e00,X ; objects_z &2806 0a ASL A &2807 0a ASL A &2808 85 71 STA &71 ; z_times_four &280a a5 70 LDA &70 ; screen_y &280c 38 SEC &280d e5 71 SBC &71 ; z_times_four &280f 99 64 3f STA &3f64,Y ; enemy_missiles_target_screen_y &2812 a9 01 LDA #&01 &2814 99 6a 3f STA &3f6a,Y ; enemy_missiles_state # Set to non-zero to indicate missile in slot &2817 bd 00 3e LDA &3e00,X ; objects_z &281a 29 fe AND #&fe &281c 99 60 3f STA &3f60,Y ; enemy_missiles_z &281f a9 00 LDA #&00 &2821 99 68 3f STA &3f68,Y ; enemy_missiles_screen_address_high # Set to zero to indicate missile not plotted &2824 a6 7f LDX &7f ; object_slot &2826 9d a0 3e STA &3ea0,X ; objects_turret_can_fire # Set to zero to suppress turret firing &2829 4c 61 21 JMP &2161 ; start_firing_sound ; unplot_enemy_missile &282c 86 7f STX &7f ; enemy_missile_slot &282e bd 68 3f LDA &3f68,X ; enemy_missiles_screen_address_high # Non-zero if missile plotted &2831 d0 01 BNE &2834 ; needs_unplotting &2833 60 RTS ; needs_unplotting &2834 85 71 STA &71 ; screen_address_high &2836 bd 66 3f LDA &3f66,X ; enemy_missiles_screen_address_low &2839 85 70 STA &70 ; screen_address_low &283b a9 03 LDA #&03 &283d 85 74 STA &74 ; sprite_width &283f a9 07 LDA #&07 &2841 85 75 STA &75 ; sprite_height &2843 a9 08 LDA #&08 ; &0800 = first_enemy_missile_buffer &2845 85 73 STA &73 ; sprite_address_high &2847 e0 00 CPX #&00 &2849 f0 02 BEQ &284d ; set_sprite_address_low &284b a2 15 LDX #&15 ; &0815 = second_enemy_missile_buffer ; set_sprite_address_low &284d 86 72 STX &72 ; sprite_address_low &284f 4c a1 1e JMP &1ea1 ; plot_sprite # Unplot enemy missile ; update_enemy_missiles &2852 a2 00 LDX #&00 ; update_enemy_missiles_loop &2854 bd 6a 3f LDA &3f6a,X ; enemy_missiles_state # Zero if no missile in slot &2857 f0 05 BEQ &285e ; consider_next_missile &2859 20 64 28 JSR &2864 ; update_enemy_missile &285c a6 7f LDX &7f ; enemy_missile_slot ; consider_next_missile &285e e8 INX &285f e0 02 CPX #&02 &2861 d0 f1 BNE &2854 ; update_enemy_missiles_loop &2863 60 RTS ; update_enemy_missile &2864 86 7f STX &7f ; enemy_missile_slot &2866 bd 60 3f LDA &3f60,X ; enemy_missiles_z &2869 18 CLC &286a ac 8a 3f LDY &3f8a ; difficulty # Non-zero on level 3 and onwards &286d d0 01 BNE &2870 ; is_difficult &286f 38 SEC # Enemy missiles move half as fast on earlier levels ; is_difficult &2870 e9 02 SBC #&02 &2872 9d 60 3f STA &3f60,X ; enemy_missiles_z &2875 10 0a BPL &2881 ; still_present # Is the missile still on screen? &2877 c9 fc CMP #&fc &2879 b0 06 BCS &2881 ; still_present &287b a9 00 LDA #&00 &287d 9d 6a 3f STA &3f6a,X ; enemy_missiles_state # Set to zero to indicate no missile in slot &2880 60 RTS ; still_present &2881 0a ASL A &2882 0a ASL A &2883 85 76 STA &76 ; z &2885 18 CLC &2886 7d 64 3f ADC &3f64,X ; enemy_missiles_target_screen_y # screen_y = target_screen_y + (z * 4) &2889 a8 TAY &288a bd 62 3f LDA &3f62,X ; enemy_missiles_target_screen_x # screen_x = target_screen_x + z &288d 18 CLC &288e 65 76 ADC &76 ; z &2890 48 PHA ; screen_x &2891 aa TAX &2892 20 5f 12 JSR &125f ; calculate_screen_address &2895 a6 7f LDX &7f ; enemy_missile_slot &2897 a5 70 LDA &70 ; screen_address_low &2899 48 PHA ; screen_address_low &289a 9d 66 3f STA &3f66,X ; enemy_missiles_screen_address_low &289d a5 71 LDA &71 ; screen_address_high &289f 48 PHA ; screen_address_high &28a0 9d 68 3f STA &3f68,X ; enemy_missiles_screen_address_high &28a3 a9 03 LDA #&03 &28a5 85 74 STA &74 ; sprite_width &28a7 48 PHA ; sprite_width &28a8 a9 07 LDA #&07 &28aa 85 75 STA &75 ; sprite_height &28ac 48 PHA ; sprite_height &28ad a9 08 LDA #&08 ; &0800 = first_enemy_missile_buffer &28af 85 73 STA &73 ; buffer_address_high &28b1 a9 00 LDA #&00 &28b3 e0 00 CPX #&00 &28b5 f0 02 BEQ &28b9 ; set_buffer_address_low &28b7 a9 15 LDA #&15 ; &0815 = second_enemy_missile_buffer ; set_buffer_address_low &28b9 85 72 STA &72 ; buffer_address_low &28bb 20 bd 1d JSR &1dbd ; buffer_sprite # Buffer enemy missile &28be 68 PLA ; sprite_height &28bf 85 75 STA &75 ; sprite_height &28c1 68 PLA ; sprite_width &28c2 85 74 STA &74 ; sprite_width &28c4 68 PLA ; screen_address_high &28c5 85 71 STA &71 ; screen_address_high &28c7 68 PLA ; screen_address_low &28c8 85 70 STA &70 ; screen_address_low &28ca 68 PLA ; screen_x &28cb a0 a0 LDY #&a0 ; &3ca0 = sprite_enemy_missile_even &28cd 29 01 AND #&01 &28cf f0 02 BEQ &28d3 ; set_sprite_address_low &28d1 a0 b5 LDY #&b5 ; &3cb5 = sprite_enemy_missile_odd ; set_sprite_address_low &28d3 84 72 STY &72 ; sprite_address_low &28d5 a9 3c LDA #&3c &28d7 85 73 STA &73 ; sprite_address_high &28d9 20 1b 1e JSR &1e1b ; plot_masked_sprite # Plot enemy missile &28dc a6 7f LDX &7f ; enemy_missile_slot &28de bd 60 3f LDA &3f60,X ; enemy_missiles_z &28e1 c9 03 CMP #&03 # Is the missile near the player? &28e3 b0 0d BCS &28f2 ; leave &28e5 ac 8a 3f LDY &3f8a ; difficulty # Non-zero on level 3 and onwards &28e8 d0 04 BNE &28ee ; is_difficult &28ea c9 02 CMP #&02 &28ec b0 04 BCS &28f2 ; leave # Earlier levels need the missile to be nearer ; is_difficult &28ee 49 00 EOR #&00 # If the missile isn't beyond the player, check for collision &28f0 10 01 BPL &28f3 ; check_for_enemy_missile_collision_with_player ; leave &28f2 60 RTS ; check_for_enemy_missile_collision_with_player &28f3 bd 62 3f LDA &3f62,X ; enemy_missiles_target_screen_x # Calculate missile world_y &28f6 18 CLC &28f7 7d 64 3f ADC &3f64,X ; enemy_missiles_target_screen_y # world_y = screen_y + screen_x &28fa 38 SEC &28fb ed 02 3f SBC &3f02 ; player_y &28fe 18 CLC &28ff 69 0c ADC #&0c &2901 30 ef BMI &28f2 ; leave # Is the missile aligned with the player vertically? &2903 c9 10 CMP #&10 &2905 b0 eb BCS &28f2 ; leave &2907 bd 62 3f LDA &3f62,X ; enemy_missiles_target_screen_x # world_x = screen_x &290a 38 SEC &290b e9 08 SBC #&08 &290d cd 03 3f CMP &3f03 ; player_x &2910 b0 0c BCS &291e ; leave # Is the missile aligned with the player horizontally? &2912 69 09 ADC #&09 &2914 cd 03 3f CMP &3f03 ; player_x &2917 90 05 BCC &291e ; leave &2919 a9 01 LDA #&01 &291b 8d 6c 3f STA &3f6c ; player_destroyed # Set to non-zero to kill player (hit by enemy missile) ; leave &291e 60 RTS ; consider_updating_electric_fence &291f ad 82 3f LDA &3f82 ; electric_fence_state # Non-zero if electric fence needs plotting &2922 d0 01 BNE &2925 ; update_electric_fence ; leave &2924 60 RTS ; update_electric_fence &2925 ce 83 3f DEC &3f83 ; electric_fence_cooldown &2928 d0 fa BNE &2924 ; leave &292a a9 00 LDA #&00 &292c 8d 82 3f STA &3f82 ; electric_fence_state # Set to zero to indicate electric fence plotted &292f a9 5e LDA #&5e &2931 85 80 STA &80 ; fence_screen_x &2933 a9 ea LDA #&ea &2935 85 81 STA &81 ; fence_screen_y &2937 a9 10 LDA #&10 &2939 85 82 STA &82 ; count ; plot_electric_fence_loop &293b a6 80 LDX &80 ; fence_screen_x &293d a4 81 LDY &81 ; fence_screen_y &293f 20 5f 12 JSR &125f ; calculate_screen_address &2942 a9 01 LDA #&01 &2944 85 74 STA &74 ; sprite_width &2946 a9 0d LDA #&0d &2948 85 75 STA &75 ; sprite_height &294a a9 fa LDA #&fa ; &3cfa = sprite_electric_fence &294c 85 72 STA &72 ; sprite_address_low &294e a9 3c LDA #&3c &2950 85 73 STA &73 ; sprite_address_high &2952 20 1b 1e JSR &1e1b ; plot_masked_sprite # Plot part of electric fence &2955 a5 80 LDA &80 ; fence_screen_x &2957 18 CLC &2958 69 04 ADC #&04 &295a 85 80 STA &80 ; fence_screen_x &295c a5 81 LDA &81 ; fence_screen_y &295e 38 SEC &295f e9 04 SBC #&04 &2961 85 81 STA &81 ; fence_screen_y &2963 c6 82 DEC &82 ; count &2965 d0 d4 BNE &293b ; plot_electric_fence_loop &2967 a9 dc LDA #&dc &2969 8d 85 3f STA &3f85 ; electric_sound_frequency &296c a9 5a LDA #&5a &296e 8d 88 3f STA &3f88 ; electric_sound_volume &2971 a9 0a LDA #&0a &2973 8d 89 3f STA &3f89 ; electric_sound_frequency_delta_cooldown &2976 a9 01 LDA #&01 &2978 8d 86 3f STA &3f86 ; electric_sound_cooldown &297b 8d 87 3f STA &3f87 ; electric_sound_frequency_delta &297e 8d 84 3f STA &3f84 ; electric_sound_state # Set to non-zero to start electric sound &2981 60 RTS ; to_update_fuel &2982 4c a3 29 JMP &29a3 ; update_fuel ; to_add_XY_to_score &2985 4c 31 2a JMP &2a31 ; add_XY_to_score ; to_update_score_and_lives &2988 4c 5e 2a JMP &2a5e ; update_score_and_lives ; to_unplot_player &298b 4c 49 2b JMP &2b49 ; unplot_player ; to_unplot_player_shadow &298e 4c 70 2b JMP &2b70 ; unplot_player_shadow ; to_explode_player &2991 4c b8 2b JMP &2bb8 ; explode_player ; to_calculate_position_of_fighter &2994 4c a0 2c JMP &2ca0 ; calculate_position_of_fighter ; to_consider_updating_fighter &2997 4c 87 2d JMP &2d87 ; consider_updating_fighter ; to_check_for_collision_with_fighter &299a 4c ba 2e JMP &2eba ; check_for_collision_with_fighter ; to_completion_screen &299d 4c 36 2f JMP &2f36 ; completion_screen ; to_high_score_screen_then_wait_for_space_or_fire &29a0 4c 6c 2c JMP &2c6c ; high_score_screen_then_wait_for_space_or_fire ; update_fuel &29a3 ce 6e 3f DEC &3f6e ; player_fuel_drain_cooldown &29a6 d0 1a BNE &29c2 ; plot_fuel &29a8 ad 6f 3f LDA &3f6f ; player_fuel_drain_maximum_cooldown &29ab 8d 6e 3f STA &3f6e ; player_fuel_drain_cooldown &29ae ad 6d 3f LDA &3f6d ; player_fuel &29b1 f0 0f BEQ &29c2 ; plot_fuel &29b3 ce 6d 3f DEC &3f6d ; player_fuel &29b6 ad 6d 3f LDA &3f6d ; player_fuel &29b9 c9 04 CMP #&04 &29bb b0 05 BCS &29c2 ; plot_fuel &29bd a9 00 LDA #&00 &29bf 8d 6d 3f STA &3f6d ; player_fuel ; plot_fuel &29c2 a9 10 LDA #&10 &29c4 cd 6d 3f CMP &3f6d ; player_fuel &29c7 90 0a BCC &29d3 ; skip_warning &29c9 ad 6e 3f LDA &3f6e ; player_fuel_drain_cooldown &29cc 29 01 AND #&01 &29ce f0 03 BEQ &29d3 ; skip_warning &29d0 4c 1e 2a JMP &2a1e ; start_warning_sound ; skip_warning &29d3 a2 68 LDX #&68 # Left of fuel bar &29d5 a0 3b LDY #&3b &29d7 20 aa 1c JSR &1caa ; to_calculate_screen_address &29da a2 0e LDX #&0e &29dc ad 6d 3f LDA &3f6d ; player_fuel &29df 48 PHA ; player_fuel &29e0 4a LSR A &29e1 4a LSR A &29e2 8d 6d 3f STA &3f6d ; player_fuel ; plot_fuel_loop &29e5 a9 ff LDA #&ff ; 3333 # Plot white for full section &29e7 ec 6d 3f CPX &3f6d ; player_fuel &29ea 90 0e BCC &29fa ; plot_fuel_section &29ec 08 PHP ; is partial section &29ed a9 0f LDA #&0f ; 1111 # Plot red for empty section &29ef 28 PLP ; is partial section &29f0 d0 08 BNE &29fa ; plot_fuel_section &29f2 68 PLA ; player_fuel &29f3 48 PHA ; player_fuel &29f4 29 03 AND #&03 &29f6 a8 TAY &29f7 b9 1a 2a LDA &2a1a,Y ; fuel_pixel_values # Plot value for partial section ; plot_fuel_section &29fa a0 03 LDY #&03 ; plot_fuel_section_byte_loop &29fc 91 70 STA (&70),Y ; screen_address # Plot section of fuel bar &29fe 88 DEY &29ff 10 fb BPL &29fc ; plot_fuel_section_byte_loop &2a01 a5 70 LDA &70 ; screen_address_low &2a03 18 CLC &2a04 69 08 ADC #&08 # Move right four pixels &2a06 85 70 STA &70 ; screen_address_low &2a08 a5 71 LDA &71 ; screen_address_high &2a0a 69 00 ADC #&00 &2a0c 10 02 BPL &2a10 ; skip_wraparound &2a0e e9 3f SBC #&3f ; skip_wraparound &2a10 85 71 STA &71 ; screen_address_high &2a12 ca DEX &2a13 d0 d0 BNE &29e5 ; plot_fuel_loop &2a15 68 PLA ; player_fuel &2a16 8d 6d 3f STA &3f6d ; player_fuel &2a19 60 RTS ; fuel_pixel_values &2a1a 1f ; 1113 &2a1b 3f ; 1133 &2a1c 7f ; 1333 &2a1d ff ; 3333 ; start_warning_sound &2a1e a9 01 LDA #&01 &2a20 8d 5b 3f STA &3f5b ; warning_sound_state # Set to non-zero to start warning sound &2a23 8d 5e 3f STA &3f5e ; warning_sound_cooldown &2a26 a9 14 LDA #&14 &2a28 8d 5c 3f STA &3f5c ; warning_sound_frequency &2a2b a9 0f LDA #&0f &2a2d 8d 5d 3f STA &3f5d ; warning_sound_duration &2a30 60 RTS ; add_XY_to_score &2a31 f8 SED &2a32 8a TXA &2a33 18 CLC &2a34 6d 58 3f ADC &3f58 ; score &2a37 8d 58 3f STA &3f58 ; score &2a3a 98 TYA &2a3b 6d 59 3f ADC &3f59 ; score + 1 &2a3e 8d 59 3f STA &3f59 ; score + 1 &2a41 08 PHP ; overflow &2a42 a9 00 LDA #&00 &2a44 6d 5a 3f ADC &3f5a ; score + 2 &2a47 8d 5a 3f STA &3f5a ; score + 2 &2a4a 28 PLP ; overflow &2a4b d8 CLD &2a4c 90 0f BCC &2a5d ; skip_extra_life # Gain extra life at 10,000 points &2a4e ad 57 3f LDA &3f57 ; suppress_extra_life &2a51 d0 0a BNE &2a5d ; skip_extra_life &2a53 ee 57 3f INC &3f57 ; suppress_extra_life &2a56 e6 07 INC &07 ; initial_suppress_extra_life &2a58 ee 5f 3f INC &3f5f ; player_lives &2a5b e6 02 INC &02 ; initial_player_lives ; skip_extra_life &2a5d 60 RTS ; update_score_and_lives &2a5e ad 08 3f LDA &3f08 ; screen_start_address_low &2a61 18 CLC &2a62 69 40 ADC #&40 &2a64 85 70 STA &70 ; screen_address_low &2a66 ad 09 3f LDA &3f09 ; screen_start_address_high &2a69 69 01 ADC #&01 &2a6b 10 02 BPL &2a6f ; skip_wraparound &2a6d e9 3f SBC #&3f ; skip_wraparound &2a6f 85 71 STA &71 ; screen_address_high &2a71 a5 70 LDA &70 ; screen_address_low &2a73 18 CLC &2a74 69 40 ADC #&40 &2a76 85 72 STA &72 ; bottom_screen_address_low &2a78 a5 71 LDA &71 ; screen_address_high &2a7a 69 01 ADC #&01 &2a7c 10 02 BPL &2a80 ; skip_wraparound &2a7e e9 3f SBC #&3f ; skip_wraparound &2a80 85 73 STA &73 ; bottom_screen_address_high &2a82 a2 0a LDX #&0a ; unplot_score_column_loop &2a84 a0 03 LDY #&03 &2a86 a9 f0 LDA #&f0 ; unplot_score_byte_loop &2a88 91 70 STA (&70),Y ; screen_address # Wipe top four rows &2a8a 91 72 STA (&72),Y ; bottom_screen_address # Wipe bottom four rows &2a8c 88 DEY &2a8d 10 f9 BPL &2a88 ; unplot_score_byte_loop &2a8f a5 70 LDA &70 ; screen_address_low &2a91 18 CLC &2a92 69 08 ADC #&08 # Move right four pixels &2a94 85 70 STA &70 ; screen_address_low &2a96 a5 71 LDA &71 ; screen_address_high &2a98 69 00 ADC #&00 &2a9a 10 02 BPL &2a9e ; skip_wraparound &2a9c e9 3f SBC #&3f ; skip_wraparound &2a9e 85 71 STA &71 ; screen_address_high &2aa0 a5 72 LDA &72 ; bottom_screen_address_low &2aa2 18 CLC &2aa3 69 08 ADC #&08 # Move right four pixels &2aa5 85 72 STA &72 ; bottom_screen_address_low &2aa7 a5 73 LDA &73 ; bottom_screen_address_high &2aa9 69 00 ADC #&00 &2aab 10 02 BPL &2aaf ; skip_wraparound &2aad e9 3f SBC #&3f ; skip_wraparound &2aaf 85 73 STA &73 ; bottom_screen_address_high &2ab1 ca DEX &2ab2 d0 d0 BNE &2a84 ; unplot_score_column_loop &2ab4 ad 08 3f LDA &3f08 ; screen_start_address_low &2ab7 18 CLC &2ab8 69 40 ADC #&40 &2aba 85 70 STA &70 ; screen_address_low &2abc ad 09 3f LDA &3f09 ; screen_start_address_high &2abf 69 00 ADC #&00 &2ac1 10 02 BPL &2ac5 ; skip_wraparound &2ac3 e9 3f SBC #&3f ; skip_wraparound &2ac5 85 71 STA &71 ; screen_address_high &2ac7 a2 00 LDX #&00 &2ac9 86 7f STX &7f ; leading_zero &2acb e8 INX ; 1 &2acc 86 7e STX &7e ; last_digit &2ace ad 5f 3f LDA &3f5f ; player_lives &2ad1 20 fe 2a JSR &2afe ; plot_number # Plot lives &2ad4 ad 08 3f LDA &3f08 ; screen_start_address_low &2ad7 18 CLC &2ad8 69 08 ADC #&08 &2ada 85 70 STA &70 ; source_address_low &2adc ad 09 3f LDA &3f09 ; screen_start_address_high &2adf 69 00 ADC #&00 &2ae1 10 02 BPL &2ae5 ; skip_wraparound &2ae3 e9 3f SBC #&3f ; skip_wraparound &2ae5 85 71 STA &71 ; screen_address_high &2ae7 a9 00 LDA #&00 &2ae9 85 7f STA &7f ; leading_zero &2aeb 85 7e STA &7e ; last_digit &2aed ad 5a 3f LDA &3f5a ; score + 2 &2af0 20 fe 2a JSR &2afe ; plot_number # Plot score &2af3 ad 59 3f LDA &3f59 ; score + 1 &2af6 20 fe 2a JSR &2afe ; plot_number &2af9 ad 58 3f LDA &3f58 ; score &2afc e6 7e INC &7e ; last_digit ; plot_number &2afe 48 PHA ; number &2aff 29 f0 AND #&f0 &2b01 4a LSR A &2b02 aa TAX &2b03 05 7f ORA &7f ; leading_zero &2b05 85 7f STA &7f ; leading_zero &2b07 8a TXA &2b08 20 19 2b JSR &2b19 ; plot_digit &2b0b 68 PLA ; number &2b0c 0a ASL A &2b0d 0a ASL A &2b0e 0a ASL A &2b0f 29 78 AND #&78 &2b11 aa TAX &2b12 05 7f ORA &7f ; leading_zero &2b14 05 7e ORA &7e ; last_digit &2b16 85 7f STA &7f ; leading_zero &2b18 8a TXA ; plot_digit &2b19 18 CLC &2b1a 69 b0 ADC #&b0 ; &2fb0 = digit_sprites &2b1c 85 72 STA &72 ; sprite_address_low &2b1e a9 2f LDA #&2f &2b20 69 00 ADC #&00 &2b22 85 73 STA &73 ; sprite_address_high &2b24 a9 01 LDA #&01 &2b26 85 74 STA &74 ; sprite_width &2b28 a9 07 LDA #&07 &2b2a 85 75 STA &75 ; sprite_height &2b2c a5 70 LDA &70 ; screen_address_low &2b2e 18 CLC &2b2f 69 08 ADC #&08 &2b31 48 PHA ; next_screen_address_low &2b32 a5 71 LDA &71 ; screen_address_high &2b34 69 00 ADC #&00 &2b36 10 02 BPL &2b3a ; skip_wraparound &2b38 e9 3f SBC #&3f ; skip_wraparound &2b3a 48 PHA ; next_screen_address_high &2b3b a5 7f LDA &7f ; leading_zero &2b3d f0 03 BEQ &2b42 ; skip_plotting_digit &2b3f 20 ad 1c JSR &1cad ; to_plot_masked_sprite ; skip_plotting_digit &2b42 68 PLA ; next_screen_address_high &2b43 85 71 STA &71 ; screen_address_high &2b45 68 PLA ; next_screen_address_low &2b46 85 70 STA &70 ; screen_address_low &2b48 60 RTS ; unplot_player &2b49 20 55 2b JSR &2b55 ; use_player_buffer &2b4c 4c b0 1c JMP &1cb0 ; to_plot_sprite ; buffer_player &2b4f 20 55 2b JSR &2b55 ; use_player_buffer &2b52 4c b3 1c JMP &1cb3 ; to_buffer_sprite # Buffer player ; use_player_buffer &2b55 ad 04 3f LDA &3f04 ; player_screen_address_low &2b58 85 70 STA &70 ; screen_address_low &2b5a ad 05 3f LDA &3f05 ; player_screen_address_high &2b5d 85 71 STA &71 ; screen_address_high &2b5f a9 00 LDA #&00 ; &0600 = player_buffer &2b61 85 72 STA &72 ; sprite_address_low &2b63 a9 06 LDA #&06 &2b65 85 73 STA &73 ; sprite_address_high &2b67 a9 04 LDA #&04 &2b69 85 74 STA &74 ; sprite_width &2b6b a9 0d LDA #&0d &2b6d 85 75 STA &75 ; sprite_height &2b6f 60 RTS ; unplot_player_shadow &2b70 ad 06 3f LDA &3f06 ; player_shadow_screen_address_low &2b73 85 70 STA &70 ; screen_address_low &2b75 ad 07 3f LDA &3f07 ; player_shadow_screen_address_high &2b78 85 71 STA &71 ; screen_address_high &2b7a a9 34 LDA #&34 ; &0634 = player_shadow_buffer &2b7c 85 72 STA &72 ; sprite_address_low &2b7e a9 06 LDA #&06 &2b80 85 73 STA &73 ; sprite_address_high &2b82 a9 04 LDA #&04 &2b84 85 74 STA &74 ; sprite_width &2b86 a9 0d LDA #&0d &2b88 85 75 STA &75 ; sprite_height &2b8a 4c b0 1c JMP &1cb0 ; to_plot_sprite # Unplot player shadow ; plot_sprite_at_player &2b8d ad 04 3f LDA &3f04 ; player_screen_address_low &2b90 85 70 STA &70 ; screen_address_low &2b92 ad 05 3f LDA &3f05 ; player_screen_address_high &2b95 85 71 STA &71 ; screen_address_high &2b97 a9 04 LDA #&04 &2b99 85 74 STA &74 ; sprite_width &2b9b a9 0d LDA #&0d &2b9d 85 75 STA &75 ; sprite_height &2b9f 4c ad 1c JMP &1cad ; to_plot_masked_sprite ; plot_player_explosion_one &2ba2 a9 39 LDA #&39 ; &39b4 = sprite_player_explosion_one &2ba4 85 73 STA &73 ; sprite_address_high &2ba6 a9 b4 LDA #&b4 &2ba8 85 72 STA &72 ; sprite_address_low &2baa 4c 8d 2b JMP &2b8d ; plot_sprite_at_player ; plot_player_explosion_two &2bad a9 3a LDA #&3a ; &3a1c = sprite_player_explosion_two &2baf 85 73 STA &73 ; sprite_address_high &2bb1 a9 1c LDA #&1c &2bb3 85 72 STA &72 ; sprite_address_low &2bb5 4c 8d 2b JMP &2b8d ; plot_sprite_at_player ; explode_player &2bb8 a9 27 LDA #&27 &2bba 85 08 STA &08 ; nop_cascade_frequency # Call NOP cascade more frequently &2bbc 20 86 2c JSR &2c86 ; start_death_sound &2bbf 20 49 2b JSR &2b49 ; unplot_player &2bc2 20 70 2b JSR &2b70 ; unplot_player_shadow &2bc5 20 4f 2b JSR &2b4f ; buffer_player # Buffer player explosion &2bc8 a9 32 LDA #&32 &2bca 85 80 STA &80 ; count ; explode_player_loop &2bcc 20 b6 1c JSR &1cb6 ; to_rnd &2bcf 29 0f AND #&0f &2bd1 09 80 ORA #&80 # Set colour 2 to random colour &2bd3 20 b9 1c JSR &1cb9 ; to_set_palette &2bd6 20 b6 1c JSR &1cb6 ; to_rnd &2bd9 29 0f AND #&0f &2bdb 09 20 ORA #&20 # Set colour 1 to random colour &2bdd 20 b9 1c JSR &1cb9 ; to_set_palette &2be0 20 b6 1c JSR &1cb6 ; to_rnd &2be3 29 08 AND #&08 &2be5 09 07 ORA #&07 # Enable or disable Shift Lock LED at random &2be7 8d 40 fe STA &fe40 ; System VIA port B input/output register &2bea 20 b6 1c JSR &1cb6 ; to_rnd &2bed 29 08 AND #&08 &2bef 09 06 ORA #&06 # Enable or disable Caps Lock LED at random &2bf1 8d 40 fe STA &fe40 ; System VIA port B input/output register &2bf4 20 b6 1c JSR &1cb6 ; to_rnd &2bf7 29 0f AND #&0f &2bf9 09 a0 ORA #&a0 # Set colour 3 to random colour &2bfb 20 b9 1c JSR &1cb9 ; to_set_palette &2bfe 20 b6 1c JSR &1cb6 ; to_rnd &2c01 29 0f AND #&0f # Set colour 0 to random colour &2c03 20 b9 1c JSR &1cb9 ; to_set_palette &2c06 a5 80 LDA &80 ; count &2c08 29 03 AND #&03 &2c0a f0 0f BEQ &2c1b ; skip_replotting_player_explosion &2c0c a5 80 LDA &80 ; count &2c0e 29 02 AND #&02 &2c10 f0 06 BEQ &2c18 ; use_player_explosion_two &2c12 20 a2 2b JSR &2ba2 ; plot_player_explosion_one # Plot player explosion &2c15 4c 1b 2c JMP &2c1b ; skip_replotting_player_explosion ; use_player_explosion_two &2c18 20 ad 2b JSR &2bad ; plot_player_explosion_two ; skip_replotting_player_explosion &2c1b a2 02 LDX #&02 ; delay_loop &2c1d 20 bc 1c JSR &1cbc ; to_wait_for_vsync &2c20 ca DEX &2c21 d0 fa BNE &2c1d ; delay_loop &2c23 20 49 2b JSR &2b49 ; unplot_player # Unplot player explosion &2c26 c6 80 DEC &80 ; count &2c28 d0 a2 BNE &2bcc ; explode_player_loop &2c2a 20 49 2b JSR &2b49 ; unplot_player # Unnecessary code; already unplotted &2c2d a9 04 LDA #&04 # Set colour 0 to blue &2c2f 20 b9 1c JSR &1cb9 ; to_set_palette &2c32 a9 a7 LDA #&a7 # Set colour 3 to white &2c34 20 b9 1c JSR &1cb9 ; to_set_palette &2c37 a9 80 LDA #&80 # Set colour 2 to black &2c39 20 b9 1c JSR &1cb9 ; to_set_palette &2c3c a9 21 LDA #&21 # Set colour 1 to red &2c3e 20 b9 1c JSR &1cb9 ; to_set_palette &2c41 a2 0f LDX #&0f # Switch off Caps Lock LED &2c43 8e 40 fe STX &fe40 ; System VIA port B input/output register &2c46 ca DEX ; &0e # Switch off Shift Lock LED &2c47 8e 40 fe STX &fe40 ; System VIA port B input/output register &2c4a ce 5f 3f DEC &3f5f ; player_lives &2c4d a2 64 LDX #&64 ; delay_loop &2c4f 20 bc 1c JSR &1cbc ; to_wait_for_vsync &2c52 ca DEX &2c53 d0 fa BNE &2c4f ; delay_loop &2c55 c6 02 DEC &02 ; initial_player_lives &2c57 f0 13 BEQ &2c6c ; high_score_screen_then_wait_for_space_or_fire &2c59 a2 02 LDX #&02 ; backup_score_loop &2c5b bd 58 3f LDA &3f58,X ; score &2c5e 95 03 STA &03,X ; initial_score &2c60 ca DEX &2c61 10 f8 BPL &2c5b ; backup_score_loop &2c63 a5 09 LDA &09 ; initial_boss_energy &2c65 d0 02 BNE &2c69 ; skip_reset &2c67 e6 09 INC &09 ; initial_boss_energy ; skip_reset &2c69 4c c2 1c JMP &1cc2 ; to_start_level ; high_score_screen_then_wait_for_space_or_fire &2c6c 20 00 0f JSR &0f00 ; check_for_high_score ; wait_for_space_or_fire &2c6f a9 00 LDA #&00 &2c71 85 21 STA &21 ; keyboard_or_joystick # Set to zero to use keyboard &2c73 a2 62 LDX #&62 ; SPACE &2c75 20 bf 1c JSR &1cbf ; to_check_for_keypress &2c78 d0 09 BNE &2c83 ; space_pressed &2c7a e6 21 INC &21 ; keyboard_or_joystick # Set to non-zero to use joystick &2c7c ad 40 fe LDA &fe40 ; System VIA port B input/output register # &10 clear if first joystick button pressed &2c7f 29 10 AND #&10 &2c81 d0 ec BNE &2c6f ; wait_for_space_or_fire ; space_pressed &2c83 4c c8 1c JMP &1cc8 ; to_start_game ; start_death_sound &2c86 a2 01 LDX #&01 &2c88 8e 70 3f STX &3f70 ; death_sound_state # Set to non-zero to start death sound &2c8b 8e 73 3f STX &3f73 ; death_sound_cooldown &2c8e 8e 74 3f STX &3f74 ; death_sound_timer &2c91 a9 0a LDA #&0a &2c93 8d 71 3f STA &3f71 ; death_sound_frequency &2c96 a9 0f LDA #&0f &2c98 8d 72 3f STA &3f72 ; death_sound_volume &2c9b ca DEX ; 0 &2c9c 8e 51 3f STX &3f51 ; explosion_sound_state # Set to zero to stop explosion sound &2c9f 60 RTS ; calculate_position_of_fighter &2ca0 a9 1c LDA #&1c &2ca2 8d 76 3f STA &3f76 ; fighter_z # Set to non-zero to activate fighter &2ca5 a9 c5 LDA #&c5 &2ca7 8d 77 3f STA &3f77 ; fighter_y &2caa a9 2d LDA #&2d &2cac 8d 78 3f STA &3f78 ; fighter_x &2caf a9 00 LDA #&00 &2cb1 8d 7f 3f STA &3f7f ; fighter_has_fired # Set to zero to allow fighter to fire ; plot_fighter_and_shadow &2cb4 ad 76 3f LDA &3f76 ; fighter_z &2cb7 38 SEC &2cb8 e9 04 SBC #&04 &2cba 0a ASL A &2cbb 0a ASL A &2cbc 85 81 STA &81 ; z_minus_one_times_four &2cbe ad 78 3f LDA &3f78 ; fighter_x # Calculate fighter screen x &2cc1 18 CLC &2cc2 65 81 ADC &81 ; z_minus_one_times_four # screen_x = world_x + ((z - 1) * 4) &2cc4 aa TAX &2cc5 86 80 STX &80 ; fighter_screen_x &2cc7 ad 77 3f LDA &3f77 ; fighter_y # Calculate fighter screen y &2cca 65 81 ADC &81 ; z_minus_one_times_four &2ccc 38 SEC &2ccd ed 78 3f SBC &3f78 ; fighter_x # screen_y = world_y + ((z - 1) * 4) - world_x &2cd0 a8 TAY &2cd1 20 aa 1c JSR &1caa ; to_calculate_screen_address &2cd4 a5 70 LDA &70 ; screen_address_low &2cd6 48 PHA ; screen_address_low &2cd7 8d 79 3f STA &3f79 ; fighter_screen_address_low &2cda a5 71 LDA &71 ; screen_address_high &2cdc 48 PHA ; screen_address_high &2cdd 8d 7a 3f STA &3f7a ; fighter_screen_address_high &2ce0 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2ce3 a9 08 LDA #&08 ; &082a = fighter_buffer &2ce5 85 73 STA &73 ; sprite_address_high &2ce7 a9 2a LDA #&2a &2ce9 85 72 STA &72 ; sprite_address_low &2ceb 20 b3 1c JSR &1cb3 ; to_buffer_sprite # Buffer fighter &2cee a9 3b LDA #&3b &2cf0 85 73 STA &73 ; sprite_address_high &2cf2 a0 b0 LDY #&b0 ; &3bb0 = sprite_fighter_even &2cf4 a5 80 LDA &80 ; fighter_screen_x &2cf6 29 02 AND #&02 &2cf8 d0 03 BNE &2cfd ; set_sprite_address_low &2cfa a8 TAY ; 0 &2cfb e6 73 INC &73 ; sprite_address_high ; &3c00 = sprite_fighter_odd ; set_sprite_address_low &2cfd 84 72 STY &72 ; sprite_address_low &2cff 68 PLA ; screen_address_high &2d00 85 71 STA &71 ; screen_address_high &2d02 68 PLA ; screen_address_low &2d03 85 70 STA &70 ; screen_address_low &2d05 a5 72 LDA &72 ; sprite_address_low &2d07 48 PHA ; sprite_address_low &2d08 a5 73 LDA &73 ; sprite_address_high &2d0a 48 PHA ; sprite_address_high &2d0b 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2d0e 20 ad 1c JSR &1cad ; to_plot_masked_sprite # Plot fighter &2d11 a6 80 LDX &80 ; fighter_screen_x &2d13 a9 90 LDA #&90 # Plot shadow on ground (y = &90) &2d15 18 CLC &2d16 65 81 ADC &81 ; tmp &2d18 38 SEC &2d19 ed 78 3f SBC &3f78 ; fighter_x &2d1c a8 TAY &2d1d 20 aa 1c JSR &1caa ; to_calculate_screen_address &2d20 a5 70 LDA &70 ; screen_address_low &2d22 8d 7b 3f STA &3f7b ; fighter_shadow_screen_address_low &2d25 48 PHA ; screen_address_low &2d26 a5 71 LDA &71 ; screen_address_high &2d28 8d 7c 3f STA &3f7c ; fighter_shadow_screen_address_high &2d2b 48 PHA ; screen_address_high &2d2c 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2d2f a9 08 LDA #&08 ; &087a = fighter_shadow_buffer &2d31 85 73 STA &73 ; sprite_address_high &2d33 a9 7a LDA #&7a &2d35 85 72 STA &72 ; sprite_address_low &2d37 20 b3 1c JSR &1cb3 ; to_buffer_sprite # Buffer fighter shadow &2d3a 68 PLA ; screen_address_high &2d3b 85 71 STA &71 ; screen_address_high &2d3d 68 PLA ; screen_address_low &2d3e 85 70 STA &70 ; screen_address_low &2d40 68 PLA ; sprite_address_low &2d41 85 73 STA &73 ; sprite_address_high &2d43 68 PLA ; sprite_address_high &2d44 85 72 STA &72 ; sprite_address_low &2d46 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2d49 4c cb 1c JMP &1ccb ; to_plot_shadow_column_loop # Plot fighter shadow ; use_fighter_sprite_sizes &2d4c a9 04 LDA #&04 &2d4e 85 74 STA &74 ; sprite_width &2d50 a9 14 LDA #&14 &2d52 85 75 STA &75 ; sprite_height &2d54 60 RTS ; unplot_fighter &2d55 ad 7b 3f LDA &3f7b ; fighter_shadow_screen_address_low &2d58 85 70 STA &70 ; screen_address_low &2d5a ad 7c 3f LDA &3f7c ; fighter_shadow_screen_address_high &2d5d 85 71 STA &71 ; screen_address_high &2d5f f0 0e BEQ &2d6f ; skip_unplotting_fighter_shadow &2d61 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2d64 a9 08 LDA #&08 ; &087a = fighter_shadow_buffer &2d66 85 73 STA &73 ; sprite_address_high &2d68 a9 7a LDA #&7a &2d6a 85 72 STA &72 ; sprite_address_low &2d6c 20 b0 1c JSR &1cb0 ; to_plot_sprite # Unplot fighter shadow ; skip_unplotting_fighter_shadow &2d6f ad 79 3f LDA &3f79 ; fighter_screen_address_low &2d72 85 70 STA &70 ; screen_address_low &2d74 ad 7a 3f LDA &3f7a ; fighter_screen_address_high &2d77 85 71 STA &71 ; screen_address_high &2d79 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2d7c a9 08 LDA #&08 ; &082a = fighter_buffer &2d7e 85 73 STA &73 ; sprite_address_high &2d80 a9 2a LDA #&2a &2d82 85 72 STA &72 ; sprite_address_low &2d84 4c b0 1c JMP &1cb0 ; to_plot_sprite # Unplot fighter ; consider_updating_fighter &2d87 ad 76 3f LDA &3f76 ; fighter_z # Non-zero if fighter is active &2d8a d0 03 BNE &2d8f ; update_fighter &2d8c 4c ce 1c JMP &1cce ; to_update_turrets ; update_fighter &2d8f 20 55 2d JSR &2d55 ; unplot_fighter &2d92 20 ce 1c JSR &1cce ; to_update_turrets &2d95 ad 7e 3f LDA &3f7e ; fighter_explosion_state # Zero if fighter is not exploding &2d98 f0 0e BEQ &2da8 ; check_for_fighter_collision_with_player &2d9a ce 7e 3f DEC &3f7e ; fighter_explosion_state &2d9d c9 02 CMP #&02 # Two if fighter has just been hit by missile &2d9f f0 04 BEQ &2da5 ; to_explode_fighter &2da1 ce 76 3f DEC &3f76 ; fighter_z # Set to zero to remove fighter &2da4 60 RTS ; to_explode_fighter &2da5 4c f0 2e JMP &2ef0 ; explode_fighter ; check_for_fighter_collision_with_player &2da8 ad 7d 3f LDA &3f7d ; fighter_homing_energy # Non-zero if fighter is homing towards player &2dab d0 41 BNE &2dee ; consider_fighter_firing_and_homing &2dad ce 76 3f DEC &3f76 ; fighter_z &2db0 ce 76 3f DEC &3f76 ; fighter_z &2db3 10 09 BPL &2dbe ; still_present # Positive if fighter is still on screen &2db5 20 b4 2c JSR &2cb4 ; plot_fighter_and_shadow &2db8 a9 00 LDA #&00 &2dba 8d 76 3f STA &3f76 ; fighter_z # Set to zero to remove fighter &2dbd 60 RTS ; still_present &2dbe ad 76 3f LDA &3f76 ; fighter_z &2dc1 c9 18 CMP #&18 # Fighter starts homing at z = &18 &2dc3 d0 0b BNE &2dd0 ; plot_fighter_and_check_for_collision_with_player &2dc5 a9 0a LDA #&0a &2dc7 ac 8a 3f LDY &3f8a ; difficulty # Non-zero on level 3 and onwards &2dca d0 01 BNE &2dcd ; set_fighter_homing_energy &2dcc 0a ASL A # Fighter homes for longer on easier levels ; set_fighter_homing_energy &2dcd 8d 7d 3f STA &3f7d ; fighter_homing_energy ; plot_fighter_and_check_for_collision_with_player &2dd0 20 b4 2c JSR &2cb4 ; plot_fighter_and_shadow &2dd3 a9 04 LDA #&04 # Check for collision with player &2dd5 85 70 STA &70 ; z_max &2dd7 ad 02 3f LDA &3f02 ; player_y &2dda 85 71 STA &71 ; y &2ddc ad 03 3f LDA &3f03 ; player_x &2ddf 85 72 STA &72 ; x &2de1 a9 00 LDA #&00 &2de3 85 73 STA &73 ; z_min &2de5 20 ba 2e JSR &2eba ; check_for_collision_with_fighter # Returns carry clear if collision occurred &2de8 b0 03 BCS &2ded ; leave &2dea ee 6c 3f INC &3f6c ; player_destroyed # Set to non-zero to kill player (hit by fighter) ; leave &2ded 60 RTS ; consider_fighter_firing_and_homing &2dee ce 7d 3f DEC &3f7d ; fighter_homing_energy &2df1 ce 76 3f DEC &3f76 ; fighter_z &2df4 a2 02 LDX #&02 &2df6 a0 03 LDY #&03 &2df8 ad 8a 3f LDA &3f8a ; difficulty # Non-zero on level 3 and onwards &2dfb f0 07 BEQ &2e04 ; is_easy &2dfd ce 76 3f DEC &3f76 ; fighter_z &2e00 a2 06 LDX #&06 # On harder levels, &2e02 a0 07 LDY #&07 # fighter moves vertically and horizontally faster ; is_easy &2e04 86 71 STX &71 ; fighter_maximum_x_velocity &2e06 84 72 STY &72 ; fighter_maximum_y_velocity &2e08 a9 1c LDA #&1c &2e0a 38 SEC &2e0b ed 76 3f SBC &3f76 ; fighter_z &2e0e 69 2c ADC #&2c &2e10 85 70 STA &70 ; fighter_maximum_x &2e12 ad 02 3f LDA &3f02 ; player_y # Calculate y difference between player and fighter &2e15 38 SEC &2e16 ed 77 3f SBC &3f77 ; fighter_y &2e19 08 PHP ; player_y - fighter_y sign &2e1a 10 02 BPL &2e1e ; skip_y_inversion &2e1c 49 fe EOR #&fe ; skip_y_inversion &2e1e c5 72 CMP &72 ; fighter_maximum_y_velocity &2e20 90 02 BCC &2e24 ; skip_y_ceiling &2e22 a5 72 LDA &72 ; fighter_maximum_y_velocity ; skip_y_ceiling &2e24 28 PLP ; player_y - fighter_y sign &2e25 10 02 BPL &2e29 ; skip_y_uninversion &2e27 49 fe EOR #&fe ; skip_y_uninversion &2e29 18 CLC &2e2a 6d 77 3f ADC &3f77 ; fighter_y # Move fighter towards player vertically &2e2d c9 98 CMP #&98 &2e2f 90 07 BCC &2e38 ; skip_moving_fighter_vertically # Don't allow fighter to move below ground &2e31 c9 c5 CMP #&c5 &2e33 b0 03 BCS &2e38 ; skip_moving_fighter_vertically # Don't allow fighter to move above top of world &2e35 8d 77 3f STA &3f77 ; fighter_y ; skip_moving_fighter_vertically &2e38 ad 03 3f LDA &3f03 ; player_x # Calculate x difference between player and fighter &2e3b 38 SEC &2e3c ed 78 3f SBC &3f78 ; fighter_x &2e3f 08 PHP ; player_x - fighter_x sign &2e40 10 02 BPL &2e44 ; skip_x_inversion &2e42 49 fe EOR #&fe ; skip_x_inversion &2e44 c5 71 CMP &71 ; fighter_maximum_x_velocity &2e46 90 02 BCC &2e4a ; skip_x_ceiling &2e48 a5 71 LDA &71 ; fighter_maximum_x_velocity ; skip_x_ceiling &2e4a 28 PLP ; player_x - fighter_x sign &2e4b 10 02 BPL &2e4f ; skip_x_uninversion &2e4d 49 fe EOR #&fe ; skip_x_uninversion &2e4f 18 CLC &2e50 6d 78 3f ADC &3f78 ; fighter_x # Move fighter towards player horizontally &2e53 c9 16 CMP #&16 &2e55 90 07 BCC &2e5e ; skip_moving_fighter_horizontally # Don't allow fighter to move off left edge of world &2e57 c5 70 CMP &70 ; fighter_maximum_x &2e59 b0 03 BCS &2e5e ; skip_moving_fighter_horizontally # Don't allow fighter to move right of diagonal &2e5b 8d 78 3f STA &3f78 ; fighter_x ; skip_moving_fighter_horizontally &2e5e a9 1e LDA #&1e # Check if fighter is aligned with player &2e60 85 70 STA &70 ; z_max &2e62 a9 00 LDA #&00 &2e64 85 73 STA &73 ; z_min &2e66 ad 02 3f LDA &3f02 ; player_y &2e69 85 71 STA &71 ; y &2e6b ad 03 3f LDA &3f03 ; player_x &2e6e 85 72 STA &72 ; x &2e70 20 ba 2e JSR &2eba ; check_for_collision_with_fighter # Returns carry clear if collision occurred &2e73 b0 42 BCS &2eb7 ; skip_fighter_firing &2e75 ad 7f 3f LDA &3f7f ; fighter_has_fired # Non-zero if fighter firing suppressed &2e78 d0 3d BNE &2eb7 ; skip_fighter_firing &2e7a a8 TAY ; 0 &2e7b ad 6a 3f LDA &3f6a ; enemy_missiles_state # Zero if no missile in slot &2e7e f0 06 BEQ &2e86 ; add_fighter_missile &2e80 c8 INY ; 1 &2e81 ad 6b 3f LDA &3f6b ; enemy_missiles_state + 1 # Zero if no missile in slot &2e84 d0 31 BNE &2eb7 ; skip_fighter_firing ; add_fighter_missile &2e86 99 68 3f STA &3f68,Y ; enemy_missiles_screen_address_high # Set to zero to indicate missile not plotted &2e89 a9 01 LDA #&01 &2e8b 99 6a 3f STA &3f6a,Y ; enemy_missiles_state # Set to non-zero to indicate missile in slot &2e8e ad 78 3f LDA &3f78 ; fighter_x &2e91 99 62 3f STA &3f62,Y ; enemy_missiles_target_screen_x # screen_x = world_x &2e94 ad 76 3f LDA &3f76 ; fighter_z &2e97 38 SEC &2e98 e9 04 SBC #&04 &2e9a 29 fe AND #&fe &2e9c 99 60 3f STA &3f60,Y ; enemy_missiles_z &2e9f ad 77 3f LDA &3f77 ; fighter_y &2ea2 38 SEC &2ea3 ed 78 3f SBC &3f78 ; fighter_x # screen_y = world_y - world_x &2ea6 e9 06 SBC #&06 &2ea8 99 64 3f STA &3f64,Y ; enemy_missiles_target_screen_y &2eab a2 01 LDX #&01 &2ead 8e 7f 3f STX &3f7f ; fighter_has_fired # Set to non-zero to suppress fighter firing &2eb0 ca DEX &2eb1 8e 7d 3f STX &3f7d ; fighter_homing_energy &2eb4 20 d1 1c JSR &1cd1 ; to_start_firing_sound ; skip_fighter_firing &2eb7 4c d0 2d JMP &2dd0 ; plot_fighter_and_check_if_still_on_screen ; check_for_collision_with_fighter &2eba ad 7e 3f LDA &3f7e ; fighter_explosion_state # Zero if fighter is not exploding &2ebd f0 02 BEQ &2ec1 ; perform_check ; leave_with_carry_set &2ebf 38 SEC # Leave with carry set to indicate no collision &2ec0 60 RTS ; perform_check &2ec1 ad 76 3f LDA &3f76 ; fighter_z &2ec4 c5 73 CMP &73 ; z_min &2ec6 90 f7 BCC &2ebf ; leave_with_carry_set &2ec8 38 SEC &2ec9 e9 04 SBC #&04 &2ecb c5 70 CMP &70 ; z_max &2ecd b0 0c BCS &2edb ; leave # Leave with carry set to indicate no collision &2ecf a5 71 LDA &71 ; y &2ed1 38 SEC &2ed2 ed 77 3f SBC &3f77 ; fighter_y &2ed5 18 CLC &2ed6 69 08 ADC #&08 &2ed8 10 02 BPL &2edc ; check_y_difference &2eda 38 SEC # Leave with carry set to indicate no collision ; leave &2edb 60 RTS ; check_y_difference &2edc c9 10 CMP #&10 &2ede b0 fb BCS &2edb ; leave # Leave with carry set to indicate no collision &2ee0 a5 72 LDA &72 ; x &2ee2 38 SEC &2ee3 ed 78 3f SBC &3f78 ; fighter_x &2ee6 18 CLC &2ee7 69 08 ADC #&08 &2ee9 10 02 BPL &2eed ; check_x_difference &2eeb 38 SEC # Leave with carry set to indicate no collision &2eec 60 RTS ; check_x_difference &2eed c9 10 CMP #&10 &2eef 60 RTS # Leave with carry clear if collision occurred ; explode_fighter &2ef0 a9 01 LDA #&01 &2ef2 8d 76 3f STA &3f76 ; fighter_z # Set to one to remove fighter on next update &2ef5 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2ef8 ad 79 3f LDA &3f79 ; fighter_screen_address_low &2efb 85 70 STA &70 ; screen_address_low &2efd ad 7a 3f LDA &3f7a ; fighter_screen_address_high &2f00 85 71 STA &71 ; screen_address_high &2f02 a9 2a LDA #&2a ; &082a = fighter_buffer &2f04 85 72 STA &72 ; buffer_address_low &2f06 a9 08 LDA #&08 &2f08 85 73 STA &73 ; buffer_address_high &2f0a 20 b3 1c JSR &1cb3 ; to_buffer_sprite # Buffer fighter explosion &2f0d 20 4c 2d JSR &2d4c ; use_fighter_sprite_sizes &2f10 ad 79 3f LDA &3f79 ; fighter_screen_address_low &2f13 85 70 STA &70 ; screen_address_low &2f15 ad 7a 3f LDA &3f7a ; fighter_screen_address_high &2f18 85 71 STA &71 ; screen_address_high &2f1a a9 50 LDA #&50 ; &3c50 = sprite_fighter_explosion &2f1c 85 72 STA &72 ; sprite_address_low &2f1e a9 3c LDA #&3c &2f20 85 73 STA &73 ; sprite_address_high &2f22 a9 00 LDA #&00 &2f24 8d 7c 3f STA &3f7c ; fighter_shadow_screen_address_high # Set to zero to indicate fighter shadow not plotted &2f27 a9 01 LDA #&01 &2f29 8d 7f 3f STA &3f7f ; fighter_has_fired # Set to non-zero to suppress fighter firing &2f2c 20 ad 1c JSR &1cad ; to_plot_masked_sprite # Plot fighter explosion &2f2f a2 50 LDX #&50 &2f31 a0 07 LDY #&07 # Score 750 for destroying fighter &2f33 4c 31 2a JMP &2a31 ; add_XY_to_score ; completion_screen &2f36 a9 27 LDA #&27 &2f38 85 08 STA &08 ; nop_cascade_frequency # Call NOP cascade more frequently &2f3a a9 04 LDA #&04 &2f3c 85 09 STA &09 ; initial_boss_energy # Reset boss energy for next level &2f3e 20 86 2c JSR &2c86 ; start_death_sound &2f41 a2 64 LDX #&64 ; delay_loop &2f43 20 bc 1c JSR &1cbc ; to_wait_for_vsync &2f46 ca DEX &2f47 d0 fa BNE &2f43 ; delay_loop &2f49 a2 02 LDX #&02 ; backup_score_loop &2f4b bd 58 3f LDA &3f58,X ; score &2f4e 95 03 STA &03,X ; initial_score &2f50 ca DEX &2f51 10 f8 BPL &2f4b ; backup_score_loop &2f53 a0 0d LDY #&0d ; set_video_registers_loop &2f55 8c 00 fe STY &fe00 ; video register number &2f58 b9 de 0e LDA &0ede,Y ; completion_screen_video_register_data &2f5b 8d 01 fe STA &fe01 ; video register value &2f5e 88 DEY &2f5f 10 f4 BPL &2f55 ; set_video_registers_loop &2f61 a9 0a LDA #&0a # Change to MODE 7, no cursor &2f63 8d 20 fe STA &fe20 ; video ULA control register &2f66 c8 INY ; 0 &2f67 84 70 STY &70 ; completion_screen_data_address_low &2f69 a9 41 LDA #&41 ; &4100 = completion_screen_data &2f6b 85 71 STA &71 ; completion_screen_data_address_high &2f6d 84 72 STY &72 ; screen_address_low &2f6f a9 7c LDA #&7c &2f71 85 73 STA &73 ; screen_address_high ; copy_completion_screen_data_loop # Display completion screen &2f73 a5 70 LDA &70 ; completion_screen_data_address_low &2f75 09 04 ORA #&04 &2f77 85 70 STA &70 ; completion_screen_data_address_low &2f79 b1 70 LDA (&70),Y ; completion_screen_data_address &2f7b 91 72 STA (&72),Y ; screen_address &2f7d e6 70 INC &70 ; completion_screen_data_address_low &2f7f d0 02 BNE &2f83 ; skip_page &2f81 e6 71 INC &71 ; completion_screen_data_address_high ; skip_page &2f83 e6 72 INC &72 ; screen_address_low &2f85 d0 ec BNE &2f73 ; copy_completion_screen_data_loop &2f87 e6 73 INC &73 ; screen_address_high &2f89 10 e8 BPL &2f73 ; copy_completion_screen_data_loop &2f8b 84 00 STY &00 ; initial_level_data_address_low &2f8d 84 06 STY &06 ; initial_reached_checkpoint &2f8f a6 01 LDX &01 ; initial_level_data_address_high &2f91 84 01 STY &01 ; initial_level_data_address_high &2f93 a0 0c LDY #&0c ; &0c00 = level_2_data &2f95 e0 0c CPX #&0c ; &0c00 = level_2_data &2f97 90 04 BCC &2f9d ; not_end_of_level_two &2f99 84 0a STY &0a ; initial_difficulty # Set to non-zero to make game more difficult &2f9b a0 0a LDY #&0a ; &0a00 = level_1_data # Level three is level one ; not_end_of_level_two &2f9d 84 14 STY &14 ; level_data_base_address_high &2f9f a2 c8 LDX #&c8 ; delay_loop &2fa1 20 bc 1c JSR &1cbc ; to_wait_for_vsync &2fa4 ca DEX &2fa5 d0 fa BNE &2fa1 ; delay_loop &2fa7 4c c2 1c JMP &1cc2 ; to_start_level ; unused &2faa 02 ab 02 b9 80 41 ; digit_sprites &2fb0 ee aa aa aa aa aa ee 00 ; 0 &2fb8 44 cc 44 44 44 44 ee 00 ; 1 &2fc0 ee aa 22 ee 88 aa ee 00 ; 2 &2fc8 ee aa 22 ee 22 aa ee 00 ; 3 &2fd0 88 aa aa ee 22 22 22 00 ; 4 &2fd8 ee aa 88 ee 22 aa ee 00 ; 5 &2fe0 ee aa 88 ee aa aa ee 00 ; 6 &2fe8 ee aa 22 66 22 22 22 00 ; 7 &2ff0 ee aa aa ee aa aa ee 00 ; 8 &2ff8 ee aa aa ee 22 aa ee 00 ; 9 ; sprite_foreground_wall_left_one # Each sprite is one vertical strip &3000 10 31 73 f7 f3 f5 f6 f7 f7 f7 f7 f7 f3 f5 f6 f7 &3010 f7 f7 f7 f7 73 31 10 ; sprite_foreground_wall_left_two &3017 80 c8 ec fe ff ff ff ff f7 fb fd fe fe fe fe fe &3027 f6 f2 f4 f6 f7 f7 f7 f7 f7 73 31 10 ; sprite_foreground_wall_middle_one &3033 80 c8 ec fe ff ff ff ff f7 fb fd fe ff ff ff ff &3043 f7 fb fd fe ff ff ff ff f7 73 31 10 ; sprite_foreground_wall_middle_two &304f 80 c8 ec fe ff ff ff ff f7 fb fd fe fe fe fe fe &305f f6 f2 f4 f6 f7 f7 f7 f7 f7 73 31 10 ; sprite_foreground_wall_right_one &306b 80 c8 ec fe ff ff ff ff f7 fb fd fe fe fe fe fe &307b f6 f2 f4 f6 f7 f7 f7 f7 f7 73 31 10 ; sprite_foreground_wall_right_two &3087 80 c8 ec fe fc fa f6 fe fe fe fe fe fc fa f6 fe &3097 fe fe fe fe ec c8 80 ; unused &309e 00 00 ; sprite_background_wall_left # Each sprite is several horizontal strips &30a0 00 80 10 c8 31 ec 73 fe f7 ff f3 ff f5 ff f6 ff &30b0 f7 f7 f7 fb f7 fd f7 fe f7 fe f3 fe f5 fe f6 fe &30c0 f7 f6 f7 f2 f7 f4 f7 f6 f7 f7 73 f7 31 f7 10 f7 &30d0 00 f7 00 73 00 31 00 10 ; sprite_background_wall_middle &30d8 80 00 c8 00 ec 00 fe 00 ff 80 ff c8 ff ec ff fe &30e8 f7 ff fb ff fd ff fe ff ff f7 ff fb ff fd ff fe &30f8 f7 fe fb fe fd fe fe fe fe f6 fe fa fe fc fe fe &3108 f6 ff 72 ff 30 ff 10 ff 00 f7 00 73 00 31 00 10 ; sprite_background_wall_right &3118 80 00 00 c8 00 00 ec 00 00 fe 00 00 ff 80 00 ff &3128 c8 00 ff ec 00 ff fe 00 f7 ff 80 fb ff c8 fd ff &3138 ec fe ff fe ff f7 fc ff fb fa ff fd f6 ff fe fe &3148 f7 fe fe fb fe fe fd fe fe fe fe fe fe f6 fc fe &3158 fa fa fe fc f6 fe fe fe f6 fe fe 72 fe fe 30 fe &3168 fe 10 fe fe 00 f6 ec 00 72 c8 00 30 80 00 10 00 ; sprite_fuel &3178 00 33 47 bf bf bf 4f 3f 0f 8f 4f bf 4f 3f 0f 0f &3188 0f 07 03 00 ee 1f ef ff ff ff ef 1f ef 0f 0f 1f &3198 ef 1f ef 0f 0f 0f 0f 0e 00 88 4c ae ae ae 4e 8e &31a8 0e 2e 4e ae 4e 8e 0e 0e 0e 0c 08 00 ; sprite_turret &31b4 00 01 01 03 03 03 67 67 bf bf cf ff 77 77 33 00 &31c4 96 69 69 96 0f 0f 0f 0f 0f ff ff 0f ff ff ff ff &31d4 00 08 08 0c 0c 0c 6e 6e df df 3f ff ee ee cc 00 ; sprite_silo &31e4 80 40 20 10 30 30 30 30 10 20 40 80 00 00 f0 f0 &31f4 90 06 06 90 f0 f0 00 00 10 20 40 80 c0 c0 c0 c0 &3204 80 40 20 10 ; unused # &3208 - &32ff is a copy of &3508 - &35ff &3208 00 00 33 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 &3218 67 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 cf 0f &3228 0f 0f 7f ff ff f7 eb 3e 00 00 00 11 8f 0f 0f 0f &3238 7f ff ff f7 eb 3e 00 00 00 33 0f 0f 0f 0f 7f ff &3248 ff f7 eb 3e 00 00 00 67 0f 0f 0f 0f 7f ff ff f7 &3258 eb 3e 00 00 00 cf 0f 0f 0f 0f 7f ff ff f7 eb 3e &3268 00 00 11 8f 0f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 &3278 33 0f 0f 0f 1f 0f 7f ff ff f7 eb 3e 00 00 77 0f &3288 0f 0f 2f 0f 7f ff ff f7 eb 3e 00 00 ff 0f 0f 0f &3298 4f 0f 7f ff ff f7 eb 3e 00 11 ff 0f 0f 0f 4f 0f &32a8 7f ff ff f7 eb 3e 00 33 ff 0f 0f 1f 4f 0f 7f ff &32b8 ff f7 eb 3e 00 77 ff 0f 0f 1f 5f 0f 7f ff ff f7 &32c8 eb 3e 00 ff ff 0f 0f 7f 2f 0f 7f ff ff f7 eb 3e &32d8 11 ff ff 0f 0f 7f 0f 0f 7f ff ff f7 eb 3e 33 ff &32e8 ff 0f 0f 5f 0f 0f 7f ff ff f7 eb 3e 77 ff ff 0f &32f8 2f 5f 0f 0f 7f ff ff f7 ; sprite_panel # Horizontal strips &3300 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 &3310 00 00 00 00 00 00 00 00 00 00 00 32 00 00 00 00 &3320 00 00 00 00 00 00 00 00 00 76 00 00 00 00 00 00 &3330 00 00 00 00 00 00 00 be &3338 00 00 00 00 00 00 00 00 00 00 00 00 11 3e 00 00 &3348 00 00 00 00 00 00 00 00 00 00 23 3e 00 00 00 00 &3358 00 00 00 00 00 00 00 00 63 3e 00 00 00 00 00 00 &3368 00 00 00 00 00 00 eb 3e &3370 00 00 00 00 00 00 00 00 00 00 00 11 eb 3e 00 00 &3380 00 00 00 00 00 00 00 00 00 33 eb 3e 00 00 00 00 &3390 00 00 00 00 00 00 00 77 eb 3e 00 00 00 00 00 00 &33a0 00 00 00 00 00 f7 eb 3e &33a8 00 00 00 00 00 00 00 00 00 00 11 f7 eb 3e 00 00 &33b8 00 00 00 00 00 00 00 00 33 f7 eb 3e 00 00 00 00 &33c8 00 00 00 00 00 00 77 f7 eb 3e 00 00 00 00 00 00 &33d8 00 00 00 00 ff f7 eb 3e &33e0 00 00 00 00 00 00 00 00 00 11 ff f7 eb 3e 00 00 &33f0 00 00 00 00 00 00 00 33 ff f7 eb 3e 00 00 00 00 &3400 00 00 00 00 00 77 ff f7 eb 3e 00 00 00 00 00 00 &3410 00 00 00 ff ff f7 eb 3e &3418 00 00 00 00 00 00 00 00 11 ff ff f7 eb 3e 00 00 &3428 00 00 00 00 00 00 33 ff ff f7 eb 3e 00 00 00 00 &3438 00 00 00 00 77 ff ff f7 eb 3e 00 00 00 00 00 00 &3448 00 00 ff ff ff f7 eb 3e &3450 00 00 00 00 00 00 00 11 ff ff ff f7 eb 3e 00 00 &3460 00 00 00 00 00 33 7f ff ff f7 eb 3e 00 00 00 00 &3470 00 00 00 67 7f ff ff f7 eb 3e 00 00 00 00 00 00 &3480 00 cf 7f ff ff f7 eb 3e &3488 00 00 00 00 00 00 11 8f 7f ff ff f7 eb 3e 00 00 &3498 00 00 00 00 33 0f 7f ff ff f7 eb 3e 00 00 00 00 &34a8 00 00 67 0f 7f ff ff f7 eb 3e 00 00 00 00 00 00 &34b8 cf 0f 7f ff ff f7 eb 3e &34c0 00 00 00 00 00 11 8f 0f 7f ff ff f7 eb 3e 00 00 &34d0 00 00 00 33 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 &34e0 00 67 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 00 cf &34f0 0f 0f 7f ff ff f7 eb 3e &34f8 00 00 00 00 11 8f 0f 0f 7f ff ff f7 eb 3e 00 00 &3508 00 00 33 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 &3518 67 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 00 cf 0f &3528 0f 0f 7f ff ff f7 eb 3e &3530 00 00 00 11 8f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 &3540 00 33 0f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 67 &3550 0f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 00 cf 0f 0f &3560 0f 0f 7f ff ff f7 eb 3e &3568 00 00 11 8f 0f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 &3578 33 0f 0f 0f 0f 0f 7f ff ff f7 eb 3e 00 00 77 0f &3588 0f 0f 2f 0f 7f ff ff f7 eb 3e 00 00 ff 0f 0f 0f &3598 4f 0f 7f ff ff f7 eb 3e &35a0 00 11 ff 0f 0f 0f cf 0f 7f ff ff f7 eb 3e 00 33 &35b0 ff 0f 0f 0f 4f 0f 7f ff ff f7 eb 3e 00 77 ff 0f &35c0 0f 2f 4f 0f 7f ff ff f7 eb 3e 00 ff ff 0f 0f 5f &35d0 4f 0f 7f ff ff f7 eb 3e &35d8 11 ff ff 0f 0f 5f 4f 0f 7f ff ff f7 eb 3e 33 ff &35e8 ff 0f 1f 7f 0f 0f 7f ff ff f7 eb 3e 77 ff ff 0f &35f8 1f 5f 0f 0f 7f ff ff f7 eb 3e ff ff ff 0f 7f 4f &3608 0f 0f 7f ff ff f7 eb 3e &3610 ff ff ff 0f 7f 4f 0f 0f 7f fe ff f7 eb 3e ff ff &3620 ff 0f 5f 0f 0f 0f 7f fd f7 f7 eb 3e ff ff ff 0f &3630 5f 0f 0f 0f 7f fb fb f7 eb 3e ff ff ff 0f 4f 0f &3640 0f 0f 7f f7 fd f7 eb 3e &3648 ff ff ff 0f 4f 0f 0f 0f 7e ff fe f7 eb 3e ff ff &3658 ff 0f 0f 0f 0f 0f fd ff ff f7 eb 3e ff ff ff 0f &3668 0f 0f 0f 1f fb ff ff ff eb 3e ff ff ff 0f 0f 0f &3678 0f 3f f7 ff ff ff eb 3e &3680 ff ff ff 0f 0f 0f 0f 7e ff ff ff ff eb 3e ff ff &3690 ff 0f 0f 0f 0f fd ff ff ff ff eb 3e ff ff ff 0f &36a0 0f 0f 1f fb ff fe ff ff eb 3e ff ff ff 0f 0f 0f &36b0 3f f7 ff ec f7 ff eb 3e &36b8 ff ff ff 0f 0f 0f 7e ff ff c8 73 ff eb 7e ff ff &36c8 ff 0f 0f 0f fd ff ff 80 31 ff eb fe ff ff ff 0f &36d8 0f 1f fb ff fe 00 10 ff fb fe ff ff ff 0f 0f 3f &36e8 f7 ff ec 00 00 f7 fb ec &36f0 ff ff ff 0f 0f 7e ff ff c8 00 00 73 fb c8 ff ff &3700 ff 0f 0f fd ff ff 80 00 00 31 fb 80 ff ff ff 0f &3710 1f fb ff fe 00 00 00 10 fa 00 ff ff ff 0f 3f f7 &3720 ff ec 00 00 00 00 e0 00 &3728 ff ff ff 0f 7e ff ff c8 00 00 00 00 40 00 ff ff &3738 ff 0f fd ff ff 80 00 00 00 00 00 00 ff ff ff 1f &3748 fb ff fe 00 00 00 00 00 00 00 ff ff ff 3f f7 ff &3758 ec 00 00 00 00 00 00 00 &3760 ff ff ff 7e ff ff c8 00 00 00 00 00 00 00 ff ff &3770 ff fd ff ff 80 00 00 00 00 00 00 00 ff ff ff fb &3780 ff fe 00 00 00 00 00 00 00 00 ff ff ff f7 ff ec &3790 00 00 00 00 00 00 00 00 &3798 ff ff fe ff ff c8 00 00 00 00 00 00 00 00 f7 ff &37a8 fd ff ff 80 00 00 00 00 00 00 00 00 fb ff fb ff &37b8 fe 00 00 00 00 00 00 00 00 00 fd ff f7 ff ec 00 &37c8 00 00 00 00 00 00 00 00 &37d0 fe fe ff ff c8 00 00 00 00 00 00 00 00 00 ff f5 &37e0 ff ff 80 00 00 00 00 00 00 00 00 00 ff fb ff fe &37f0 00 00 00 00 00 00 00 00 00 00 ff ff ff ec 00 00 &3800 00 00 00 00 00 00 00 00 &3808 ff ff ff c8 00 00 00 00 00 00 00 00 00 00 ff ff &3818 ff 80 00 00 00 00 00 00 00 00 00 00 ff ff fe 00 &3828 00 00 00 00 00 00 00 00 00 00 f7 ff ec 00 00 00 &3838 00 00 00 00 00 00 00 00 &3840 73 ff c8 00 00 00 00 00 00 00 00 00 00 00 31 ff &3850 80 00 00 00 00 00 00 00 00 00 00 00 10 fe 00 00 &3860 00 00 00 00 00 00 00 00 00 00 00 e4 00 00 00 00 &3870 00 00 00 00 00 00 00 00 &3878 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3888 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3898 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &38a8 00 00 00 00 00 00 00 00 ; electric_wall_background_parts_data ; 0 1 2 3 4 5 6 7 # 034562 ; l r r m m m m m # 71 &38b0 07 08 08 08 08 08 08 08 ; &0900 = background_wall_parts_rows_remaining &38b8 1d 35 21 21 25 29 2d 31 ; &0908 = background_wall_parts_start_x &38c0 02 03 03 02 02 02 02 02 ; &0910 = background_wall_parts_width &38c8 a0 18 18 d8 d8 d8 d8 d8 ; &0918 = background_wall_parts_sprite_address_low &38d0 30 31 31 30 30 30 30 30 ; &0920 = background_wall_parts_sprite_address_high &38d8 0c 00 0e 0a 08 06 04 02 ; &0928 = background_wall_parts_distance &38e0 04 02 02 03 03 01 01 01 ; &0930 = background_wall_parts_repeats_remaining &38e8 01 03 03 02 02 02 02 02 ; &0938 = background_wall_parts_row_to_start_repeat &38f0 06 07 07 07 07 07 07 07 ; &0940 = background_wall_parts_rows_after_repeat &38f8 00 02 02 00 00 00 00 00 ; &0948 = background_wall_parts_repeat_type &3900 00 03 03 00 00 00 00 00 ; &0950 = background_wall_parts_row_to_start_special_repeat &3908 00 04 04 00 00 00 00 00 ; &0958 = background_wall_parts_rows_after_second_repeat &3910 00 08 08 00 00 00 00 00 ; &0960 = background_wall_parts_rows_after_first_repeat ; large_wall_background_parts_data ; 0 1 2 3 4 5 6 7 # 034562 ; l r r m m m m m # 71 &3918 07 08 08 08 08 08 08 08 ; &0900 = background_wall_parts_rows_remaining &3920 1d 35 21 21 25 29 2d 31 ; &0908 = background_wall_parts_start_x &3928 02 03 03 02 02 02 02 02 ; &0910 = background_wall_parts_width &3930 a0 18 18 d8 d8 d8 d8 d8 ; &0918 = background_wall_parts_sprite_address_low &3938 30 31 31 30 30 30 30 30 ; &0920 = background_wall_parts_sprite_address_high &3940 0c 00 10 0a 08 06 04 02 ; &0928 = background_wall_parts_distance &3948 04 04 00 03 03 03 03 02 ; &0930 = background_wall_parts_repeats_remaining &3950 01 03 00 02 02 02 02 02 ; &0938 = background_wall_parts_row_to_start_repeat &3958 06 07 00 07 07 07 07 07 ; &0940 = background_wall_parts_rows_after_repeat &3960 00 02 00 00 00 00 00 00 ; &0948 = background_wall_parts_repeat_type &3968 00 03 00 00 00 00 00 00 ; &0950 = background_wall_parts_row_to_start_special_repeat &3970 00 04 00 00 00 00 00 00 ; &0958 = background_wall_parts_rows_after_second_repeat &3978 00 08 00 00 00 00 00 00 ; &0960 = background_wall_parts_rows_after_first_repeat ; sprite_player_odd &3980 01 01 01 01 ef ef 67 23 01 01 00 00 00 00 08 0c &3990 0f 0f 0f 1f 3f 7f ff 77 33 11 00 46 8f 0f 0e 08 &39a0 88 88 88 88 88 88 88 00 00 00 00 00 00 00 00 00 &39b0 00 00 00 00 ; sprite_player_explosion_one &39b4 00 00 00 02 03 01 07 07 03 03 01 00 00 00 08 0f &39c4 6f 0f 1f bf af 0f 0f 13 03 00 00 02 07 0f 2f 8f &39d4 0e 0c 8e 8f 0e 0c 08 00 00 08 00 08 00 00 00 00 &39e4 00 00 00 00 ; sprite_player_even &39e8 00 00 00 00 33 33 11 00 00 00 00 00 00 04 06 07 &39f8 07 8f 8f 8f 8f 17 37 11 00 00 00 11 23 0f 0f 0e &3a08 6e ee ee ee ee ee 66 00 08 0c 0c 08 00 00 00 00 &3a18 00 00 00 00 ; sprite_player_explosion_two &3a1c 00 02 07 03 00 01 03 13 17 3f 07 01 01 02 0b cf &3a2c 0f 6f 4f 0f 0f 9f 2f 0f 01 00 00 01 0e 0f 8f 4e &3a3c 8e 0f 1f 6f 8e 00 00 00 00 00 00 04 08 00 08 0c &3a4c 00 00 00 00 ; sprite_destroyed_large &3a50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 40 &3a60 20 20 30 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a70 00 20 b0 40 60 80 40 a0 00 00 00 00 00 00 00 00 &3a80 00 00 00 00 00 00 40 80 80 c0 80 00 ; sprite_destroyed_small &3a8c 00 00 00 00 00 00 00 00 00 10 00 20 60 30 00 20 &3a9c 00 00 00 00 00 00 00 00 00 50 e0 a0 90 30 c0 20 &3aac 00 00 00 00 00 00 00 00 00 00 80 00 00 00 40 00 ; sprite_explosion_large &3abc 00 00 00 01 00 00 22 07 23 33 13 33 27 33 13 07 &3acc 02 15 11 00 00 00 02 00 4c 8d 6f df 3f 3f df 7f &3adc df 6f df 6f 44 aa 11 8a 00 00 00 08 0c 88 08 00 &3aec 04 0c 8c 88 08 cc 0c 4c 88 04 00 00 ; sprite_explosion_small &3af8 00 00 02 04 23 05 13 13 44 2b af 37 03 45 22 00 &3b08 00 00 00 cd 4e 77 cf 3f 2f 4f 19 ab bf 23 dd 22 &3b18 00 00 00 00 04 02 44 88 44 00 88 cc 08 4c 2a 00 ; sprite_rocket_one &3b28 01 01 01 03 03 03 03 03 03 07 07 17 06 15 26 04 &3b38 00 00 00 00 00 00 00 08 08 08 08 08 08 0c 0c 0c &3b48 0c 04 8c 04 00 00 00 00 ; sprite_rocket_two &3b50 01 01 01 03 03 03 03 03 03 07 07 17 06 15 26 04 &3b60 33 55 00 22 00 00 00 08 08 08 08 08 08 0c 0c 0c &3b70 0c 04 8c 8c 44 00 88 44 ; sprite_rocket_explosion &3b78 00 00 05 0f 07 03 17 17 0f 13 27 2f 0f 07 03 17 &3b88 0f 03 00 00 00 00 00 0a 0e 0c 0c 8c 0e 6e 4e 3f &3b98 0e 8e 8e 0c 0e 00 00 00 ; sprite_wall_explosion &3ba0 02 01 01 02 03 04 02 00 04 02 0d 0c 06 09 01 00 ; sprite_fighter_even &3bb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 &3bc0 11 33 22 00 00 00 00 00 00 00 00 01 01 03 13 37 &3bd0 77 ef 4f cc 88 00 00 00 00 00 00 00 17 1f 3f 3f &3be0 7f ef cf 8f 0f 0c 00 00 00 00 00 00 44 44 cc cc &3bf0 cc cc ce 8e 0f 0f 0f 0c 00 00 00 00 00 00 00 00 ; sprite_fighter_odd &3c00 00 00 00 00 00 00 00 00 00 00 00 01 11 33 13 37 &3c10 66 cc 88 00 00 00 00 00 01 03 03 07 17 3f 7f ef &3c20 cf 8f 0c 00 00 00 00 00 11 11 33 33 7f 7f ff ef &3c30 cf 8f 0f 0f 0c 00 00 00 00 00 00 00 00 00 00 00 &3c40 00 00 08 08 0c 0c 0c 00 00 00 00 00 00 00 00 00 ; sprite_fighter_explosion &3c50 00 00 00 00 00 00 00 00 00 00 00 03 03 13 07 02 &3c60 00 00 00 00 00 00 00 01 01 03 06 07 0b 03 0f 3f &3c70 8b 8e 09 07 03 00 00 00 00 01 0f 0a 0f ce 0e 37 &3c80 13 0c 03 2f 27 07 00 0c 00 00 00 00 00 00 08 04 &3c90 04 0c 0c 0c 8e 0e 0e 02 0c 00 00 00 00 00 00 00 ; sprite_enemy_missile_even &3ca0 00 00 03 07 07 0f 0c 02 0c 0c 08 00 00 00 00 00 &3cb0 00 00 00 00 00 ; sprite_enemy_missile_odd &3cb5 00 00 00 01 01 03 03 00 03 0f 0e 0c 0c 00 08 00 &3cc5 00 00 00 00 00 ; sprite_boss &3cca 80 c0 a8 98 01 03 03 01 10 20 40 80 80 80 88 88 &3cda 00 00 06 0f 9f 69 9f 96 0f 06 00 00 00 00 00 00 &3cea 10 30 51 91 08 0c 0c 08 80 40 20 10 10 10 11 11 ; sprite_electric_fence &3cfa 04 02 04 08 04 02 04 08 04 02 04 08 04 ; unused &3d07 02 04 # Would extend electric fence ; unused # Source code fragment &3d09 53 54 41 26 33 46 37 ; "STA&3F7" ; high_scores &3d10 00 00 01 ; 10000 &3d13 41 6d 63 6f 6d 20 20 20 20 20 20 20 20 20 20 ; "Amcom " &3d22 00 90 00 ; 9000 &3d25 4d 61 74 20 4e 65 77 6d 61 6e 20 20 20 20 20 ; "Mat Newman " &3d34 00 80 00 ; 8000 &3d37 41 6d 63 6f 6d 20 20 20 20 20 20 20 20 20 20 ; "Amcom " &3d46 00 70 00 ; 7000 &3d49 4d 61 74 20 4e 65 77 6d 61 6e 20 20 20 20 20 ; "Mat Newman " &3d58 00 60 00 ; 6000 &3d5b 41 6d 63 6f 6d 20 20 20 20 20 20 20 20 20 20 ; "Amcom " &3d6a 00 50 00 ; 5000 &3d6d 4d 61 74 20 4e 65 77 6d 61 6e 20 20 20 20 20 ; "Mat Newman " &3d7c 00 40 00 ; 4000 &3d7f 41 6d 63 6f 6d 20 20 20 20 20 20 20 20 20 20 ; "Amcom " &3d8e 00 30 00 ; 3000 &3d91 4d 61 74 20 4e 65 77 6d 61 6e 20 20 20 20 20 ; "Mat Newman " &3da0 00 20 00 ; 2000 &3da3 41 6d 63 6f 6d 20 20 20 20 20 20 20 20 20 20 ; "Amcom " &3db2 00 10 00 ; 1000 &3db5 4d 61 74 20 4e 65 77 6d 61 6e 20 20 20 20 20 ; "Mat Newman " ; unused &3dc4 0d ; unused # Source code fragment similar to &1cff - &1d08 &3dc5 3a 49 4e 43 26 33 46 34 30 3a 52 54 53 0d ; ... : ; INC&3F40: ; RTS &3dd3 04 38 50 4c 44 58 23 26 34 38 3a 4a 53 52 4b 45 ; 1080LDX#&48: # &1d03 LDX &30 (&48 is keycode for ') &3de3 59 3a 42 45 51 ; JSRKEY: ; BEQ ... ; real_entry_point &3de8 a9 4c LDA #&4c ; JMP &3dea 8d 87 02 STA &0287 ; BREAK intercept code &3ded a9 3b LDA #&3b ; &133b = start_game &3def 8d 88 02 STA &0288 ; BREAK intercept code + 1 &3df2 a9 13 LDA #&13 &3df4 8d 89 02 STA &0289 ; BREAK intercept code + 2 &3df7 a9 c8 LDA #&c8 ; Read/Write BREAK/ESCAPE effect &3df9 a0 00 LDY #&00 &3dfb a2 02 LDX #&02 ; Memory cleared on next reset &3dfd 20 f4 ff JSR &fff4 ; OSBYTE &3e00 a9 03 LDA #&03 ; 0000 0011 # Reset ACIA &3e02 8d 08 fe STA &fe08 ; Cassette ACIA control register &3e05 a9 7f LDA #&7f ; 0111 1111 # Turn off cassette motor; RS-432 system has control &3e07 8d 10 fe STA &fe10 ; Serial ULA control register &3e0a a0 04 LDY #&04 ; copy_keys_loop &3e0c b9 80 00 LDA &0080,Y ; loader_keys &3e0f 99 30 00 STA &0030,Y ; keys &3e12 88 DEY &3e13 10 f7 BPL &3e0c ; copy_keys_loop &3e15 a9 21 LDA #&21 ; &2021 = leave &3e17 8d 24 02 STA &0224 ; net_vector_low &3e1a a9 20 LDA #&20 &3e1c 8d 25 02 STA &0225 ; net_vector_high &3e1f 4c 20 12 JMP &1220 ; move_memory &3e22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &3e00 - &3e0f ; objects_z # &3e10 - &3e1f ; objects_width_remaining # &3e20 - &3e2f ; objects_min_x ; objects_max_x &3e30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_min_y &3e40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_max_y &3e50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Object types # ============ # 1 OBJECT_FUEL # 2 OBJECT_TURRET # 3 OBJECT_SILO # 4 OBJECT_ELECTRIC_WALL # 5 OBJECT_LARGE_WALL # 6 OBJECT_SMALL_WALL # 7 OBJECT_ROCKET # 8 OBJECT_BOSS # 9 OBJECT_FIGHTER ; objects_type &3e60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_screen_address_low &3e70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_screen_address_high &3e80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_rocket_ttl &3e90 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ; objects_rocket_buffer_address_low ; objects_turret_can_fire &3ea0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_silo_firing_position ; objects_turret_initial_screen_y &3eb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_silo_centre_screen_address_low ; objects_turret_initial_z &3ec0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; objects_silo_centre_screen_address_high &3ed0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; unused &3ee0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3ef0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; unused_distance_low &3f00 09 ; unused_distance_high &3f01 00 ; player_y &3f02 98 ; player_x &3f03 15 ; player_screen_address_low &3f04 28 ; player_screen_address_high &3f05 5d ; player_shadow_screen_address_low &3f06 a8 ; player_shadow_screen_address_high &3f07 5f ; screen_start_address_low &3f08 40 ; screen_start_address_high &3f09 76 ; distance_since_checkpoint &3f0a 01 ; missiles_state &3f0b 00 00 00 00 ; missiles_y &3f0f 00 00 00 00 ; missiles_x &3f13 00 00 00 00 ; missiles_screen_address_low &3f17 00 00 00 00 ; missiles_screen_address_high &3f1b 00 00 00 00 ; suppress_firing_roller &3f1f 00 ; new_objects_foreground_y &3f20 00 00 00 00 ; new_objects_width_remaining &3f24 00 00 00 00 ; new_objects_sprite_address_low &3f28 00 00 00 00 ; new_objects_height &3f2c 00 00 00 00 ; unused &3f30 00 00 00 00 ; explosions_sprite_address_low &3f34 00 00 00 00 ; explosions_screen_address_low &3f38 00 00 00 00 ; explosions_screen_address_high &3f3c 00 00 00 00 ; background_sound_frequency &3f40 11 ; wall_explosions_state &3f41 00 00 00 00 ; wall_explosions_screen_address_low &3f45 00 00 00 00 ; wall_explosions_screen_address_high &3f49 00 00 00 00 ; firing_sound_state &3f4d 00 ; firing_sound_duration &3f4e 00 ; firing_sound_volume &3f4f 00 ; firing_sound_cooldown &3f50 00 ; explosion_sound_state &3f51 00 ; explosion_sound_frequency &3f52 00 ; explosion_sound_volume &3f53 00 ; explosion_sound_cooldown &3f54 00 ; vsync_counter &3f55 02 ; previous_vsync_counter &3f56 02 ; suppress_extra_life &3f57 00 ; score &3f58 00 00 00 ; warning_sound_state &3f5b 00 ; warning_sound_frequency &3f5c 00 ; warning_sound_duration &3f5d 00 ; warning_sound_cooldown &3f5e 00 ; player_lives &3f5f 03 ; enemy_missiles_z &3f60 00 00 ; enemy_missiles_target_screen_x &3f62 00 00 ; enemy_missiles_target_screen_y &3f64 00 00 ; enemy_missiles_screen_address_low &3f66 00 00 ; enemy_missiles_screen_address_high &3f68 00 00 ; enemy_missiles_state &3f6a 00 00 ; player_destroyed &3f6c 00 ; player_fuel &3f6d 3a ; player_fuel_drain_cooldown &3f6e 01 ; player_fuel_drain_maximum_cooldown &3f6f 03 ; death_sound_state &3f70 00 ; death_sound_frequency &3f71 00 ; death_sound_volume &3f72 00 ; death_sound_cooldown &3f73 00 ; death_sound_timer &3f74 00 ; reached_checkpoint &3f75 00 ; fighter_z &3f76 00 ; fighter_y &3f77 00 ; fighter_x &3f78 00 ; fighter_screen_address_low &3f79 00 ; fighter_screen_address_high &3f7a 00 ; fighter_shadow_screen_address_low &3f7b 00 ; fighter_shadow_screen_address_high &3f7c 00 ; fighter_homing_energy &3f7d 00 ; fighter_explosion_state &3f7e 00 ; fighter_has_fired &3f7f 00 ; level_completed &3f80 00 ; boss_energy &3f81 04 ; electric_fence_state &3f82 00 ; electric_fence_cooldown &3f83 00 ; electric_sound_state &3f84 00 ; electric_sound_frequency &3f85 00 ; electric_sound_cooldown &3f86 00 ; electric_sound_frequency_delta &3f87 00 ; electric_sound_volume &3f88 00 ; electric_sound_frequency_delta_cooldown &3f89 00 ; difficulty &3f8a 00 ; unused &3f8b 00 00 00 00 00 ; adc_channel &3f90 00 ; adc_channel_values &3f91 00 00 ; unused &3f93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3fa3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3fb3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3fc3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3fd3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3fe3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3ff3 00 00 00 00 00 00 00 00 00 00 00 00 00 ; screen memory # &4000 - &7fff is screen memory, but only the first # four bytes of every group of eight are displayed &4000 ff 00 00 00 ; nop_cascade # The CRTC updates rows 0 - 3, 8 - 11, ... 120 - 123 &4004 ea NOP # of the DRAM multiple times per v-sync by accessing &4005 4c 0c 40 JMP &400c ; nop_cascade_1 # screen memory. nop_cascade refreshes the other rows &4008 00 00 00 00 # (4 - 7, 12 - 15, ... 124 - 127) via irq1_handler, to ; nop_cascade_1 # prevent values in these rows from decaying &400c ea NOP &400d 4c 14 40 JMP &4014 ; nop_cascade_2 &4010 00 00 00 00 ; nop_cascade_2 &4014 ea NOP &4015 4c 1c 40 JMP &401c ; nop_cascade_3 &4018 00 00 00 00 ; nop_cascade_3 &401c ea NOP &401d 4c 24 40 JMP &4024 ; nop_cascade_4 &4020 00 00 00 00 ; nop_cascade_4 &4024 ea NOP &4025 4c 2c 40 JMP &402c ; nop_cascade_5 &4028 00 00 00 00 ; nop_cascade_5 &402c ea NOP &402d 4c 34 40 JMP &4034 ; nop_cascade_6 &4030 00 00 00 00 ; nop_cascade_6 &4034 ea NOP &4035 4c 3c 40 JMP &403c ; nop_cascade_7 &4038 00 00 00 00 ; nop_cascade_7 &403c ea NOP &403d 4c 44 40 JMP &4044 ; nop_cascade_8 &4040 00 00 00 00 ; nop_cascade_8 &4044 ea NOP &4045 4c 4c 40 JMP &404c ; nop_cascade_9 &4048 00 00 00 00 ; nop_cascade_9 &404c ea NOP &404d 4c 54 40 JMP &4054 ; nop_cascade_10 &4050 00 00 00 00 ; nop_cascade_10 &4054 ea NOP &4055 4c 5c 40 JMP &405c ; nop_cascade_11 &4058 00 00 00 00 ; nop_cascade_11 &405c ea NOP &405d 4c 64 40 JMP &4064 ; nop_cascade_12 &4060 00 00 00 00 ; nop_cascade_12 &4064 ea NOP &4065 4c 6c 40 JMP &406c ; nop_cascade_13 &4068 00 00 00 00 ; nop_cascade_13 &406c ea NOP &406d 4c 74 40 JMP &4074 ; nop_cascade_14 &4070 00 00 00 00 ; nop_cascade_14 &4074 ea NOP &4075 4c 7c 40 JMP &407c ; nop_cascade_15 &4078 00 00 00 00 ; nop_cascade_15 &407c ea NOP &407d ea NOP &407e ea NOP &407f 60 RTS # &407f is stored in DRAM row 127 ; unused # Source code fragment corresponding to &1cc5 - &1cec ; 0 1 2 3 4 5 6 7 8 9 a b c d e f ; <---------> <---------> &4080 a0 f0 f0 f0 4c 4e 53 3a f0 f0 f0 f0 54 41 52 54 ; "LNS:", "TART" # (????)LNS: &1cc5 JMP &11f6 &4090 f0 f0 f0 f0 53 48 44 57 f0 f0 f0 f0 4c 41 5a 41 ; "SHDW", "LAZA" # (JMPS)TART(: &1cc8 JMP &133b &40a0 f0 f0 f0 f0 46 53 53 0d f0 f0 f0 f0 4d 6f 76 65 ; "FSS.", "Move" # JMP)SHDW(: &1ccb JMP &1f4a &40b0 f0 f0 f0 f0 26 33 46 30 f0 f0 f0 f0 45 53 49 41 ; "&3F0", "ESIA" # JMP)LAZA(: &1ccd JMP &278e &40c0 f0 f0 f0 f0 23 31 35 32 f0 f0 f0 f0 26 33 46 30 ; "#152", "&3F0" # JMP)FSS( &1cd1 JMP &2161 &40d0 f0 f0 f0 f0 41 23 32 31 f0 f0 f0 f0 26 33 46 30 ; "A#21", "&3F0" # ??? .)Move(: &40e0 f0 f0 f0 f0 41 23 31 37 f0 f0 f0 f0 26 33 46 34 ; "A#17", "&3F4" # LDA)&3F0(2: &1cd4 LDA &3f02 &40f0 f0 f0 f0 f0 41 23 26 45 f0 f0 f0 f0 52 42 59 54 ; "A#&E", "RBYT" # BN)ESIA(: &1cd7 BNE &1ced # LDA)#152(: &1cd9 LDA #&98 # STA)&3F0(2: &1cdb STA &3f02 # LD)A#21(: &1cde LDA #&15 # STA)&3F0(3: &1ce0 STA &3f03 # LD)A#17(: &1ce3 LDA #&11 # STA)&3F4(0: &1ce5 STA &3f40 # LD)A#&E(F: &1ce8 LDA #&ef # JS)RBYT ... &1cea JSR &236a ; completion_screen_data ; 0 1 2 3 4 5 6 7 8 9 a b c d e f ; <---------> <---------> &4100 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4110 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4120 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. ....Amcom's FORTRESS .. " &4130 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. ....Amcom's FORTRESS .. " &4140 f0 f0 f0 f0 20 20 20 20 00 80 c0 e0 20 20 20 20 ; ".. " &4150 00 00 00 00 84 9d 20 20 00 00 00 00 20 20 20 20 ; ".. " &4160 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; ".. ....Nice one!! .. " &4170 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; ".. ....Nice one!! .. " &4180 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4190 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. . ... " &41a0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. . .... " &41b0 f0 f0 f0 f0 87 9d 84 8d f0 f0 f0 f0 41 6d 63 6f ; ".. . ... " &41c0 f0 f0 f0 f0 6d 27 73 20 f0 f0 f0 f0 46 4f 52 54 ; ".. . ........ " &41d0 f0 f0 f0 f0 52 45 53 53 f0 f0 f0 f0 20 20 84 9d ; ".. .................. " &41e0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. .................. " &41f0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. ................. " &4200 f0 f0 f0 f0 87 9d 84 8d f0 f0 f0 f0 41 6d 63 6f ; ".. .................. " &4210 f0 f0 f0 f0 6d 27 73 20 f0 f0 f0 f0 46 4f 52 54 ; ".. . .............. " &4220 f0 f0 f0 f0 52 45 53 53 f0 f0 f0 f0 20 20 84 9d ; ".. " &4230 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4240 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. ....(NOW DO IT AGAIN!!) .. " &4250 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. ....(NOW DO IT AGAIN!!) .. " &4260 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4270 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. .(C) Matthew Newman 1983 " &4280 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 ; ".. " &4290 00 80 c0 e0 84 9d 20 20 00 00 00 00 20 20 20 20 ; " " &42a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &42b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &42c0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &42d0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &42e0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &42f0 f0 f0 f0 f0 20 20 20 83 f0 f0 f0 f0 9d 84 8d 4e &4300 f0 f0 f0 f0 69 63 65 20 f0 f0 f0 f0 6f 6e 65 21 &4310 f0 f0 f0 f0 21 20 20 84 f0 f0 f0 f0 9d 20 20 20 &4320 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4330 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4340 f0 f0 f0 f0 20 20 20 83 f0 f0 f0 f0 9d 84 8d 4e &4350 f0 f0 f0 f0 69 63 65 20 f0 f0 f0 f0 6f 6e 65 21 &4360 f0 f0 f0 f0 21 20 20 84 f0 f0 f0 f0 9d 20 20 20 &4370 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4380 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4390 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &43a0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &43b0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &43c0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &43d0 f0 f0 f0 f0 84 9d 20 20 00 80 c0 e0 20 20 20 20 &43e0 00 00 00 00 20 88 20 20 00 00 00 00 20 20 20 20 &43f0 00 00 00 00 20 95 ff f4 00 00 00 00 20 20 20 20 &4400 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4410 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4420 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4430 f0 f0 f0 f0 20 88 20 20 f0 f0 f0 f0 20 20 20 20 &4440 f0 f0 f0 f0 95 ea ff b7 f0 f0 f0 f0 20 20 20 20 &4450 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4460 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4470 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4480 f0 f0 f0 f0 20 88 20 20 f0 f0 f0 f0 20 20 20 20 &4490 f0 f0 f0 f0 95 ef ff 20 f0 f0 f0 f0 20 20 20 20 &44a0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &44b0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &44c0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &44d0 f0 f0 f0 f0 20 88 20 20 f0 f0 f0 f0 20 20 20 95 &44e0 f0 f0 f0 f0 e0 fa ff fd f0 f0 f0 f0 f4 f0 b0 20 &44f0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4500 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4510 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4520 00 80 c0 e0 20 88 95 f0 00 00 00 00 f0 f0 f0 fc &4530 00 00 00 00 ff ff ff ff 00 00 00 00 ff ff ff ff &4540 f0 f0 f0 f0 ff ff bd 20 f0 f0 f0 f0 20 20 20 20 &4550 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4560 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4570 f0 f0 f0 f0 20 88 95 ff f0 f0 f0 f0 ff ff ff ff &4580 f0 f0 f0 f0 ff ff ff ff f0 f0 f0 f0 ff ff ff ff &4590 f0 f0 f0 f0 fd fc b0 20 f0 f0 f0 f0 20 20 20 20 &45a0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &45b0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &45c0 f0 f0 f0 f0 20 88 95 ff f0 f0 f0 f0 ff ff ff ff &45d0 f0 f0 f0 f0 ff ff ff ff f0 f0 f0 f0 ff ff ff ff &45e0 f0 f0 f0 f0 f7 f3 20 20 f0 f0 f0 f0 20 20 20 20 &45f0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4600 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4610 f0 f0 f0 f0 20 88 95 ff f0 f0 f0 f0 ff ff ff ff &4620 f0 f0 f0 f0 ff ff ff ff f0 f0 f0 f0 ff ff ff ff &4630 f0 f0 f0 f0 af af a1 20 f0 f0 f0 f0 20 20 20 20 &4640 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4650 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4660 f0 f0 f0 f0 20 88 20 20 00 80 c0 e0 95 a2 af af &4670 00 00 00 00 af af a3 ab 00 00 00 00 af ff ff ff &4680 f0 f0 f0 f0 ff bd 20 20 f0 f0 f0 f0 20 20 20 20 &4690 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &46a0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &46b0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &46c0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &46d0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &46e0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &46f0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4700 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4710 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4720 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4730 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4740 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 81 9d &4750 f0 f0 f0 f0 87 8d 28 4e f0 f0 f0 f0 4f 57 20 44 &4760 f0 f0 f0 f0 4f 20 49 54 f0 f0 f0 f0 20 41 47 41 &4770 f0 f0 f0 f0 49 4e 21 21 f0 f0 f0 f0 29 20 20 84 &4780 f0 f0 f0 f0 9d 20 20 20 f0 f0 f0 f0 20 20 20 20 &4790 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 81 9d &47a0 f0 f0 f0 f0 87 8d 28 4e f0 f0 f0 f0 4f 57 20 44 &47b0 00 80 c0 e0 4f 20 49 54 00 00 00 00 20 41 47 41 &47c0 f0 f0 f0 f0 49 4e 21 21 f0 f0 f0 f0 29 20 20 84 &47d0 f0 f0 f0 f0 9d 20 20 20 f0 f0 f0 f0 20 20 20 20 &47e0 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &47f0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4800 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4810 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4820 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4830 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 86 &4840 f0 f0 f0 f0 28 43 29 20 f0 f0 f0 f0 4d 61 74 74 &4850 f0 f0 f0 f0 68 65 77 20 f0 f0 f0 f0 4e 65 77 6d &4860 f0 f0 f0 f0 61 6e 20 31 f0 f0 f0 f0 39 38 33 20 &4870 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &4880 f0 f0 f0 f0 84 9d 20 20 f0 f0 f0 f0 20 20 20 20 &4890 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48a0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48b0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48c0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48d0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48e0 f0 f0 f0 f0 20 20 20 20 f0 f0 f0 f0 20 20 20 20 &48f0 f0 f0 f0 f0 20 20 20 20 00 80 c0 e0 20 20 20 20 ; new_high_score_screen_data ; 0 1 2 3 4 5 6 7 8 9 a b c d e f ; <---------> <---------> &4900 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4910 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " ....Amcom's FORTRESS . " &4920 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " ....Amcom's FORTRESS . " &4930 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4940 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4950 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4960 00 00 00 00 87 9d 84 8d 00 00 00 00 41 6d 63 6f ; " ....Congratulations . " &4970 00 00 00 00 6d 27 73 20 00 00 00 00 46 4f 52 54 ; " ....Congratulations . " &4980 00 00 00 00 52 45 53 53 00 00 00 00 20 20 20 9c ; " " &4990 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &49a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &49b0 00 00 00 00 87 9d 84 8d 00 00 00 00 41 6d 63 6f ; " Your score is in the terrific ten! " &49c0 00 00 00 00 6d 27 73 20 00 00 00 00 46 4f 52 54 ; " " &49d0 00 00 00 00 52 45 53 53 00 00 00 00 20 20 20 9c ; " Please type your name, then press " &49e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &49f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " RETURN. " &4a00 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a10 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a20 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " ... . " &4a30 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a40 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a50 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a60 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a70 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a80 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4a90 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &4aa0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ab0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ac0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ad0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ae0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4af0 00 00 00 00 84 9d 83 8d 00 00 00 00 43 6f 6e 67 &4b00 ff 00 00 00 72 61 74 75 00 00 00 00 6c 61 74 69 &4b10 00 00 00 00 6f 6e 73 20 00 00 00 00 20 20 20 9c &4b20 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4b30 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4b40 00 00 00 00 84 9d 83 8d 00 00 00 00 43 6f 6e 67 &4b50 00 00 00 00 72 61 74 75 00 00 00 00 6c 61 74 69 &4b60 00 00 00 00 6f 6e 73 20 00 00 00 00 20 20 20 9c &4b70 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4b80 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4b90 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ba0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4bb0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4bc0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4bd0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4be0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4bf0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c00 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c10 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c20 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c30 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c40 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c50 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c60 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4c70 00 00 00 00 20 20 20 20 00 00 00 00 59 6f 75 72 &4c80 00 00 00 00 20 73 63 6f 00 00 00 00 72 65 20 69 &4c90 00 00 00 00 73 20 69 6e 00 00 00 00 20 74 68 65 &4ca0 00 00 00 00 20 74 65 72 00 00 00 00 72 69 66 69 &4cb0 00 00 00 00 63 20 74 65 00 00 00 00 6e 21 20 20 &4cc0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4cd0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ce0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4cf0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4d00 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4d10 00 00 00 00 20 20 20 20 00 00 00 00 50 6c 65 61 &4d20 00 00 00 00 73 65 20 74 00 00 00 00 79 70 65 20 &4d30 00 00 00 00 79 6f 75 72 00 00 00 00 20 6e 61 6d &4d40 00 00 00 00 65 2c 20 74 00 00 00 00 68 65 6e 20 &4d50 00 00 00 00 70 72 65 73 00 00 00 00 73 20 20 20 &4d60 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4d70 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4d80 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4d90 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4da0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4db0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4dc0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4dd0 00 00 00 00 20 52 45 54 00 00 00 00 55 52 4e 2e &4de0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4df0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e00 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e10 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e20 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e30 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e40 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e50 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e60 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e70 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e80 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4e90 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ea0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4eb0 00 00 00 00 20 84 9d 83 00 00 00 00 20 20 20 20 &4ec0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ed0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 9c &4ee0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ef0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f00 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f10 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f20 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f30 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f40 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f50 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f60 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f70 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f80 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4f90 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4fa0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4fb0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4fc0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4fd0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4fe0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &4ff0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5000 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5010 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5020 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5030 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5040 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5050 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5060 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5070 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5080 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5090 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &50f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; high_scores_screen_data ; 0 1 2 3 4 5 6 7 8 9 a b c d e f ; <---------> <---------> &5100 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5110 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " ....Amcom's FORTRESS . " &5120 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " ....Amcom's FORTRESS . " &5130 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5140 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " .The terrific ten... " &5150 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5160 00 00 00 00 87 9d 84 8d 00 00 00 00 41 6d 63 6f ; " " &5170 00 00 00 00 6d 27 73 20 00 00 00 00 46 4f 52 54 ; " 1 ... .... " &5180 00 00 00 00 52 45 53 53 00 00 00 00 20 20 20 9c ; " 2 ... .... " &5190 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " 3 ... .... " &51a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " 4 ... .... " &51b0 00 00 00 00 87 9d 84 8d 00 00 00 00 41 6d 63 6f ; " 5 ... .... " &51c0 00 00 00 00 6d 27 73 20 00 00 00 00 46 4f 52 54 ; " 6 ... .... " &51d0 00 00 00 00 52 45 53 53 00 00 00 00 20 20 20 9c ; " 7 ... .... " &51e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " 8 ... .... " &51f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " 9 ... .... " &5200 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " 10 ... .... " &5210 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5220 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5230 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5240 00 00 00 00 20 82 54 68 00 00 00 00 65 20 74 65 ; " .Press the.SPACE.bar or.(FIRE).on " &5250 00 00 00 00 72 72 69 66 00 00 00 00 69 63 20 74 ; " .joystick _1 to play. " &5260 00 00 00 00 65 6e 2e 2e 00 00 00 00 2e 20 20 20 ; " " &5270 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5280 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &5290 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; " " &52a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &52b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &52c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &52d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &52e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &52f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5300 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5310 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5320 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5330 00 00 00 00 20 20 20 20 00 00 00 00 20 20 31 20 &5340 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5350 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5360 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5370 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5380 00 00 00 00 20 20 20 20 00 00 00 00 20 20 32 20 &5390 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &53a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &53b0 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &53c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &53d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 33 20 &53e0 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &53f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5400 ff 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5410 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5420 00 00 00 00 20 20 20 20 00 00 00 00 20 20 34 20 &5430 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5440 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5450 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5460 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5470 00 00 00 00 20 20 20 20 00 00 00 00 20 20 35 20 &5480 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5490 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &54a0 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &54b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &54c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 36 20 &54d0 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &54e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &54f0 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5500 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5510 00 00 00 00 20 20 20 20 00 00 00 00 20 20 37 20 &5520 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5530 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5540 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5550 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5560 00 00 00 00 20 20 20 20 00 00 00 00 20 20 38 20 &5570 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5580 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5590 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &55a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &55b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 39 20 &55c0 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &55d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &55e0 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &55f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5600 ff 00 00 00 20 20 20 20 00 00 00 00 20 31 30 20 &5610 00 00 00 00 2e 2e 2e 20 00 00 00 00 20 20 20 20 &5620 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5630 00 00 00 00 20 20 20 87 00 00 00 00 2e 2e 2e 20 &5640 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5650 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5660 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5670 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5680 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5690 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &56f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5700 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5710 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5720 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5730 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5740 00 00 00 00 20 20 83 50 00 00 00 00 72 65 73 73 &5750 00 00 00 00 20 74 68 65 00 00 00 00 86 53 50 41 &5760 00 00 00 00 43 45 83 62 00 00 00 00 61 72 20 6f &5770 00 00 00 00 72 86 28 46 00 00 00 00 49 52 45 29 &5780 00 00 00 00 83 6f 6e 20 00 00 00 00 20 20 20 20 &5790 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &57a0 00 00 00 00 83 6a 6f 79 00 00 00 00 73 74 69 63 &57b0 00 00 00 00 6b 20 5f 31 00 00 00 00 20 74 6f 20 &57c0 00 00 00 00 70 6c 61 79 00 00 00 00 2e 20 20 20 &57d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &57e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &57f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5800 ff 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5810 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5820 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5830 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5840 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5850 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5860 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5870 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5880 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &5890 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58a0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58b0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58c0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58d0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58e0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 &58f0 00 00 00 00 20 20 20 20 00 00 00 00 20 20 20 20 ; unused # Source code fragment corresponding to &231a - &235a &5900 54 0d ; ... T &5902 06 7c 66 2e 48 4f 4c 45 20 4c 44 58 26 37 46 3a ; 1660.HOLE &5912 4c 44 41 26 33 46 30 46 2c 58 3a 53 45 43 3a 53 ; LDX&7F: &5922 42 43 23 31 34 32 3a 4c 44 58 26 37 44 3a 43 4d ; LDA&3F0F,X: &5932 50 26 33 45 35 30 2c 58 3a 42 43 53 53 4d 49 49 ; SEC: &5942 3a 43 4d 50 26 33 45 34 30 2c 58 3a 42 43 43 53 ; SBC#142: &5952 4d 49 49 3a 4c 44 58 26 37 46 3a 4c 44 41 26 33 ; LDX&7D: &5962 46 31 33 2c 58 0d ; CMP&3E50,X: ; BCSSMII: ; CMP&3E40,X: ; BCCSMII: ; LDX&7F: ; LDA&3F13,X &5968 06 86 82 53 45 43 3a 53 42 43 23 35 3a 4c 44 58 ; 1670SEC: &5978 26 37 44 3a 43 4d 50 26 33 45 32 30 2c 58 3a 42 ; SBC#5: &5988 43 43 53 4d 49 49 3a 43 4d 50 26 33 45 33 30 2c ; LDX&7D: &5998 58 3a 42 43 53 53 4d 49 49 3a 4c 44 41 23 30 3a ; CMP&3E20,X: &59a8 53 54 41 26 37 30 3a 4c 44 41 23 31 3a 53 54 41 ; BCCSMII: &59b8 26 37 31 3a 52 54 53 3a 2e 53 4d 49 49 20 4c 44 ; CMP&3E30,X: &59c8 41 26 37 31 3a 42 45 51 50 25 2b 33 3a 52 54 53 ; BCSSMII: &59d8 3a 4c 44 41 23 31 3a 53 54 41 26 37 30 3a 52 54 ; LDA#0: &59e8 53 0d ; STA&70: ; LDA#1: ; STA&71: ; RTS: ; .SMII ; LDA&71: ; BEQP%+3: ; RTS: ; LDA#1: ; STA&70: ; RTS ; &59ea 06 90 48 2e 43 4f 4c 20 82 23 37 3a 53 54 41 26 ; 1680.COL &59fa 46 45 32 31 3a 84 ; EOR #7 ; STA&FE21: ; OR ... # &5a00 - &60ff is moved to &0a00 - &10ff at &123e ; level_data ; level_1_data ; d t l fy &0a00 01 05 00 00 ; at distance &01, OBJECT_LARGE_WALL &0a04 1d 01 00 0a ; at distance &1d, OBJECT_FUEL, fy = &0a &0a08 28 03 00 0a ; at distance &28, OBJECT_SILO, fy = &0a &0a0c 30 ff 00 00 ; at distance &30, checkpoint &0a10 01 00 05 00 ; at distance &01, start 5 panels &0a14 01 01 00 0a ; at distance &01, OBJECT_FUEL, fy = &0a &0a18 12 02 00 0a ; at distance &12, OBJECT_TURRET, fy = &0a &0a1c 12 01 00 2a ; at distance &12, OBJECT_FUEL, fy = &2a &0a20 1a 03 8b 0a ; at distance &1a, OBJECT_SILO, fy = &0a, always fires at z = &0b &0a24 23 03 00 23 ; at distance &23, OBJECT_SILO, fy = &23 &0a28 2c 03 00 3c ; at distance &2c, OBJECT_SILO, fy = &3c &0a2c 30 01 00 0a ; at distance &30, OBJECT_FUEL, fy = &0a &0a30 35 01 00 0a ; at distance &35, OBJECT_FUEL, fy = &0a &0a34 3c 02 00 26 ; at distance &3c, OBJECT_TURRET, fy = &26 &0a38 42 ff 00 00 ; at distance &42, checkpoint &0a3c 03 03 8a 20 ; at distance &03, OBJECT_SILO, fy = &20, always fires at z = &0a &0a40 0b 03 00 0a ; at distance &0b, OBJECT_SILO, fy = &0a &0a44 0b 03 00 3c ; at distance &0b, OBJECT_SILO, fy = &3c &0a48 0e 00 04 00 ; at distance &0e, start 4 panels &0a4c 16 01 00 0a ; at distance &16, OBJECT_FUEL, fy = &0a &0a50 1d 01 00 0a ; at distance &1d, OBJECT_FUEL, fy = &0a &0a54 25 06 00 20 ; at distance &25, OBJECT_SMALL_WALL, length 0, fy = &20 &0a58 25 03 00 3c ; at distance &25, OBJECT_SILO, fy = &3c &0a5c 30 02 00 3c ; at distance &30, OBJECT_TURRET, fy = &3c &0a60 30 01 00 16 ; at distance &30, OBJECT_FUEL, fy = &16 &0a64 38 02 00 16 ; at distance &38, OBJECT_TURRET, fy = &16 &0a68 45 03 00 0a ; at distance &45, OBJECT_SILO, fy = &0a &0a6c 45 03 00 30 ; at distance &45, OBJECT_SILO, fy = &30 &0a70 50 ff 00 00 ; at distance &50, checkpoint &0a74 0a 00 02 00 ; at distance &0a, start 2 panels &0a78 0a 02 00 10 ; at distance &0a, OBJECT_TURRET, fy = &10 &0a7c 0a 03 00 40 ; at distance &0a, OBJECT_SILO, fy = &40 &0a80 10 01 00 40 ; at distance &10, OBJECT_FUEL, fy = &40 &0a84 15 03 00 28 ; at distance &15, OBJECT_SILO, fy = &28 &0a88 18 02 00 0a ; at distance &18, OBJECT_TURRET, fy = &0a &0a8c 20 02 00 0a ; at distance &20, OBJECT_TURRET, fy = &0a &0a90 28 ff 00 00 ; at distance &28, checkpoint &0a94 0d 00 04 00 ; at distance &0d, start 4 panels &0a98 10 02 00 1a ; at distance &10, OBJECT_TURRET, fy = &1a &0a9c 10 03 00 30 ; at distance &10, OBJECT_SILO, fy = &30 &0aa0 19 01 00 0a ; at distance &19, OBJECT_FUEL, fy = &0a &0aa4 20 01 00 0a ; at distance &20, OBJECT_FUEL, fy = &0a &0aa8 25 03 00 20 ; at distance &25, OBJECT_SILO, fy = &20 &0aac 25 09 00 00 ; at distance &25, OBJECT_FIGHTER &0ab0 31 03 00 0a ; at distance &31, OBJECT_SILO, fy = &0a &0ab4 39 03 00 1c ; at distance &39, OBJECT_SILO, fy = &1c &0ab8 41 03 00 2e ; at distance &41, OBJECT_SILO, fy = &2e &0abc 49 03 00 41 ; at distance &49, OBJECT_SILO, fy = &41 &0ac0 4d 01 00 0a ; at distance &4d, OBJECT_FUEL, fy = &0a &0ac4 50 02 00 25 ; at distance &50, OBJECT_TURRET, fy = &25 &0ac8 58 ff 00 00 ; at distance &58, checkpoint &0acc 0d 02 00 10 ; at distance &0d, OBJECT_TURRET, fy = &10 &0ad0 17 02 00 0a ; at distance &17, OBJECT_TURRET, fy = &0a &0ad4 17 03 00 30 ; at distance &17, OBJECT_SILO, fy = &30 &0ad8 19 00 06 00 ; at distance &19, start 6 panels &0adc 25 01 00 0a ; at distance &25, OBJECT_FUEL, fy = &0a &0ae0 25 02 00 2a ; at distance &25, OBJECT_TURRET, fy = &2a &0ae4 31 03 00 0a ; at distance &31, OBJECT_SILO, fy = &0a &0ae8 31 06 03 3c ; at distance &31, OBJECT_SMALL_WALL, length 3, fy = &3c &0aec 38 01 00 34 ; at distance &38, OBJECT_FUEL, fy = &34 &0af0 3d 02 00 0a ; at distance &3d, OBJECT_TURRET, fy = &0a &0af4 40 02 00 34 ; at distance &40, OBJECT_TURRET, fy = &34 &0af8 4d 01 00 0a ; at distance &4d, OBJECT_FUEL, fy = &0a &0afc 57 02 00 0a ; at distance &57, OBJECT_TURRET, fy = &0a &0b00 57 03 00 20 ; at distance &57, OBJECT_SILO, fy = &20 &0b04 57 03 00 38 ; at distance &57, OBJECT_SILO, fy = &38 &0b08 61 09 00 00 ; at distance &61, OBJECT_FIGHTER &0b0c 68 04 01 00 ; at distance &68, OBJECT_ELECTRIC_WALL &0b10 90 01 00 40 ; at distance &90, OBJECT_FUEL, fy = &40 &0b14 a0 ff 00 00 ; at distance &a0, checkpoint &0b18 01 00 06 00 ; at distance &01, start 6 panels &0b1c 01 02 00 10 ; at distance &01, OBJECT_TURRET, fy = &10 &0b20 01 03 00 30 ; at distance &01, OBJECT_SILO, fy = &30 &0b24 0d 02 00 10 ; at distance &0d, OBJECT_TURRET, fy = &10 &0b28 0d 03 00 30 ; at distance &0d, OBJECT_SILO, fy = &30 &0b2c 19 02 00 10 ; at distance &19, OBJECT_TURRET, fy = &10 &0b30 19 03 00 30 ; at distance &19, OBJECT_SILO, fy = &30 &0b34 25 01 00 0a ; at distance &25, OBJECT_FUEL, fy = &0a &0b38 25 02 00 20 ; at distance &25, OBJECT_TURRET, fy = &20 &0b3c 2d 02 00 0a ; at distance &2d, OBJECT_TURRET, fy = &0a &0b40 2d 03 00 20 ; at distance &2d, OBJECT_SILO, fy = &20 &0b44 35 09 00 00 ; at distance &35, OBJECT_FIGHTER &0b48 3d 03 00 0a ; at distance &3d, OBJECT_SILO, fy = &0a &0b4c 40 03 00 1a ; at distance &40, OBJECT_SILO, fy = &1a &0b50 43 03 00 2a ; at distance &43, OBJECT_SILO, fy = &2a &0b54 46 03 00 3a ; at distance &46, OBJECT_SILO, fy = &3a &0b58 4a 03 00 0a ; at distance &4a, OBJECT_SILO, fy = &0a &0b5c 4a 03 00 36 ; at distance &4a, OBJECT_SILO, fy = &36 &0b60 50 01 00 0a ; at distance &50, OBJECT_FUEL, fy = &0a &0b64 50 01 00 36 ; at distance &50, OBJECT_FUEL, fy = &36 &0b68 60 ff 00 00 ; at distance &60, checkpoint &0b6c 0d 00 04 00 ; at distance &0d, start 4 panels &0b70 0d 01 00 0a ; at distance &0d, OBJECT_FUEL, fy = &0a &0b74 10 03 00 20 ; at distance &10, OBJECT_SILO, fy = &20 &0b78 16 09 00 00 ; at distance &16, OBJECT_FIGHTER &0b7c 20 02 00 0a ; at distance &20, OBJECT_TURRET, fy = &0a &0b80 25 03 00 20 ; at distance &25, OBJECT_SILO, fy = &20 &0b84 31 01 00 0a ; at distance &31, OBJECT_FUEL, fy = &0a &0b88 3d 09 00 00 ; at distance &3d, OBJECT_FIGHTER &0b8c 50 ff 00 00 ; at distance &50, checkpoint &0b90 0a 02 00 0a ; at distance &0a, OBJECT_TURRET, fy = &0a &0b94 0f 00 03 00 ; at distance &0f, start 3 panels &0b98 11 03 00 0a ; at distance &11, OBJECT_SILO, fy = &0a &0b9c 18 02 00 0a ; at distance &18, OBJECT_TURRET, fy = &0a &0ba0 1a 03 00 30 ; at distance &1a, OBJECT_SILO, fy = &30 &0ba4 23 01 00 0a ; at distance &23, OBJECT_FUEL, fy = &0a &0ba8 23 03 00 29 ; at distance &23, OBJECT_SILO, fy = &29 &0bac 33 06 02 40 ; at distance &33, OBJECT_SMALL_WALL, length 2, fy = &40 &0bb0 40 01 00 3c ; at distance &40, OBJECT_FUEL, fy = &3c &0bb4 43 09 00 00 ; at distance &43, OBJECT_FIGHTER &0bb8 51 04 01 00 ; at distance &51, OBJECT_ELECTRIC_WALL &0bbc 70 01 00 30 ; at distance &70, OBJECT_FUEL, fy = &30 &0bc0 80 ff 00 00 ; at distance &80, checkpoint &0bc4 0d 00 05 00 ; at distance &0d, start 5 panels &0bc8 10 02 00 0a ; at distance &10, OBJECT_TURRET, fy = &0a &0bcc 17 03 00 20 ; at distance &17, OBJECT_SILO, fy = &20 &0bd0 1a 02 00 0a ; at distance &1a, OBJECT_TURRET, fy = &0a &0bd4 22 03 00 20 ; at distance &22, OBJECT_SILO, fy = &20 &0bd8 29 01 00 16 ; at distance &29, OBJECT_FUEL, fy = &16 &0bdc 29 09 00 00 ; at distance &29, OBJECT_FIGHTER &0be0 34 03 00 0a ; at distance &34, OBJECT_SILO, fy = &0a &0be4 3a 03 00 20 ; at distance &3a, OBJECT_SILO, fy = &20 &0be8 40 02 00 0a ; at distance &40, OBJECT_TURRET, fy = &0a &0bec 43 02 00 16 ; at distance &43, OBJECT_TURRET, fy = &16 &0bf0 49 08 00 0a ; at distance &49, OBJECT_BOSS, fy = &0a &0bf4 4c 09 00 00 ; at distance &4c, OBJECT_FIGHTER &0bf8 a0 08 00 0a ; at distance &a0, OBJECT_BOSS, fy = &0a &0bfc b0 ff 01 00 ; at distance &b0, checkpoint ; level_2_data ; d t l fy &0c00 01 05 00 00 ; at distance &01, OBJECT_LARGE_WALL &0c04 22 01 00 30 ; at distance &22, OBJECT_FUEL, fy = &30 &0c08 2c 01 00 20 ; at distance &2c, OBJECT_FUEL, fy = &20 &0c0c 34 03 00 0a ; at distance &34, OBJECT_SILO, fy = &0a &0c10 38 03 00 26 ; at distance &38, OBJECT_SILO, fy = &26 &0c14 3c ff 00 00 ; at distance &3c, checkpoint &0c18 01 00 06 00 ; at distance &01, start 6 panels &0c1c 01 02 00 0a ; at distance &01, OBJECT_TURRET, fy = &0a &0c20 09 03 00 0a ; at distance &09, OBJECT_SILO, fy = &0a &0c24 13 01 00 0a ; at distance &13, OBJECT_FUEL, fy = &0a &0c28 13 03 00 20 ; at distance &13, OBJECT_SILO, fy = &20 &0c2c 20 02 00 0a ; at distance &20, OBJECT_TURRET, fy = &0a &0c30 28 03 00 0a ; at distance &28, OBJECT_SILO, fy = &0a &0c34 31 03 00 1c ; at distance &31, OBJECT_SILO, fy = &1c &0c38 3a 03 00 0a ; at distance &3a, OBJECT_SILO, fy = &0a &0c3c 40 02 00 30 ; at distance &40, OBJECT_TURRET, fy = &30 &0c40 49 01 00 0a ; at distance &49, OBJECT_FUEL, fy = &0a &0c44 49 01 00 30 ; at distance &49, OBJECT_FUEL, fy = &30 &0c48 54 03 00 18 ; at distance &54, OBJECT_SILO, fy = &18 &0c4c 56 ff 00 00 ; at distance &56, checkpoint &0c50 0d 00 06 00 ; at distance &0d, start 6 panels &0c54 0d 02 00 1c ; at distance &0d, OBJECT_TURRET, fy = &1c &0c58 15 02 00 1c ; at distance &15, OBJECT_TURRET, fy = &1c &0c5c 1b 03 00 0a ; at distance &1b, OBJECT_SILO, fy = &0a &0c60 20 01 00 1c ; at distance &20, OBJECT_FUEL, fy = &1c &0c64 24 03 8a 0a ; at distance &24, OBJECT_SILO, fy = &0a, always fires at z = &0a &0c68 29 06 00 20 ; at distance &29, OBJECT_SMALL_WALL, length 0, fy = &20 &0c6c 2a 03 00 40 ; at distance &2a, OBJECT_SILO, fy = &40 &0c70 32 02 00 40 ; at distance &32, OBJECT_TURRET, fy = &40 &0c74 36 01 00 40 ; at distance &36, OBJECT_FUEL, fy = &40 &0c78 3d 03 00 0a ; at distance &3d, OBJECT_SILO, fy = &0a &0c7c 40 06 02 51 ; at distance &40, OBJECT_SMALL_WALL, length 2, fy = &51 &0c80 45 02 00 0a ; at distance &45, OBJECT_TURRET, fy = &0a &0c84 4a 01 00 0a ; at distance &4a, OBJECT_FUEL, fy = &0a &0c88 50 02 00 0a ; at distance &50, OBJECT_TURRET, fy = &0a &0c8c 60 ff 00 00 ; at distance &60, checkpoint &0c90 01 09 00 00 ; at distance &01, OBJECT_FIGHTER &0c94 0d 00 05 00 ; at distance &0d, start 5 panels &0c98 0d 03 00 0a ; at distance &0d, OBJECT_SILO, fy = &0a &0c9c 13 03 00 16 ; at distance &13, OBJECT_SILO, fy = &16 &0ca0 19 03 00 22 ; at distance &19, OBJECT_SILO, fy = &22 &0ca4 20 03 00 2e ; at distance &20, OBJECT_SILO, fy = &2e &0ca8 26 02 00 3a ; at distance &26, OBJECT_TURRET, fy = &3a &0cac 26 02 00 0a ; at distance &26, OBJECT_TURRET, fy = &0a &0cb0 29 03 8a 1c ; at distance &29, OBJECT_SILO, fy = &1c &0cb4 31 01 00 3a ; at distance &31, OBJECT_FUEL, fy = &3a &0cb8 31 02 00 0a ; at distance &31, OBJECT_TURRET, fy = &0a &0cbc 3d 02 00 18 ; at distance &3d, OBJECT_TURRET, fy = &18 &0cc0 44 03 00 3a ; at distance &44, OBJECT_SILO, fy = &3a &0cc4 44 01 00 18 ; at distance &44, OBJECT_FUEL, fy = &18 &0cc8 60 ff 00 00 ; at distance &60, checkpoint &0ccc 01 03 00 20 ; at distance &01, OBJECT_SILO, fy = &20 &0cd0 06 03 00 10 ; at distance &06, OBJECT_SILO, fy = &10 &0cd4 06 03 00 30 ; at distance &06, OBJECT_SILO, fy = &30 &0cd8 0b 03 00 20 ; at distance &0b, OBJECT_SILO, fy = &20 &0cdc 10 01 00 20 ; at distance &10, OBJECT_FUEL, fy = &20 &0ce0 10 00 05 00 ; at distance &10, start 5 panels &0ce4 16 03 00 0a ; at distance &16, OBJECT_SILO, fy = &0a &0ce8 16 03 00 28 ; at distance &16, OBJECT_SILO, fy = &28 &0cec 20 02 00 0a ; at distance &20, OBJECT_TURRET, fy = &0a &0cf0 24 03 8a 18 ; at distance &24, OBJECT_SILO, fy = &18, always fires at z = &0a &0cf4 28 01 00 0a ; at distance &28, OBJECT_FUEL, fy = &0a &0cf8 2a 03 c0 36 ; at distance &2a, OBJECT_SILO, fy = &36, never fires &0cfc 2d 02 00 18 ; at distance &2d, OBJECT_TURRET, fy = &18 &0d00 36 03 00 0a ; at distance &36, OBJECT_SILO, fy = &0a &0d04 36 02 00 20 ; at distance &36, OBJECT_TURRET, fy = &20 &0d08 36 03 00 34 ; at distance &36, OBJECT_SILO, fy = &34 &0d0c 40 01 00 18 ; at distance &40, OBJECT_FUEL, fy = &18 &0d10 46 03 00 18 ; at distance &46, OBJECT_SILO, fy = &18 &0d14 58 ff 00 00 ; at distance &58, checkpoint &0d18 06 00 07 00 ; at distance &06, start 7 panels &0d1c 09 03 00 13 ; at distance &09, OBJECT_SILO, fy = &13 &0d20 12 03 00 24 ; at distance &12, OBJECT_SILO, fy = &24 &0d24 1b 02 00 18 ; at distance &1b, OBJECT_TURRET, fy = &18 &0d28 25 01 00 38 ; at distance &25, OBJECT_FUEL, fy = &38 &0d2c 2c 03 00 24 ; at distance &2c, OBJECT_SILO, fy = &24 &0d30 30 03 00 16 ; at distance &30, OBJECT_SILO, fy = &16 &0d34 33 02 00 0a ; at distance &33, OBJECT_TURRET, fy = &0a &0d38 37 09 00 00 ; at distance &37, OBJECT_FIGHTER &0d3c 40 03 00 30 ; at distance &40, OBJECT_SILO, fy = &30 &0d40 43 01 00 0a ; at distance &43, OBJECT_FUEL, fy = &0a &0d44 4c 06 03 30 ; at distance &4c, OBJECT_SMALL_WALL, length 3, fy = &30 &0d48 4f 03 00 0a ; at distance &4f, OBJECT_SILO, fy = &0a &0d4c 5d 01 00 38 ; at distance &5d, OBJECT_FUEL, fy = &38 &0d50 63 09 00 00 ; at distance &63, OBJECT_FIGHTER &0d54 69 02 00 38 ; at distance &69, OBJECT_TURRET, fy = &38 &0d58 72 04 01 00 ; at distance &72, OBJECT_ELECTRIC_WALL &0d5c 74 03 00 14 ; at distance &74, OBJECT_SILO, fy = &14 &0d60 78 03 00 24 ; at distance &78, OBJECT_SILO, fy = &24 &0d64 8e 01 00 0a ; at distance &8e, OBJECT_FUEL, fy = &0a &0d68 b0 ff 00 00 ; at distance &b0, checkpoint &0d6c 01 09 00 00 ; at distance &01, OBJECT_FIGHTER &0d70 01 00 06 00 ; at distance &01, start 6 panels &0d74 06 03 00 18 ; at distance &06, OBJECT_SILO, fy = &18 &0d78 0d 02 00 18 ; at distance &0d, OBJECT_TURRET, fy = &18 &0d7c 15 03 00 10 ; at distance &15, OBJECT_SILO, fy = &10 &0d80 15 03 00 20 ; at distance &15, OBJECT_SILO, fy = &20 &0d84 19 01 00 18 ; at distance &19, OBJECT_FUEL, fy = &18 &0d88 25 01 00 18 ; at distance &25, OBJECT_FUEL, fy = &18 &0d8c 2a 02 00 18 ; at distance &2a, OBJECT_TURRET, fy = &18 &0d90 34 03 00 10 ; at distance &34, OBJECT_SILO, fy = &10 &0d94 38 03 00 20 ; at distance &38, OBJECT_SILO, fy = &20 &0d98 3c 03 00 30 ; at distance &3c, OBJECT_SILO, fy = &30 &0d9c 40 03 00 40 ; at distance &40, OBJECT_SILO, fy = &40 &0da0 49 01 00 18 ; at distance &49, OBJECT_FUEL, fy = &18 &0da4 49 03 00 30 ; at distance &49, OBJECT_SILO, fy = &30 &0da8 49 03 00 40 ; at distance &49, OBJECT_SILO, fy = &40 &0dac 4a 09 00 00 ; at distance &4a, OBJECT_FIGHTER &0db0 50 01 00 40 ; at distance &50, OBJECT_FUEL, fy = &40 &0db4 56 02 00 40 ; at distance &56, OBJECT_TURRET, fy = &40 &0db8 65 ff 00 00 ; at distance &65, checkpoint &0dbc 01 00 03 00 ; at distance &01, start 3 panels &0dc0 0a 03 00 18 ; at distance &0a, OBJECT_SILO, fy = &18 &0dc4 0e 09 00 00 ; at distance &0e, OBJECT_FIGHTER &0dc8 10 06 01 30 ; at distance &10, OBJECT_SMALL_WALL, length 1, fy = &30 &0dcc 18 01 00 18 ; at distance &18, OBJECT_FUEL, fy = &18 &0dd0 20 09 00 00 ; at distance &20, OBJECT_FIGHTER &0dd4 25 01 00 18 ; at distance &25, OBJECT_FUEL, fy = &18 &0dd8 29 02 00 18 ; at distance &29, OBJECT_TURRET, fy = &18 &0ddc 3c ff 00 00 ; at distance &3c, checkpoint &0de0 02 00 02 00 ; at distance &02, start 2 panels &0de4 03 02 00 18 ; at distance &03, OBJECT_TURRET, fy = &18 &0de8 0d 03 00 0a ; at distance &0d, OBJECT_SILO, fy = &0a &0dec 0d 09 00 00 ; at distance &0d, OBJECT_FIGHTER &0df0 10 01 00 18 ; at distance &10, OBJECT_FUEL, fy = &18 &0df4 19 02 00 18 ; at distance &19, OBJECT_TURRET, fy = &18 &0df8 19 03 00 0a ; at distance &19, OBJECT_SILO, fy = &0a &0dfc 19 03 00 28 ; at distance &19, OBJECT_SILO, fy = &28 &0e00 20 05 00 00 ; at distance &20, OBJECT_LARGE_WALL &0e04 23 03 00 18 ; at distance &23, OBJECT_SILO, fy = &18 &0e08 25 03 00 24 ; at distance &25, OBJECT_SILO, fy = &24 &0e0c 44 09 00 00 ; at distance &44, OBJECT_FIGHTER &0e10 44 00 02 00 ; at distance &44, start 2 panels &0e14 53 02 00 0a ; at distance &53, OBJECT_TURRET, fy = &0a &0e18 56 03 00 24 ; at distance &56, OBJECT_SILO, fy = &24 &0e1c 5a 02 00 0a ; at distance &5a, OBJECT_TURRET, fy = &0a &0e20 5c 03 00 24 ; at distance &5c, OBJECT_SILO, fy = &24 &0e24 64 01 00 18 ; at distance &64, OBJECT_FUEL, fy = &18 &0e28 72 ff 00 00 ; at distance &72, checkpoint &0e2c 01 00 05 00 ; at distance &01, start 5 panels &0e30 01 03 00 0a ; at distance &01, OBJECT_SILO, fy = &0a &0e34 05 03 00 16 ; at distance &05, OBJECT_SILO, fy = &16 &0e38 0d 09 00 00 ; at distance &0d, OBJECT_FIGHTER &0e3c 16 02 00 0a ; at distance &16, OBJECT_TURRET, fy = &0a &0e40 19 03 00 18 ; at distance &19, OBJECT_SILO, fy = &18 &0e44 20 02 00 0a ; at distance &20, OBJECT_TURRET, fy = &0a &0e48 27 01 00 16 ; at distance &27, OBJECT_FUEL, fy = &16 &0e4c 35 02 00 0a ; at distance &35, OBJECT_TURRET, fy = &0a &0e50 39 02 00 1a ; at distance &39, OBJECT_TURRET, fy = &1a &0e54 3d 02 00 18 ; at distance &3d, OBJECT_TURRET, fy = &18 &0e58 3d 09 00 00 ; at distance &3d, OBJECT_FIGHTER &0e5c 40 08 00 16 ; at distance &40, OBJECT_BOSS, fy = &16 &0e60 a0 08 00 16 ; at distance &a0, OBJECT_BOSS, fy = &16 &0e64 c0 ff 01 00 ; at distance &c0, end of level ; check_joystick &0e68 ad 40 fe LDA &fe40 ; System VIA port B input/output register # &10 clear if first joystick button pressed &0e6b 29 10 AND #&10 &0e6d 49 10 EOR #&10 &0e6f 85 20 STA &20 ; joystick_fire # Set to non-zero if fire pressed &0e71 ad c0 fe LDA &fec0 ; ADC conversion status # &80 clear if conversion completed &0e74 30 1a BMI &0e90 ; leave &0e76 84 24 STY &24 ; tmp_y &0e78 ac 90 3f LDY &3f90 ; adc_channel &0e7b ad c0 fe LDA &fec0 ; ADC conversion status &0e7e 29 30 AND #&30 &0e80 0a ASL A &0e81 0a ASL A &0e82 99 91 3f STA &3f91,Y ; adc_channel_values &0e85 98 TYA &0e86 a4 24 LDY &24 ; tmp_y &0e88 49 01 EOR #&01 &0e8a 8d 90 3f STA &3f90 ; adc_channel &0e8d 8d c0 fe STA &fec0 ; ADC start conversion # Start 8 bit conversion on next channel ; leave &0e90 60 RTS ; check_for_movement &0e91 a5 21 LDA &21 ; keyboard_or_joystick # Zero if using keyboard &0e93 f0 44 BEQ &0ed9 ; to_check_for_keypress &0e95 e4 32 CPX &32 ; key_left &0e97 d0 0e BNE &0ea7 ; consider_checking_right &0e99 a9 80 LDA #&80 # Leave with non-zero if joystick left &0e9b ae 91 3f LDX &3f91 ; adc_channel_values &0e9e e0 c0 CPX #&c0 &0ea0 f0 02 BEQ &0ea4 ; joystick_is_left &0ea2 a9 00 LDA #&00 # Leave with zero if joystick not left ; joystick_is_left &0ea4 49 00 EOR #&00 &0ea6 60 RTS ; consider_checking_right &0ea7 e4 33 CPX &33 ; key_right &0ea9 d0 0c BNE &0eb7 ; consider_checking_up &0eab a9 80 LDA #&80 # Leave with non-zero if joystick right &0ead ae 91 3f LDX &3f91 ; adc_channel_values &0eb0 f0 02 BEQ &0eb4 ; joystick_is_right &0eb2 a9 00 LDA #&00 # Leave with zero if joystick not right ; joystick_is_right &0eb4 49 00 EOR #&00 &0eb6 60 RTS ; consider_checking_up &0eb7 e4 30 CPX &30 ; key_up &0eb9 d0 0c BNE &0ec7 ; consider_checking_down &0ebb a9 80 LDA #&80 # Leave with non-zero if joystick up &0ebd ae 92 3f LDX &3f92 ; adc_channel_values + 1 &0ec0 f0 02 BEQ &0ec4 ; joystick_is_up &0ec2 a9 00 LDA #&00 # Leave with zero if joystick not up ; joystick_is_up &0ec4 49 00 EOR #&00 &0ec6 60 RTS ; consider_checking_down &0ec7 e4 31 CPX &31 ; key_down &0ec9 d0 0e BNE &0ed9 ; to_check_for_keypress &0ecb a9 80 LDA #&80 # Leave with non-zero if joystick down &0ecd ae 92 3f LDX &3f92 ; adc_channel_values + 1 &0ed0 e0 c0 CPX #&c0 &0ed2 f0 02 BEQ &0ed6 ; joystick_is_down &0ed4 a9 00 LDA #&00 # Leave with zero if joystick not down ; joystick_is_down &0ed6 49 00 EOR #&00 &0ed8 60 RTS ; to_check_for_keypress &0ed9 4c a2 12 JMP &12a2 ; check_for_keypress # Returns and leaves with non-zero if key pressed ; unused &0edc 3a 50 ; completion_screen_video_register_data &0ede 3f ; R0: Horizontal total register &0edf 28 ; R1: Number of characters per line &0ee0 33 ; R2: Horizontal sync position register &0ee1 24 ; R3: Sync width register &0ee0 1e ; R4: Vertical total register &0ee3 02 ; R5: Vertical total adjust register &0ee4 19 ; R6: Vertical displayed register &0ee5 1b ; R7: Vertical sync position &0ee6 93 ; R8: Interlace and delay register &0ee7 12 ; R9: Scan lines per character register &0ee8 01 ; R10: Cursor start register &0ee9 00 ; R11: Cursor end register &0eea 28 ; R12: Displayed screen start address register (high) &0eeb 00 ; R13: Displayed screen start address register (low) ; game_video_register_data &0eec 3f 00 ; R0: Horizontal total register &0eee 28 01 ; R1: Number of characters per line &0ef0 31 02 ; R2: Horizontal sync position register &0ef2 14 03 ; R3: Sync width register &0ef4 4c 04 ; R4: Vertical total register &0ef6 00 05 ; R5: Vertical total adjust register &0ef8 32 06 ; R6: Vertical displayed register &0efa 41 07 ; R7: Vertical sync position &0efc 00 08 ; R8: Interlace and delay register &0efe 03 09 ; R9: Scan lines per character register # Four rows per group ; check_for_high_score &0f00 78 SEI &0f01 a5 10 LDA &10 ; previous_irq1_vector_low &0f03 8d 04 02 STA &0204 ; irq1_vector_low &0f06 a5 11 LDA &11 ; previous_irq1_vector_high &0f08 8d 05 02 STA &0205 ; irq1_vector_high &0f0b a9 ff LDA #&ff # Enable all System VIA interrupts &0f0d 8d 4e fe STA &fe4e ; System VIA interrupt enable register &0f10 a9 7f LDA #&7f # Disable all User VIA interrupts &0f12 8d 6e fe STA &fe6e ; User VIA interrupt enable register &0f15 58 CLI &0f16 a9 13 LDA #&13 ; Wait for vertical retrace &0f18 20 f4 ff JSR &fff4 ; OSBYTE &0f1b a2 00 LDX #&00 ; all buffers &0f1d a9 0f LDA #&0f ; Flush buffers &0f1f 20 f4 ff JSR &fff4 ; OSBYTE &0f22 a9 fe LDA #&fe ; Read/Write available RAM, keyboard extensions &0f24 a2 40 LDX #&40 # Set &028e (os_available_ram) to &40 &0f26 20 f4 ff JSR &fff4 ; OSBYTE # i.e. pretend system has 16k of RAM &0f29 a9 16 LDA #&16 # Change to MODE 7 &0f2b 20 ee ff JSR &ffee ; OSWRCH &0f2e a9 07 LDA #&07 &0f30 20 ee ff JSR &ffee ; OSWRCH &0f33 a9 ca LDA #&ca ; Read/Write Keyboard Status &0f35 a2 20 LDX #&20 ; Enable CAPS LOCK, disable SHIFT LOCK &0f37 a0 cf LDY #&cf &0f39 20 f4 ff JSR &fff4 ; OSBYTE &0f3c a2 00 LDX #&00 &0f3e a9 10 LDA #&10 ; &3d10 = high_scores &0f40 85 70 STA &70 ; high_score_address_low &0f42 a9 3d LDA #&3d &0f44 85 71 STA &71 ; high_score_address_high &0f46 86 80 STX &80 ; player_rank &0f48 e8 INX ; check_for_high_score_rank_loop &0f49 a0 02 LDY #&02 ; check_for_high_score_byte_loop &0f4b b9 58 3f LDA &3f58,Y ; score &0f4e d1 70 CMP (&70),Y ; high_score_address &0f50 90 05 BCC &0f57 ; consider_next_rank &0f52 d0 12 BNE &0f66 ; new_high_score &0f54 88 DEY &0f55 10 f4 BPL &0f4b ; check_for_high_score_byte_loop ; consider_next_rank &0f57 a5 70 LDA &70 ; high_score_address_low &0f59 18 CLC &0f5a 69 12 ADC #&12 &0f5c 85 70 STA &70 ; high_score_address_low &0f5e e8 INX &0f5f e0 0b CPX #&0b &0f61 d0 e6 BNE &0f49 ; check_for_high_score_rank_loop &0f63 4c 14 10 JMP &1014 ; high_score_screen ; new_high_score &0f66 86 80 STX &80 ; player_rank &0f68 a9 49 LDA #&49 ; &4900 = new_high_score_screen_data &0f6a 85 74 STA &74 ; new_high_score_screen_data_address_high &0f6c a0 00 LDY #&00 &0f6e 84 73 STY &73 ; new_high_score_screen_data_address_low &0f70 84 75 STY &75 ; screen_address_low &0f72 a9 7c LDA #&7c &0f74 85 76 STA &76 ; screen_address_high ; copy_new_high_score_screen_data_loop # Display new high score screen &0f76 a5 73 LDA &73 ; new_high_score_screen_data_address_low &0f78 09 04 ORA #&04 &0f7a 85 73 STA &73 ; new_high_score_screen_data_address_low &0f7c b1 73 LDA (&73),Y ; new_high_score_screen_data_address &0f7e 91 75 STA (&75),Y ; screen_address &0f80 e6 73 INC &73 ; new_high_score_screen_data_address_low &0f82 d0 02 BNE &0f86 ; skip_page &0f84 e6 74 INC &74 ; new_high_score_screen_data_address_high ; skip_page &0f86 e6 75 INC &75 ; screen_address_low &0f88 d0 ec BNE &0f76 ; copy_new_high_score_screen_data_loop &0f8a e6 76 INC &76 ; screen_address_high &0f8c 10 e8 BPL &0f76 ; copy_new_high_score_screen_data_loop &0f8e a9 a0 LDA #&a0 ; &3da0 = high_scores + 8 * &12 &0f90 85 73 STA &73 ; source_address_low &0f92 a9 3d LDA #&3d &0f94 85 74 STA &74 ; source_address_high &0f96 85 76 STA &76 ; target_address_high &0f98 a9 b2 LDA #&b2 ; &3db2 = high_scores + 9 * &12 &0f9a 85 75 STA &75 ; target_address_low &0f9c e0 0a CPX #&0a &0f9e f0 1b BEQ &0fbb ; skip_shuffling_scores ; shuffle_scores_rank_loop &0fa0 a0 11 LDY #&11 ; shuffle_scores_byte_loop &0fa2 b1 73 LDA (&73),Y ; source_address &0fa4 91 75 STA (&75),Y ; target_address &0fa6 88 DEY &0fa7 10 f9 BPL &0fa2 ; shuffle_scores_byte_loop &0fa9 a5 73 LDA &73 ; source_address_low &0fab 38 SEC &0fac e9 12 SBC #&12 &0fae 85 73 STA &73 ; source_address_low &0fb0 a5 75 LDA &75 ; target_address_low &0fb2 38 SEC &0fb3 e9 12 SBC #&12 &0fb5 85 75 STA &75 ; target_address_low &0fb7 c5 70 CMP &70 ; high_score_address_low &0fb9 d0 e5 BNE &0fa0 ; shuffle_scores_rank_loop ; skip_shuffling_scores &0fbb a9 1f LDA #&1f # TAB(&0c, &12) &0fbd 20 ee ff JSR &ffee ; OSWRCH &0fc0 a9 0c LDA #&0c &0fc2 20 ee ff JSR &ffee ; OSWRCH &0fc5 a9 12 LDA #&12 &0fc7 20 ee ff JSR &ffee ; OSWRCH &0fca a9 7e LDA #&7e ; Acknowledge ESCAPE condition &0fcc 20 f4 ff JSR &fff4 ; OSBYTE &0fcf a9 09 LDA #&09 ; &0900 = name_buffer &0fd1 85 51 STA &51 ; input_block + 1 &0fd3 a9 0f LDA #&0f ; 15 characters maximum &0fd5 85 52 STA &52 ; input_block + 2 &0fd7 a0 00 LDY #&00 &0fd9 84 50 STY &50 ; input_block &0fdb a9 20 LDA #&20 ; " " &0fdd 85 53 STA &53 ; input_block + 3 &0fdf a9 87 LDA #&87 ; TELETEXT_WHITE &0fe1 85 54 STA &54 ; input_block + 4 &0fe3 98 TYA ; 0 ; Input line &0fe4 a2 50 LDX #&50 ; &0050 = input_block &0fe6 20 f1 ff JSR &fff1 ; OSWORD # Get name into name_buffer &0fe9 90 0d BCC &0ff8 ; escape_not_pressed &0feb a0 04 LDY #&04 ; copy_amcom_string_loop &0fed b9 fb 10 LDA &10fb,Y ; amcom_string # Use "Amcom" if ESCAPE pressed &0ff0 99 00 09 STA &0900,Y ; name_buffer &0ff3 88 DEY &0ff4 10 f7 BPL &0fed ; copy_amcom_string_loop &0ff6 a0 05 LDY #&05 ; escape_not_pressed &0ff8 a9 00 LDA #&00 ; wipe_unused_part_of_input_block_loop &0ffa 99 00 09 STA &0900,Y ; input_block &0ffd c8 INY &0ffe c0 11 CPY #&11 &1000 d0 f8 BNE &0ffa ; wipe_unused_part_of_input_block_loop ; copy_name_into_high_scores_loop &1002 b9 fd 08 LDA &08fd,Y ; input_block - 3 &1005 91 70 STA (&70),Y ; high_score_address &1007 88 DEY &1008 10 f8 BPL &1002 ; copy_name_into_high_scores_loop &100a a0 02 LDY #&02 ; copy_score_into_high_scores_loop &100c b9 58 3f LDA &3f58,Y ; score &100f 91 70 STA (&70),Y ; high_score_address &1011 88 DEY &1012 10 f8 BPL &100c ; copy_score_into_high_scores_loop ; high_score_screen &1014 a9 51 LDA #&51 ; &5100 = high_scores_screen_data &1016 85 74 STA &74 ; high_scores_screen_data_address_high &1018 a0 00 LDY #&00 &101a 84 73 STY &73 ; high_scores_screen_data_address_low &101c 84 75 STY &75 ; screen_address_low &101e a9 7c LDA #&7c &1020 85 76 STA &76 ; screen_address_high ; copy_high_scores_screen_data_loop # Display high scores screen &1022 a5 73 LDA &73 ; high_scores_screen_data_address_low &1024 09 04 ORA #&04 &1026 85 73 STA &73 ; high_scores_screen_data_address_low &1028 b1 73 LDA (&73),Y ; high_scores_screen_data_address &102a 91 75 STA (&75),Y ; screen_address &102c e6 73 INC &73 ; high_scores_screen_data_address_low &102e d0 02 BNE &1032 ; copy_high_scores_screen_data_loop &1030 e6 74 INC &74 ; high_scores_screen_data_address_high &1032 e6 75 INC &75 ; screen_address_high &1034 d0 ec BNE &1022 ;copy_high_scores_screen_data_loop &1036 e6 76 INC &76 ; screen_address_low &1038 10 e8 BPL &1022 ; copy_high_scores_screen_data_loop ; copy_names_to_screen # Display names &103a a2 0a LDX #&0a &103c a9 13 LDA #&13 ; &3d13 = high_scores + 3 &103e 85 70 STA &70 ; high_scores_address_low &1040 a9 3d LDA #&3d &1042 85 71 STA &71 ; high_scores_address_high &1044 a9 7d LDA #&7d ; &7d24 = &7c00 + 7 * 40 + 12 # Start at (&0c, &07) &1046 85 73 STA &73 ; screen_address_high &1048 a9 24 LDA #&24 &104a 85 72 STA &72 ; screen_address_low ; copy_names_to_screen_rank_loop &104c a0 0e LDY #&0e ; copy_names_to_screen_byte_loop &104e b1 70 LDA (&70),Y ; high_scores_address &1050 91 72 STA (&72),Y ; screen_address &1052 88 DEY &1053 10 f9 BPL &104e ; copy_names_to_screen_byte_loop &1055 a5 70 LDA &70 ; high_scores_address_low &1057 18 CLC &1058 69 12 ADC #&12 &105a 85 70 STA &70 ; high_scores_address_low &105c a5 72 LDA &72 ; screen_address_low &105e 18 CLC &105f 69 28 ADC #&28 &1061 85 72 STA &72 ; screen_address_low &1063 90 02 BCC &1067 ; skip_page &1065 e6 73 INC &73 ; screen_address_high ; skip_page &1067 ca DEX &1068 d0 e2 BNE &104c ; copy_names_to_screen_rank_loop ; copy_scores_to_screen # Display scores &106a a2 0a LDX #&0a &106c 86 78 STX &78 ; rank_count &106e a9 10 LDA #&10 ; &3d10 = high_scores &1070 85 70 STA &70 ; high_scores_address_low &1072 a9 7d LDA #&7d ; &7d38 = &7c00 + 7 * 40 + 32 # Start at (&20, &07) &1074 85 73 STA &73 ; screen_address_high &1076 a9 38 LDA #&38 &1078 85 72 STA &72 ; screen_address_low ; copy_scores_to_screen_rank_loop &107a a9 00 LDA #&00 &107c 85 75 STA &75 ; screen_offset &107e a0 02 LDY #&02 &1080 85 77 STA &77 ; suppress_leading_zeros ; copy_scores_to_screen_byte_loop &1082 b1 70 LDA (&70),Y ; high_scores_address &1084 84 76 STY &76 ; number_count &1086 a4 75 LDY &75 ; screen_offset &1088 aa TAX &1089 05 77 ORA &77 ; suppress_leading_zeros &108b f0 20 BEQ &10ad ; skip_byte &108d 8a TXA &108e 4a LSR A &108f 4a LSR A &1090 4a LSR A &1091 4a LSR A &1092 85 79 STA &79 ; byte &1094 05 77 ORA &77 ; suppress_leading_zeros &1096 f0 07 BEQ &109f ; skip_digit &1098 a5 79 LDA &79 ; byte &109a 18 CLC &109b 69 30 ADC #&30 ; "0" &109d 91 72 STA (&72),Y ; screen_address # Display first digit of pair ; skip_digit &109f c8 INY &10a0 8a TXA &10a1 29 0f AND #&0f &10a3 18 CLC &10a4 69 30 ADC #&30 ; "0" &10a6 91 72 STA (&72),Y ; screen_address # Display second digit of pair &10a8 8a TXA &10a9 05 77 ORA &77 ; suppress_leading_zeros &10ab 85 77 STA &77 ; suppress_leading_zeros ; skip_byte &10ad a5 75 LDA &75 ; screen_offset &10af 18 CLC &10b0 69 02 ADC #&02 &10b2 85 75 STA &75 ; screen_offset &10b4 a4 76 LDY &76 ; number_count &10b6 88 DEY &10b7 10 c9 BPL &1082 ; copy_scores_to_screen_byte_loop &10b9 a5 70 LDA &70 ; high_scores_address_low &10bb 18 CLC &10bc 69 12 ADC #&12 &10be 85 70 STA &70 ; high_scores_address_low &10c0 a5 72 LDA &72 ; screen_address_low &10c2 18 CLC &10c3 69 28 ADC #&28 &10c5 85 72 STA &72 ; screen_address_low &10c7 90 02 BCC &10cb ; skip_page &10c9 e6 73 INC &73 ; screen_address_high ; skip_page &10cb c6 78 DEC &78 ; count &10cd d0 ab BNE &107a ; copy_scores_to_screen_rank_loop &10cf a9 0b LDA #&0b ; R11: Cursor end register &10d1 8d 00 fe STA &fe00 ; video register number &10d4 a9 00 LDA #&00 &10d6 8d 01 fe STA &fe01 ; video register value &10d9 a9 7c LDA #&7c ; &7cf0 = &7c00 + 6 * 40 # Start at (&00, &06) &10db 85 71 STA &71 ; screen_address_high &10dd a9 f0 LDA #&f0 &10df 85 70 STA &70 ; screen_address_low &10e1 a4 80 LDY &80 ; player_rank &10e3 f0 0f BEQ &10f4 ; set_rank_flash &10e5 18 CLC ; calculate_rank_flash_address_loop &10e6 a5 70 LDA &70 ; screen_address_low &10e8 18 CLC &10e9 69 28 ADC #&28 ; 40 &10eb 85 70 STA &70 ; screen_address_low &10ed 90 02 BCC &10f1 ; skip_page &10ef e6 71 INC &71 ; screen_address_high ; skip_page &10f1 88 DEY &10f2 d0 f2 BNE &10e6 ; calculate_rank_flash_address_loop ; set_rank_flash &10f4 a9 88 LDA #&88 ; TELETEXT_FLASH &10f6 a0 00 LDY #&00 &10f8 91 70 STA (&70),Y ; screen_address # Make new high score flash &10fa 60 RTS ; amcom_string &10fb 41 6d 63 6f 6d ; "Amcom" # &6100 - &62ff is used unrelocated ; entry_point &6100 a9 0f LDA #&0f ; Flush buffers &6102 a2 00 LDX #&00 ; all buffers &6104 20 f4 ff JSR &fff4 ; OSBYTE &6107 a2 ff LDX #&ff &6109 9a TXS &610a a9 16 LDA #&16 # Change to MODE 7 &610c 20 ee ff JSR &ffee ; OSWRCH &610f a9 07 LDA #&07 &6111 20 ee ff JSR &ffee ; OSWRCH &6114 78 SEI &6115 a9 03 LDA #&03 ; 0000 0011 # Reset ACIA &6117 8d 08 fe STA &fe08 ; Cassette ACIA control register &611a a9 9d LDA #&9d ; 1001 1101 # Turn on cassette motor; cassette system has control &611c 8d 10 fe STA &fe10 ; Serial ULA control register ; write_searching &611f a0 08 LDY #&08 ; write_searching_loop &6121 b9 93 62 LDA &6293,Y ; searching_string &6124 99 50 7c STA &7c50,Y ; screen_memory + &50 # Write "Searching" &6127 88 DEY &6128 10 f7 BPL &6121 ; write_searching_loop &612a a9 91 LDA #&91 ; 1001 0001 # 1200 baud, even parity, 2 stop bits, 8 bit word &612c 8d 08 fe STA &fe08 ; Cassette ACIA control register ; wait_for_framing_error &612f a9 04 LDA #&04 &6131 2d 08 fe AND &fe08 ; Cassette ACIA status register # &04 set if framing error occurred &6134 f0 f9 BEQ &612f ; wait_for_framing_error &6136 a0 f0 LDY #&f0 &6138 84 01 STY &01 ; eor &613a a9 73 LDA #&73 ; &6173 = first_stage_read_next_block &613c 85 51 STA &51 ; call_read_next_block + 1 &613e a9 4c LDA #&4c ; JMP &6140 85 50 STA &50 ; call_read_next_block &6142 a9 61 LDA #&61 &6144 85 52 STA &52 ; call_read_next_block + 2 ; wait_for_start_of_data ; wait_for_interrupt &6146 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6149 10 fb BPL &6146 ; wait_for_interrupt &614b ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &614e 29 70 AND #&70 &6150 d0 f4 BNE &6146 ; wait_for_start_of_data &6152 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte of nonsense data &6155 45 01 EOR &01 ; eor &6157 f0 07 BEQ &6160 ; skip_resetting_eor &6159 a0 f0 LDY #&f0 &615b 84 01 STY &01 ; eor &615d 4c 46 61 JMP &6146 ; wait_for_start_of_data ; skip_resetting_eor &6160 e6 01 INC &01 ; eor &6162 d0 e2 BNE &6146 ; wait_for_start_of_data ; write_found &6164 a0 08 LDY #&08 ; write_found_loop &6166 b9 8a 62 LDA &628a,Y ; found_string &6169 99 50 7c STA &7c50,Y ; screen_memory + &50 # Write "Found " &616c 88 DEY &616d 10 f7 BPL &6166 ; write_found_loop &616f a0 06 LDY #&06 &6171 84 05 STY &05 ; block_screen_offset ; first_stage_read_next_block &6173 20 b1 61 JSR &61b1 ; first_stage_read_block ; wait_for_interrupt &6176 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6179 10 fb BPL &6176 ; wait_for_interrupt &617b ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &617e 29 70 AND #&70 &6180 f0 03 BEQ &6185 ; no_error &6182 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &6185 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address low &6188 85 03 STA &03 ; call_address_low ; wait_for_interrupt &618a 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &618d 10 fb BPL &618a ; wait_for_interrupt &618f ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6192 29 70 AND #&70 &6194 f0 03 BEQ &6199 ; no_error &6196 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &6199 ad 09 fe LDA &fe09 ; Cassette ACIA data register &619c 85 04 STA &04 ; call_address_high # Read byte for call address high &619e a9 2a LDA #&2a ; "*" &61a0 a4 05 LDY &05 ; block_screen_offset &61a2 99 50 7c STA &7c50,Y ; screen_memory + &50 &61a5 e6 05 INC &05 ; block_screen_offset &61a7 c0 4c CPY #&4c &61a9 d0 03 BNE &61ae ; to_call_address # Always branches &61ab 4c 3e 19 JMP &193e ; unused_call # Unused code ; to_call_address &61ae 6c 03 00 JMP (&0003) ; call_address ; first_stage_read_block ; wait_for_interrupt &61b1 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &61b4 10 fb BPL &61b1 ; wait_for_interrupt &61b6 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &61b9 29 70 AND #&70 &61bb f0 03 BEQ &61c0 ; no_error &61bd 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &61c0 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address low &61c3 85 00 STA &00 ; block_address_low ; wait_for_interrupt &61c5 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &61c8 10 fb BPL &61c5 ; wait_for_interrupt &61ca ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &61cd 29 70 AND #&70 &61cf f0 03 BEQ &61d4 ; no_error &61d1 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &61d4 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address high &61d7 85 01 STA &01 ; block_address_high ; wait_for_interrupt &61d9 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &61dc 10 fb BPL &61d9 ; wait_for_interrupt &61de ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &61e1 29 70 AND #&70 &61e3 f0 03 BEQ &61e8 ; no_error &61e5 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &61e8 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block length &61eb 85 02 STA &02 ; block_length &61ed a0 00 LDY #&00 ; first_stage_read_block_byte_loop ; wait_for_interrupt &61ef 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &61f2 10 fb BPL &61ef ; wait_for_interrupt &61f4 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &61f7 29 70 AND #&70 &61f9 f0 03 BEQ &61fe ; no_error &61fb 20 09 62 JSR &6209 ; first_stage_error # Never returns ; no_error &61fe ad 09 fe LDA &fe09 ; Cassette ACIA data register &6201 91 00 STA (&00),Y ; block_address &6203 c8 INY &6204 c4 02 CPY &02 ; block_length &6206 d0 e7 BNE &61ef ; first_stage_read_block_byte_loop &6208 60 RTS ; first_stage_error &6209 a0 74 LDY #&74 ; write_error_message_loop &620b b9 16 62 LDA &6216,Y ; first_stage_error_message &620e 99 20 7f STA &7f20,Y ; screen_memory + &320 &6211 88 DEY &6212 10 f7 BPL &620b ; write_error_message_loop ; infinite_loop &6214 30 fe BMI &6214 ; infinite_loop ; first_stage_error_message &6216 54 68 65 72 65 20 68 61 73 20 62 65 65 6e 20 61 ; "There has been a" &6226 20 6c 6f 61 64 69 6e 67 20 65 72 72 6f 72 20 77 ; " loading error w" &6236 68 69 63 68 20 6d 61 79 63 61 75 73 65 20 74 68 ; "hich maycause th" &6246 69 73 20 70 72 6f 67 72 61 6d 20 74 6f 20 77 6f ; "is program to wo" &6256 72 6b 20 69 6e 63 6f 72 72 65 63 74 6c 79 2e 20 ; "rk incorrectly. " &6266 50 72 65 73 73 20 27 42 52 45 41 4b 27 20 61 6e ; "Press 'BREAK' an" &6276 64 20 74 72 79 20 6c 6f 61 64 69 6e 67 20 61 67 ; "d try loading ag" &6286 61 69 6e 2e ; "ain." ; found_string &628a 46 6f 75 6e 64 20 20 20 20 ; "Found " ; searching_string &6293 53 65 61 72 63 68 69 6e 67 ; "Searching" ; unused &629c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62ac 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62bc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62cc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62dc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62ec 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &62fc 00 00 00 00 # First stage reads: # # &7000 - &70ff, calls &0050 ; call_read_next_block (first_stage_read_next_block) # &7100 - &717f, calls &7000 ; second_stage # &7000 - &717f is read from stream by first stage ; second_stage &7000 a9 95 LDA #&95 ; 1001 0101 # 1200 baud, odd parity, 2 stop bits, 8 bit word &7002 8d 08 fe STA &fe08 ; Cassette ACIA control register &7005 a9 11 LDA #&11 ; &7011 = second_stage_read_next_block &7007 85 51 STA &51 ; call_read_next_block + 1 &7009 a9 4c LDA #&4c ; JMP &700b 85 50 STA &50 ; call_read_next_block &700d a9 70 LDA #&70 &700f 85 52 STA &52 ; call_read_next_block + 2 ; second_stage_read_next_block &7011 20 4f 70 JSR &704f ; second_stage_read_block # May not return ; wait_for_interrupt &7014 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &7017 10 fb BPL &7014 ; wait_for_interrupt &7019 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &701c 29 70 AND #&70 &701e f0 03 BEQ &7023 ; no_error &7020 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &7023 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address low &7026 85 03 STA &03 ; call_address_low ; wait_for_interrupt &7028 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &702b 10 fb BPL &7028 ; wait_for_interrupt &702d ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &7030 29 70 AND #&70 &7032 f0 03 BEQ &7037 ; no_error &7034 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &7037 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address high &703a 85 04 STA &04 ; call_address_high &703c a9 2a LDA #&2a ; "*" &703e a4 05 LDY &05 ; block_screen_offset &7040 99 50 7c STA &7c50,Y ; screen_memory + &50 &7043 e6 05 INC &05 ; block_screen_offset &7045 c0 4c CPY #&4c &7047 d0 03 BNE &704c ; to_call_address # Always branches &7049 4c 3e 19 JMP &193e ; unused_call # Unused code ; to_call_address &704c 6c 03 00 JMP (&0003) ; call_address ; second_stage_read_block ; wait_for_interrupt &704f 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &7052 10 fb BPL &704f ; wait_for_interrupt &7054 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &7057 29 70 AND #&70 &7059 f0 03 BEQ &705e ; no_error &705b 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &705e ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address low &7061 85 00 STA &00 ; block_address_low ; wait_for_interrupt &7063 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &7066 10 fb BPL &7063 ; wait_for_interrupt &7068 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &706b 29 70 AND #&70 &706d f0 03 BEQ &7072 ; no_error &706f 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &7072 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block start address high &7075 85 01 STA &01 ; block_address_high ; wait_for_interrupt &7077 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &707a 10 fb BPL &7077 ; wait_for_interrupt &707c ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &707f 29 70 AND #&70 &7081 f0 03 BEQ &7086 ; no_error &7083 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &7086 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block length &7089 85 02 STA &02 ; block_length &708b a0 00 LDY #&00 ; second_stage_read_block_byte_loop ; wait_for_interrupt &708d 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &7090 10 fb BPL &708d ; wait_for_interrupt &7092 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &7095 29 70 AND #&70 &7097 f0 03 BEQ &709c ; no_error &7099 20 a7 70 JSR &70a7 ; second_stage_error # Never returns ; no_error &709c ad 09 fe LDA &fe09 ; Cassette ACIA data register &709f 91 00 STA (&00),Y ; block_address &70a1 c8 INY &70a2 c4 02 CPY &02 ; block_length &70a4 d0 e7 BNE &708d ; second_stage_read_block_byte_loop &70a6 60 RTS # Leaves to &6e00 after final second stage block ; second_stage_error &70a7 a0 74 LDY #&74 ; write_error_message_loop &70a9 b9 b4 70 LDA &70b4,Y ; second_stage_error_message &70ac 99 20 7f STA &7f20,Y ; screen_memory + &320 &70af 88 DEY &70b0 10 f7 BPL &70a9 ; write_error_message_loop ; infinite_loop &70b2 30 fe BMI &70b2 ; infinite_loop ; second_stage_error_message &70b4 54 68 65 72 65 20 68 61 73 20 62 65 65 6e 20 61 ; "There has been a" &70c4 20 6c 6f 61 64 69 6e 67 20 65 72 72 6f 72 20 77 ; " loading error w" &70d4 68 69 63 68 20 6d 61 79 63 61 75 73 65 20 74 68 ; "hich maycause th" &70e4 69 73 20 70 72 6f 67 72 61 6d 20 74 6f 20 77 6f ; "is program to wo" &70f4 72 6b 20 69 6e 63 6f 72 72 65 63 74 6c 79 2e 20 ; "rk incorrectly. " &7104 50 72 65 73 73 20 27 42 52 45 41 4b 27 20 61 6e ; "Press 'BREAK' an" &7114 64 20 74 72 79 20 6c 6f 61 64 69 6e 67 20 61 67 ; "d try loading ag" &7124 61 69 6e 2e ; "ain." ; unused # &7128 - &717f is a copy of &2128 - &217f &7128 12 a6 20 f0 02 09 80 0a 6e 1f 3f 2c 1f 3f 70 0c &7138 10 0a a2 03 bd 0b 3f f0 04 ca 10 f8 60 a9 01 9d &7148 0b 3f ad 02 3f 38 e9 02 9d 0f 3f ad 03 3f 18 69 &7158 05 9d 13 3f a9 00 9d 1b 3f a9 01 8d 4d 3f a9 32 &7168 8d 4e 3f a9 0d 8d 4f 3f a9 02 8d 50 3f 60 20 89 &7178 21 a2 03 bd 0b 3f f0 05 # Second stage reads: # # &1100 - &11ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1200 - &12ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1300 - &13ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1400 - &14ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1500 - &15ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1600 - &16ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &1700 - &17ff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &6e00 - &6eff, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &6f00 - &6f7f, calls &0050 ; call_read_next_block (second_stage_read_next_block) # &01fe - &01ff, overwrites stack to leave second_stage_read_block to &6e00 ; third_stage # &6e00 - &6e7f is read from stream by second stage ; third_stage &6e00 a9 91 LDA #&91 ; 1001 0001 # 1200 baud, even parity, 2 stop bits, 8 bit word &6e02 8d 08 fe STA &fe08 ; Cassette ACIA control register &6e05 a9 11 LDA #&11 ; &6e11 = third_stage_read_next_block &6e07 85 51 STA &51 ; call_read_next_block + 1 &6e09 a9 4c LDA #&4c ; JMP &6e0b 85 50 STA &50 ; call_read_next_block &6e0d a9 6e LDA #&6e &6e0f 85 52 STA &52 ; call_read_next_block + 2 ; third_stage_read_next_block &6e11 20 4f 6e JSR &6e4f ; third_stage_read_block # May not return ; wait_for_interrupt &6e14 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e17 10 fb BPL &6e14 ; wait_for_interrupt &6e19 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e1c 29 70 AND #&70 &6e1e f0 03 BEQ &6e23 ; no_error &6e20 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e23 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address low &6e26 85 03 STA &03 ; call_address_low ; wait_for_interrupt &6e28 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e2b 10 fb BPL &6e28 ; wait_for_interrupt &6e2d ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e30 29 70 AND #&70 &6e32 f0 03 BEQ &6e37 ; no_error &6e34 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e37 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for call address high &6e3a 85 04 STA &04 ; call_address_high &6e3c a9 2a LDA #&2a ; "*" &6e3e a4 05 LDY &05 ; block_screen_offset &6e40 99 50 7c STA &7c50,Y ; screen_memory + &50 &6e43 e6 05 INC &05 ; block_screen_offset &6e45 c0 4c CPY #&4c &6e47 d0 03 BNE &6e4c ; to_call_address # Always branches &6e49 4c 3e 19 JMP &193e ; unused_call # Unused code ; to_call_address &6e4c 6c 03 00 JMP (&0003) ; call_address ; third_stage_read_block ; wait_for_interrupt &6e4f 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e52 10 fb BPL &6e4f ; wait_for_interrupt &6e54 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e57 29 70 AND #&70 &6e59 f0 03 BEQ &6e5e ; no_error &6e5b 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e5e ad 09 fe LDA &fe09 ; Cassette ACIA data register &6e61 85 00 STA &00 ; block_address_low ; wait_for_interrupt &6e63 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e66 10 fb BPL &6e63 ; wait_for_interrupt &6e68 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e6b 29 70 AND #&70 &6e6d f0 03 BEQ &6e72 ; no_error &6e6f 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e72 ad 09 fe LDA &fe09 ; Cassette ACIA data register &6e75 85 01 STA &01 ; block_address_high ; wait_for_interrupt &6e77 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e7a 10 fb BPL &6e77 ; wait_for_interrupt &6e7c ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e7f 29 70 AND #&70 &6e81 f0 03 BEQ &6e86 ; no_error &6e83 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e86 ad 09 fe LDA &fe09 ; Cassette ACIA data register # Read byte for block length &6e89 85 02 STA &02 ; block_length &6e8b a0 00 LDY #&00 ; third_stage_read_block_byte_loop ; wait_for_interrupt &6e8d 2c 08 fe BIT &fe08 ; Cassette ACIA status register # Top bit set if interrupt generated &6e90 10 fb BPL &6e8d ; wait_for_interrupt &6e92 ad 08 fe LDA &fe08 ; Cassette ACIA status register # &70 clear if no error occurred &6e95 29 70 AND #&70 &6e97 f0 03 BEQ &6e9c ; no_error &6e99 20 a7 6e JSR &6ea7 ; third_stage_error # Never returns ; no_error &6e9c ad 09 fe LDA &fe09 ; Cassette ACIA data register &6e9f 91 00 STA (&00),Y ; block_address &6ea1 c8 INY &6ea2 c4 02 CPY &02 ; block_length &6ea4 d0 e7 BNE &6e8d ; third_stage_read_block_byte_loop &6ea6 60 RTS # Leaves to &3de8 after final third stage block ; third_stage_error &6ea7 a0 74 LDY #&74 ; write_error_message_loop &6ea9 b9 b4 6e LDA &6eb4,Y ; third_stage_error_message &6eac 99 20 7f STA &7f20,Y ; screen_memory + &320 &6eaf 88 DEY &6eb0 10 f7 BPL &6ea9 ; write_error_message_loop ; infinite_loop &6eb2 30 fe BMI &6eb2 ; infinite_loop ; third_stage_error_message &6eb4 54 68 65 72 65 20 68 61 73 20 62 65 65 6e 20 61 ; "There has been a" &6ec4 20 6c 6f 61 64 69 6e 67 20 65 72 72 6f 72 20 77 ; " loading error w" &6ed4 68 69 63 68 20 6d 61 79 63 61 75 73 65 20 74 68 ; "hich maycause th" &6ee4 69 73 20 70 72 6f 67 72 61 6d 20 74 6f 20 77 6f ; "is program to wo" &6ef4 72 6b 20 69 6e 63 6f 72 72 65 63 74 6c 79 2e 20 ; "rk incorrectly. " &6f04 50 72 65 73 73 20 27 42 52 45 41 4b 27 20 61 6e ; "Press 'BREAK' an" &6f14 64 20 74 72 79 20 6c 6f 61 64 69 6e 67 20 61 67 ; "d try loading ag" &6f24 61 69 6e 2e ; "ain." ; unused # &6f28 - &6f7f is a copy of &2a28 - &2a7f &6f28 8d 5c 3f a9 0f 8d 5d 3f 60 f8 8a 18 6d 58 3f 8d &6f38 58 3f 98 6d 59 3f 8d 59 3f 08 a9 00 6d 5a 3f 8d &6f48 5a 3f 28 d8 90 0f ad 57 3f d0 0a ee 57 3f e6 07 &6f58 ee 5f 3f e6 02 60 ad 08 3f 18 69 40 85 70 ad 09 &6f68 3f 69 01 10 02 e9 3f 85 71 a5 70 18 69 40 85 72 &6f78 a5 71 69 01 10 02 e9 3f # Third stage reads: # # &1800 - &18ff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1900 - &19ff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1a00 - &1aff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1b00 - &1bff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1c00 - &1cff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1d00 - &1dff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1e00 - &1eff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &1f00 - &1fff, calls &0050 ; call_read_next_block (third_stage_read_next_block) # &01fe - &01ff, overwrites stack to leave third_stage_read_block to &3de8 ; real_entry_point # &1100 - &1fff is read from stream by second and third stages ; set_video_register &1100 8e 00 fe STX &fe00 ; video register number &1103 8d 01 fe STA &fe01 ; video register value &1106 60 RTS ; initialise_interrupts &1107 78 SEI &1108 a9 33 LDA #&33 ; &1133 = irq1_handler &110a 8d 04 02 STA &0204 ; irq1_vector_low &110d a9 11 LDA #&11 &110f 8d 05 02 STA &0205 ; irq1_vector_high &1112 a9 7d LDA #&7d ; 0111 1101 # Disable all System VIA interrupts except CA1 (v-sync) &1114 8d 4e fe STA &fe4e ; System VIA interrupt enable register &1117 58 CLI &1118 a9 00 LDA #&00 # Set User VIA timers one and two to one-shot mode &111a 85 24 STA &24 ; unused # Unused variable &111c 8d 6b fe STA &fe6b ; User VIA auxiliary control register &111f a9 e0 LDA #&e0 ; 1110 0000 # Enable User VIA timer interrupts &1121 8d 6e fe STA &fe6e ; User VIA interrupt enable register &1124 a9 10 LDA #&10 &1126 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1129 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &112c 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &112f 8d 65 fe STA &fe65 ; User VIA timer 1 counter MSB &1132 60 RTS ; irq1_handler &1133 20 68 0e JSR &0e68 ; check_joystick &1136 a9 40 LDA #&40 &1138 2d 6d fe AND &fe6d ; User VIA interrupt flag register # &40 set if timer 1 interrupt &113b f0 0d BEQ &114a ; not_timer_1_interrupt &113d a9 ff LDA #&ff &113f 8d 64 fe STA &fe64 ; User VIA timer 1 counter LSB &1142 a5 08 LDA &08 ; nop_cascade_frequency # &ff during game, &27 in explosions and screens &1144 8d 65 fe STA &fe65 ; User VIA timer 1 counter MSB &1147 20 04 40 JSR &4004 ; nop_cascade ; not_timer_1_interrupt &114a a9 20 LDA #&20 &114c 2d 6d fe AND &fe6d ; User VIA interrupt flag register # &20 set if timer 2 interrupt &114f f0 0d BEQ &115e ; not_timer_2_interrupt &1151 a9 10 LDA #&10 &1153 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1156 a9 27 LDA #&27 &1158 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &115b 20 5c 24 JSR &245c ; update_sounds ; not_timer_2_interrupt &115e a9 02 LDA #&02 &1160 2d 4d fe AND &fe4d ; System VIA interrupt flag register # &02 set if v-sync interrupt &1163 f0 0d BEQ &1172 ; not_vsync_interrupt &1165 8d 4d fe STA &fe4d ; System VIA interrupt flag register # Clear interrupt &1168 ee 55 3f INC &3f55 ; vsync_counter &116b 10 05 BPL &1172 ; skip_wraparound &116d a9 00 LDA #&00 &116f 8d 55 3f STA &3f55 ; vsync_counter ; skip_wraparound ; not_vsync_interrupt &1172 a5 fc LDA &fc ; irq_accumulator &1174 40 RTI ; initialise_screen &1175 a9 04 LDA #&04 ; 0000 0100 # Change to MODE 5, no cursor &1177 8d 20 fe STA &fe20 ; video ULA control register &117a a0 12 LDY #&12 ; set_video_registers_loop &117c b9 ec 0e LDA &0eec,Y ; game_video_register_data &117f be ed 0e LDX &0eed,Y ; game_video_register_data + 1 &1182 20 00 11 JSR &1100 ; set_video_register &1185 88 DEY &1186 88 DEY &1187 10 f3 BPL &117c ; set_video_registers_loop &1189 a9 05 LDA #&05 # Set addressable latch B5 to 0 &118b 8d 40 fe STA &fe40 ; System VIA port B input/output register &118e a9 04 LDA #&04 # Set addressable latch B4 to 0, i.e. scroll from &4000 &1190 8d 40 fe STA &fe40 ; System VIA port B input/output register &1193 20 55 23 JSR &2355 ; set_palette # Set colour 0 to blue &1196 a9 80 LDA #&80 &1198 20 55 23 JSR &2355 ; set_palette # Set colour 2 to black &119b a9 a7 LDA #&a7 &119d 20 55 23 JSR &2355 ; set_palette # Set colour 3 to white &11a0 a9 21 LDA #&21 &11a2 20 55 23 JSR &2355 ; set_palette # Set colour 1 to red &11a5 a9 00 LDA #&00 &11a7 8d 08 3f STA &3f08 ; screen_start_address_low &11aa a9 40 LDA #&40 ; &4000 = screen_memory &11ac 8d 09 3f STA &3f09 ; screen_start_address_high ; update_screen &11af ad 08 3f LDA &3f08 ; screen_start_address_low &11b2 85 70 STA &70 ; crtc_start_address_low &11b4 ad 09 3f LDA &3f09 ; screen_start_address_high &11b7 4a LSR A &11b8 66 70 ROR &70 ; crtc_start_address_low &11ba 4a LSR A &11bb 66 70 ROR &70 ; crtc_start_address_low &11bd 4a LSR A &11be 66 70 ROR &70 ; crtc_start_address_low &11c0 a2 0c LDX #&0c ; R12: Displayed screen start address register (high) &11c2 20 00 11 JSR &1100 ; set_video_register &11c5 a5 70 LDA &70 ; crtc_start_address_low &11c7 a2 0d LDX #&0d ; R13: Displayed screen start address register (low) &11c9 20 00 11 JSR &1100 ; set_video_register &11cc a5 50 LDA &50 ; distance_before_foreground # Non-zero if before start of level &11ce d0 03 BNE &11d3 ; skip_increasing_distance_since_checkpoint &11d0 ee 0a 3f INC &3f0a ; distance_since_checkpoint ; skip_increasing_distance_since_checkpoint &11d3 ee 00 3f INC &3f00 ; unused_distance_low # Unused variable &11d6 d0 03 BNE &11db ; scroll_objects &11d8 ee 01 3f INC &3f01 ; unused_distance_high # Unused variable ; scroll_objects &11db a2 09 LDX #&09 ; scroll_objects_loop &11dd bd 00 3e LDA &3e00,X ; objects_z # Negative if no object in slot &11e0 30 10 BMI &11f2 ; consider_next_object &11e2 de 00 3e DEC &3e00,X ; objects_z # Move object towards player in z &11e5 10 0b BPL &11f2 ; consider_next_object &11e7 bd 10 3e LDA &3e10,X ; objects_width_remaining # Non-zero if object not fully plotted &11ea f0 06 BEQ &11f2 ; consider_next_object &11ec de 10 3e DEC &3e10,X ; objects_width_remaining &11ef fe 00 3e INC &3e00,X ; objects_z ; consider_next_object &11f2 ca DEX &11f3 10 e8 BPL &11dd ; scroll_objects_loop &11f5 60 RTS ; wipe_screen &11f6 a9 40 LDA #&40 ; &4000 = screen_memory &11f8 85 71 STA &71 ; wipe_address_high &11fa a9 00 LDA #&00 &11fc 85 70 STA &70 ; wipe_address_low ; wipe_screen_group_loop &11fe a9 f0 LDA #&f0 ; 3333 &1200 a0 03 LDY #&03 ; wipe_screen_byte_loop &1202 91 70 STA (&70),Y ; wipe_address # Wipe top four bytes of every column with colour 3 &1204 88 DEY &1205 10 fb BPL &1202 ; wipe_screen_byte_loop &1207 a5 70 LDA &70 ; wipe_address_low &1209 18 CLC &120a 69 08 ADC #&08 # Move to next column &120c 85 70 STA &70 ; wipe_address_low &120e a5 71 LDA &71 ; wipe_address_high &1210 69 00 ADC #&00 &1212 85 71 STA &71 ; wipe_address_high &1214 10 e8 BPL &11fe ; wipe_screen_group_loop &1216 a2 0e LDX #&0e # Switch off Shift Lock LED &1218 8e 40 fe STX &fe40 ; System VIA port B input/output register &121b e8 INX ; &0f # Switch off Caps Lock LED &121c 8e 40 fe STX &fe40 ; System VIA port B input/output register &121f 60 RTS ; move_memory &1220 a5 70 LDA &70 ; loader_keyboard_or_joystick &1222 85 21 STA &21 ; keyboard_or_joystick &1224 ad 04 02 LDA &0204 ; irq1_vector_low &1227 85 10 STA &10 ; previous_irq1_vector_low &1229 ad 05 02 LDA &0205 ; irq1_vector_high &122c 85 11 STA &11 ; previous_irq1_vector_high &122e a2 07 LDX #&07 &1230 a0 00 LDY #&00 &1232 84 70 STY &70 ; source_address_low &1234 84 72 STY &72 ; target_address_low &1236 a9 0a LDA #&0a &1238 85 73 STA &73 ; target_address_high &123a a9 5a LDA #&5a &123c 85 71 STA &71 ; source_address_high ; move_5a00_to_60ff_loop # Move &5a00 - &60ff to &0a00 - &10ff &123e b1 70 LDA (&70),Y ; source_address &1240 91 72 STA (&72),Y ; target_address &1242 88 DEY &1243 d0 f9 BNE &123e ; move_5a00_to_60ff_loop &1245 e6 71 INC &71 ; source_address_high &1247 e6 73 INC &73 ; target_address_high &1249 ca DEX &124a d0 f2 BNE &123e ; move_5a00_to_60ff_loop &124c ca DEX ; &ff &124d 86 12 STX &12 ; sound_enabled # Set to &ff to enable sound &124f 86 13 STX &13 ; initial_sound_enabled # Set to &ff to enable sound &1251 4c 3b 13 JMP &133b ; start_game ; silence_all_channels &1254 a2 03 LDX #&03 ; silence_all_channels_loop &1256 a9 00 LDA #&00 &1258 20 84 23 JSR &2384 ; set_sound_channel_volume &125b ca DEX &125c 10 f8 BPL &1256 ; silence_all_channels_loop &125e 60 RTS ; calculate_screen_address # Called with X = x, Y = y &125f a9 00 LDA #&00 &1261 85 70 STA &70 ; screen_address_low &1263 98 TYA &1264 49 ff EOR #&ff # y increases towards top of screen &1266 a8 TAY &1267 4a LSR A &1268 4a LSR A &1269 85 71 STA &71 ; screen_address_high &126b 4a LSR A &126c 66 70 ROR &70 ; screen_address_low &126e 4a LSR A &126f 66 70 ROR &70 ; screen_address_low &1271 18 CLC &1272 65 71 ADC &71 ; screen_address_high &1274 85 71 STA &71 ; screen_address_high &1276 8a TXA &1277 29 fc AND #&fc &1279 0a ASL A &127a 26 72 ROL &72 ; tmp &127c 18 CLC &127d 65 70 ADC &70 ; screen_address_low &127f 48 PHA ; screen_address_low &1280 a5 72 LDA &72 ; tmp &1282 29 01 AND #&01 &1284 65 71 ADC &71 ; screen_address_high &1286 85 71 STA &71 ; screen_address_high &1288 68 PLA ; screen_address_low &1289 18 CLC &128a 6d 08 3f ADC &3f08 ; screen_start_address_low &128d 85 70 STA &70 ; screen_address_low &128f a5 71 LDA &71 ; screen_address_high &1291 6d 09 3f ADC &3f09 ; screen_start_address_high &1294 10 02 BPL &1298 ; skip_wraparound &1296 e9 3f SBC #&3f &1298 85 71 STA &71 ; screen_address_high ; skip_wraparound &129a 98 TYA &129b 29 03 AND #&03 &129d 05 70 ORA &70 ; screen_address_low &129f 85 70 STA &70 ; screen_address_low &12a1 60 RTS ; check_for_keypress &12a2 08 PHP ; processor status &12a3 78 SEI &12a4 a9 03 LDA #&03 # Disable keyboard auto-scan &12a6 8d 40 fe STA &fe40 ; System VIA port B input/output register &12a9 a9 7f LDA #&7f # Set top bit as input, low seven bits as output &12ab 8d 43 fe STA &fe43 ; System VIA data direction register A &12ae 8e 41 fe STX &fe41 ; System VIA output register A &12b1 ad 41 fe LDA &fe41 ; System VIA output register A &12b4 29 80 AND #&80 &12b6 48 PHA ; key pressed &12b7 a9 ff LDA #&ff # Set all bits to output &12b9 8d 43 fe STA &fe43 ; System VIA data direction register A &12bc a9 0b LDA #&0b # Enable keyboard auto-scan &12be 8d 40 fe STA &fe40 ; System VIA port B input/output register &12c1 68 PLA ; key pressed &12c2 28 PLP ; processor status &12c3 49 00 EOR #&00 &12c5 60 RTS # Leave with not equal if key pressed ; rnd &12c6 98 TYA &12c7 48 PHA ; tmp_y &12c8 a0 08 LDY #&08 ; shuffle_rnd_state_loop &12ca a5 8b LDA &8b ; rnd_state &12cc 29 48 AND #&48 &12ce 69 38 ADC #&38 &12d0 0a ASL A &12d1 0a ASL A &12d2 26 8d ROL &8d ; rnd_state + 2 &12d4 26 8c ROL &8c ; rnd_state + 1 &12d6 26 8b ROL &8b ; rnd_state &12d8 88 DEY &12d9 d0 ef BNE &12ca ; shuffle_rnd_state_loop &12db 68 PLA ; tmp_y &12dc a8 TAY &12dd a5 8b LDA &8b ; rnd_state &12df 60 RTS ; wait_for_vsync &12e0 ad 55 3f LDA &3f55 ; vsync_counter &12e3 cd 56 3f CMP &3f56 ; previous_vsync_counter &12e6 f0 f8 BEQ &12e0 ; wait_for_vsync &12e8 8d 56 3f STA &3f56 ; previous_vsync_counter &12eb 60 RTS ; initialise_level &12ec a2 40 LDX #&40 &12ee a9 00 LDA #&00 ; wipe_variables_loop &12f0 95 40 STA &40,X # Wipe &0041 - &0080 &12f2 ca DEX &12f3 d0 fb BNE &12f0 ; wipe_variables_loop ; wipe_data_loop &12f5 9d 00 09 STA &0900,X # Wipe &0900 - &09ff &12f8 9d 00 07 STA &0700,X # Wipe &0700 - &07ff &12fb 9d 00 3e STA &3e00,X # Wipe &3e00 - &3fff &12fe 9d 00 3f STA &3f00,X &1301 ca DEX &1302 d0 f1 BNE &12f5 ; wipe_data_loop &1304 a9 ff LDA #&ff &1306 a2 0f LDX #&0f ; wipe_objects_loop &1308 9d 00 3e STA &3e00,X ; objects_z # Set to &ff to indicate no object in slot &130b 9d 90 3e STA &3e90,X ; objects_rocket_ttl # Set to &ff to indicate no rocket in slot &130e ca DEX &130f 10 f7 BPL &1308 ; wipe_objects_loop &1311 20 f6 11 JSR &11f6 ; wipe_screen &1314 20 75 11 JSR &1175 ; initialise_screen &1317 a9 02 LDA #&02 &1319 85 89 STA &89 ; game_speed # Constant &131b a9 40 LDA #&40 &131d 85 50 STA &50 ; distance_before_foreground &131f a9 28 LDA #&28 &1321 85 51 STA &51 ; distance_before_background &1323 a9 00 LDA #&00 &1325 85 5e STA &5e ; distance_before_large_wall &1327 a9 3c LDA #&3c &1329 8d 6d 3f STA &3f6d ; player_fuel &132c a9 03 LDA #&03 &132e 8d 6f 3f STA &3f6f ; player_fuel_drain_maximum_cooldown &1331 8d 6e 3f STA &3f6e ; player_fuel_drain_cooldown &1334 a9 ff LDA #&ff &1336 85 08 STA &08 ; nop_cascade_frequency # Call NOP cascade less frequently &1338 4c 54 12 JMP &1254 ; silence_all_channels ; start_game &133b 20 07 11 JSR &1107 ; initialise_interrupts &133e a2 0f LDX #&0f &1340 a9 00 LDA #&00 ; wipe_0000_to_000f_loop &1342 95 00 STA &00,X # Wipe &0000 - &000f &1344 ca DEX &1345 10 fb BPL &1342 ; wipe_0000_to_000f_loop &1347 a2 03 LDX #&03 &1349 86 02 STX &02 ; initial_player_lives # Player starts with three lives &134b e8 INX &134c 86 09 STX &09 ; initial_boss_energy &134e a9 0a LDA #&0a ; &0a00 = level_data # Start on level one &1350 85 14 STA &14 ; level_data_base_address_high ; start_level &1352 20 ec 12 JSR &12ec ; initialise_level &1355 a5 00 LDA &00 ; initial_level_data_address_low &1357 85 85 STA &85 ; level_data_address_low &1359 a5 01 LDA &01 ; initial_level_data_address_high &135b 85 86 STA &86 ; level_data_address_high &135d a5 02 LDA &02 ; initial_player_lives &135f 8d 5f 3f STA &3f5f ; player_lives &1362 a5 06 LDA &06 ; initial_reached_checkpoint # Zero if no checkpoint has been reached &1364 8d 75 3f STA &3f75 ; reached_checkpoint &1367 f0 09 BEQ &1372 ; skip_scrolling_to_checkpoint &1369 a9 00 LDA #&00 &136b 85 50 STA &50 ; distance_before_foreground &136d 85 51 STA &51 ; distance_before_background &136f 20 65 14 JSR &1465 ; scroll_to_checkpoint ; skip_scrolling_to_checkpoint &1372 a2 02 LDX #&02 ; restore_score_loop &1374 b5 03 LDA &03,X ; initial_score &1376 9d 58 3f STA &3f58,X ; score &1379 ca DEX &137a 10 f8 BPL &1374 ; restore_score_loop &137c a5 07 LDA &07 ; initial_suppress_extra_life &137e 8d 57 3f STA &3f57 ; suppress_extra_life &1381 a5 09 LDA &09 ; initial_boss_energy &1383 8d 81 3f STA &3f81 ; boss_energy &1386 a5 13 LDA &13 ; initial_sound_enabled &1388 85 12 STA &12 ; sound_enabled &138a a5 0a LDA &0a ; initial_difficulty &138c 8d 8a 3f STA &3f8a ; difficulty &138f ce 1f 3f DEC &3f1f ; suppress_firing_roller ; main_game_loop &1392 20 b1 14 JSR &14b1 ; prepare_foreground &1395 20 16 15 JSR &1516 ; prepare_background &1398 a5 50 LDA &50 ; distance_before_foreground &139a d0 03 BNE &139f ; skip_updating_world &139c 20 81 1b JSR &1b81 ; update_world ; skip_updating_world &139f 20 e0 12 JSR &12e0 ; wait_for_vsync &13a2 20 cb 16 JSR &16cb ; consider_updating_foreground_part_of_large_wall &13a5 20 f3 17 JSR &17f3 ; consider_updating_background_part_of_large_wall &13a8 20 1f 29 JSR &291f ; consider_updating_electric_fence &13ab 20 e0 12 JSR &12e0 ; wait_for_vsync &13ae a9 00 LDA #&00 &13b0 8d 55 3f STA &3f55 ; vsync_counter &13b3 a2 43 LDX #&43 ; F &13b5 20 a2 12 JSR &12a2 ; check_for_keypress &13b8 f0 0e BEQ &13c8 ; f_not_pressed &13ba 20 49 14 JSR &1449 ; mute_sound # Mute sound when game paused ; wait_for_r_to_be_pressed &13bd a2 33 LDX #&33 ; R &13bf 20 a2 12 JSR &12a2 ; check_for_keypress &13c2 f0 f9 BEQ &13bd ; wait_for_r_to_be_pressed &13c4 a5 13 LDA &13 ; initial_sound_enabled # Unmute sound when game unpaused &13c6 85 12 STA &12 ; sound_enabled ; f_not_pressed &13c8 a0 0a LDY #&0a &13ca a2 00 LDX #&00 ; delay_loop &13cc ca DEX &13cd d0 fd BNE &13cc ; delay_loop &13cf 88 DEY &13d0 d0 fa BNE &13cc ; delay_loop &13d2 20 88 29 JSR &2988 ; to_update_score_and_lives &13d5 a2 10 LDX #&10 ; Q &13d7 20 a2 12 JSR &12a2 ; check_for_keypress &13da f0 07 BEQ &13e3 ; q_not_pressed &13dc 20 49 14 JSR &1449 ; mute_sound &13df a9 00 LDA #&00 &13e1 85 13 STA &13 ; initial_sound_enabled # Set to zero to disable sound ; q_not_pressed &13e3 a2 51 LDX #&51 ; S &13e5 20 a2 12 JSR &12a2 ; check_for_keypress &13e8 f0 06 BEQ &13f0 ; s_not_pressed &13ea a9 ff LDA #&ff &13ec 85 12 STA &12 ; sound_enabled &13ee 85 13 STA &13 ; initial_sound_enabled # Set to &ff to enable sound ; s_not_pressed &13f0 20 d4 1c JSR &1cd4 ; consider_moving_player &13f3 20 51 14 JSR &1451 ; scroll_screen_start_address &13f6 20 b8 15 JSR &15b8 ; plot_background &13f9 20 af 11 JSR &11af ; update_screen &13fc 20 67 15 JSR &1567 ; plot_foreground &13ff 20 82 29 JSR &2982 ; to_update_fuel &1402 20 5a 1d JSR &1d5a ; update_player &1405 20 f7 1f JSR &1ff7 ; check_for_player_collision_with_objects &1408 ad 80 3f LDA &3f80 ; level_completed # Non-zero if boss has been destroyed &140b f0 03 BEQ &1410 ; game_not_completed &140d 4c 9d 29 JMP &299d ; to_completion_screen ; game_not_completed ; wait_for_vsyncs &1410 ad 55 3f LDA &3f55 ; vsync_counter &1413 c5 89 CMP &89 ; game_speed # Constant; always two &1415 90 f9 BCC &1410 ; wait_for_vsyncs &1417 8d 56 3f STA &3f56 ; previous_vsync_counter &141a a5 50 LDA &50 ; distance_before_foreground &141c 38 SEC &141d e9 02 SBC #&02 &141f 30 02 BMI &1423 ; skip_setting_distance_before_foreground &1421 85 50 STA &50 ; distance_before_foreground ; skip_setting_distance_before_foreground &1423 a5 51 LDA &51 ; distance_before_background &1425 38 SEC &1426 e9 02 SBC #&02 &1428 30 02 BMI &142c ; skip_setting_distance_before_background &142a 85 51 STA &51 ; distance_before_background ; skip_setting_distance_before_background &142c a2 70 LDX #&70 ; ESCAPE &142e 20 a2 12 JSR &12a2 ; check_for_keypress &1431 d0 03 BNE &1436 ; escape_pressed ; to_main_game_loop &1433 4c 92 13 JMP &1392 ; main_game_loop ; escape_pressed &1436 a2 62 LDX #&62 ; SPACE &1438 20 a2 12 JSR &12a2 ; check_for_keypress &143b d0 f6 BNE &1433 ; to_main_game_loop &143d 20 49 14 JSR &1449 ; mute_sound &1440 8d 59 3f STA &3f59 ; score + 1 &1443 8d 5a 3f STA &3f5a ; score + 2 &1446 4c a0 29 JMP &29a0 ; to_high_score_screen_then_wait_for_space_or_fire ; mute_sound &1449 20 54 12 JSR &1254 ; silence_all_channels &144c a9 00 LDA #&00 &144e 85 12 STA &12 ; sound_enabled &1450 60 RTS ; scroll_screen_start_address &1451 ad 08 3f LDA &3f08 ; screen_start_address_low &1454 38 SEC &1455 e9 38 SBC #&38 # Move right one column, up one group &1457 8d 08 3f STA &3f08 ; screen_start_address_low &145a ad 09 3f LDA &3f09 ; screen_start_address_high &145d e9 01 SBC #&01 &145f 09 40 ORA #&40 # Keep within screen memory &1461 8d 09 3f STA &3f09 ; screen_start_address_high &1464 60 RTS ; scroll_to_checkpoint &1465 a9 00 LDA #&00 # Set colour 0 to black &1467 20 55 23 JSR &2355 ; set_palette &146a a9 80 LDA #&80 # Set colour 2 to black &146c 20 55 23 JSR &2355 ; set_palette &146f a9 a0 LDA #&a0 # Set colour 3 to black &1471 20 55 23 JSR &2355 ; set_palette &1474 a9 20 LDA #&20 # Set colour 1 to black &1476 20 55 23 JSR &2355 ; set_palette &1479 a9 32 LDA #&32 ; scroll_to_checkpoint_loop &147b 48 PHA ; count &147c 20 16 15 JSR &1516 ; prepare_background &147f 20 b1 14 JSR &14b1 ; prepare_foreground &1482 20 51 14 JSR &1451 ; scroll_screen_start_address &1485 20 b8 15 JSR &15b8 ; plot_background &1488 20 67 15 JSR &1567 ; plot_foreground &148b 20 af 11 JSR &11af ; update_screen &148e 68 PLA ; count &148f aa TAX &1490 ca DEX &1491 8a TXA &1492 d0 e7 BNE &147b ; scroll_to_checkpoint_loop &1494 8d 0a 3f STA &3f0a ; distance_since_checkpoint &1497 20 e0 12 JSR &12e0 ; wait_for_vsync &149a 20 e0 12 JSR &12e0 ; wait_for_vsync &149d a9 04 LDA #&04 # Set colour 0 to blue &149f 20 55 23 JSR &2355 ; set_palette &14a2 a9 80 LDA #&80 # Set colour 2 to black &14a4 20 55 23 JSR &2355 ; set_palette &14a7 a9 a7 LDA #&a7 # Set colour 3 to white &14a9 20 55 23 JSR &2355 ; set_palette &14ac a9 21 LDA #&21 # Set colour 1 to red &14ae 4c 55 23 JMP &2355 ; set_palette ; prepare_foreground &14b1 a9 00 LDA #&00 &14b3 85 70 STA &70 ; foreground_buffer_address_low &14b5 a9 04 LDA #&04 ; &0400 = foreground_buffer &14b7 85 71 STA &71 ; foreground_buffer_address_high &14b9 a2 40 LDX #&40 ; prepare_foreground_group_loop &14bb a0 03 LDY #&03 ; prepare_foreground_row_loop &14bd a9 f0 LDA #&f0 ; 2222 &14bf e0 1e CPX #&1e # If the row is below the bottom of the ground, &14c1 90 2f BCC &14f2 ; set_foreground_buffer &14c3 e4 50 CPX &50 ; distance_before_foreground # or the row is before the start of the ground, &14c5 90 2b BCC &14f2 ; set_foreground_buffer # set it to black &14c7 08 PHP ; is start &14c8 a9 00 LDA #&00 ; 0000 # Otherwise, use blue for ground &14ca 28 PLP ; is start &14cb d0 1a BNE &14e7 ; consider_right_edge_of_ground &14cd a5 50 LDA &50 ; distance_before_foreground &14cf c9 1e CMP #&1e &14d1 f0 0a BEQ &14dd ; bottom_right_corner_of_ground ; start_of_ground &14d3 a9 f0 LDA #&f0 ; 2222 &14d5 39 06 15 AND &1506,Y ; top_left_to_bottom_right_edge # Apply diagonal edge \ to start of ground &14d8 49 f0 EOR #&f0 ; 2222 &14da 4c f2 14 JMP &14f2 ; set_foreground_buffer ; bottom_right_corner_of_ground &14dd a9 f0 LDA #&f0 &14df 39 0a 15 AND &150a,Y ; top_corner # Apply corner v to start of ground &14e2 49 f0 EOR #&f0 &14e4 4c f2 14 JMP &14f2 ; set_foreground_buffer ; consider_right_edge_of_ground &14e7 e0 1e CPX #&1e &14e9 d0 07 BNE &14f2 ; set_foreground_buffer ; right_edge_of_ground &14eb a9 f0 LDA #&f0 &14ed 39 02 15 AND &1502,Y ; top_right_to_bottom_left_edge # Apply diagonal edge / to right of ground &14f0 49 f0 EOR #&f0 ; set_foreground_buffer &14f2 91 70 STA (&70),Y ; foreground_buffer_address &14f4 88 DEY &14f5 10 c6 BPL &14bd ; prepare_foreground_row_loop &14f7 a5 70 LDA &70 ; foreground_buffer_address_low &14f9 18 CLC &14fa 69 04 ADC #&04 &14fc 85 70 STA &70 ; foreground_buffer_address_low &14fe ca DEX &14ff d0 ba BNE &14bb ; prepare_foreground_group_loop &1501 60 RTS ; top_right_to_bottom_left_edge &1502 ff ee cc 88 ; 3333 3330 3300 3000 ; 3 = white, 0 = blue ; top_left_to_bottom_right_edge &1506 ff 77 33 11 ; 3333 0333 0033 0003 ; top_corner &150a ff 66 00 00 ; 3333 0330 0000 0000 ; inverse_top_right_to_bottom_left_edge &150e 11 33 77 ff ; 0003 0033 0333 3333 ; right_corner &1512 11 33 33 11 ; 0003 0033 0033 0003 ; prepare_background &1516 a9 00 LDA #&00 &1518 85 70 STA &70 ; background_buffer_address_low &151a a9 05 LDA #&05 &151c 85 71 STA &71 ; background_buffer_address_high &151e a2 27 LDX #&27 ; prepare_background_group_loop &1520 a0 03 LDY #&03 ; prepare_background_row_loop &1522 a9 f0 LDA #&f0 ; 2222 &1524 e0 14 CPX #&14 &1526 90 2f BCC &1557 ; set_background_buffer &1528 e4 51 CPX &51 ; distance_before_background # Use black if before background &152a 90 2b BCC &1557 ; set_background_buffer &152c 08 PHP ; is start &152d a9 00 LDA #&00 ; 0000 # Otherwise use blue for background part of ground &152f 28 PLP ; is start &1530 d0 1a BNE &154c ; consider_left_edge_of_ground &1532 a5 51 LDA &51 ; distance_before_background &1534 c9 14 CMP #&14 &1536 f0 0a BEQ &1542 ; top_left_corner_of_ground ; start_of_ground &1538 a9 f0 LDA #&f0 ; 2222 &153a 39 06 15 AND &1506,Y ; top_left_to_bottom_right_edge # Apply diagonal edge \ to start of ground &153d 49 f0 EOR #&f0 ; 2222 &153f 4c 57 15 JMP &1557 ; set_background_buffer ; top_left_corner_of_ground &1542 a9 f0 LDA #&f0 ; 2222 &1544 39 12 15 AND &1512,Y ; right_corner # Apply corner < to start of ground &1547 49 f0 EOR #&f0 ; 2222 &1549 4c 57 15 JMP &1557 ; set_background_buffer ; consider_left_edge_of_ground &154c e0 14 CPX #&14 &154e d0 07 BNE &1557 ; set_background_buffer ; left_edge_of_ground &1550 a9 f0 LDA #&f0 ; 2222 &1552 39 0e 15 AND &150e,Y ; inverse_top_right_to_bottom_left_edge # Apply diagonal edge / to left of ground &1555 49 f0 EOR #&f0 ; 2222 ; set_background_buffer &1557 91 70 STA (&70),Y ; background_buffer_address &1559 88 DEY &155a 10 c6 BPL &1522 ; prepare_background_row_loop &155c a5 70 LDA &70 ; background_buffer_address_low &155e 18 CLC &155f 69 04 ADC #&04 &1561 85 70 STA &70 ; background_buffer_address_low &1563 ca DEX &1564 d0 ba BNE &1520 ; prepare_background_group_loop &1566 60 RTS ; plot_foreground # Plot a vertical strip from top right of screen &1567 ad 08 3f LDA &3f08 ; screen_start_address_low &156a 18 CLC &156b 69 38 ADC #&38 ; + &138 # Last column of topmost group &156d 85 70 STA &70 ; screen_address_low &156f ad 09 3f LDA &3f09 ; screen_start_address_high &1572 69 01 ADC #&01 &1574 10 02 BPL &1578 ; skip_wraparound &1576 e9 3f SBC #&3f ; skip_wraparound &1578 85 71 STA &71 ; screen_address_high &157a a2 00 LDX #&00 &157c a0 00 LDY #&00 ; plot_foreground_loop &157e bd 00 04 LDA &0400,X ; foreground_buffer &1581 91 70 STA (&70),Y ; screen_address &1583 c8 INY # Move down a row &1584 c0 04 CPY #&04 &1586 d0 13 BNE &159b ; not_group &1588 a0 00 LDY #&00 &158a a5 70 LDA &70 ; screen_address_low &158c 18 CLC &158d 69 40 ADC #&40 # Move down a group &158f 85 70 STA &70 ; screen_address_low &1591 a5 71 LDA &71 ; screen_address_high &1593 69 01 ADC #&01 &1595 10 02 BPL &1599 ; skip_wraparound &1597 e9 3f SBC #&3f ; skip_wraparound &1599 85 71 STA &71 ; screen_address_high ; not_group &159b e8 INX &159c e0 c8 CPX #&c8 &159e d0 de BNE &157e ; plot_foreground_loop ; leave &15a0 60 RTS ; move_along_background_edge &15a1 c8 INY # Move down a row &15a2 c0 04 CPY #&04 &15a4 d0 fa BNE &15a0 ; leave &15a6 a0 00 LDY #&00 &15a8 a5 70 LDA &70 ; screen_address_low &15aa 38 SEC &15ab e9 08 SBC #&08 # Move right a column &15ad 85 70 STA &70 ; screen_address_low &15af a5 71 LDA &71 ; screen_address_high &15b1 e9 00 SBC #&00 &15b3 09 40 ORA #&40 &15b5 85 71 STA &71 ; screen_address_high &15b7 60 RTS ; plot_background # Plot a horizontal strip from top right of screen &15b8 ad 08 3f LDA &3f08 ; screen_start_address_low &15bb 18 CLC &15bc 69 30 ADC #&30 ; + &130 # Second to last column of topmost group &15be 85 70 STA &70 ; screen_address_low &15c0 ad 09 3f LDA &3f09 ; screen_start_address_high &15c3 69 01 ADC #&01 &15c5 10 02 BPL &15c9 ; skip_wraparound &15c7 e9 3f SBC #&3f ; skip_wraparound &15c9 85 71 STA &71 ; screen_address_high &15cb a2 00 LDX #&00 &15cd a0 00 LDY #&00 ; plot_background_loop &15cf bd 00 05 LDA &0500,X ; background_buffer &15d2 91 70 STA (&70),Y ; screen_address &15d4 20 a1 15 JSR &15a1 ; move_along_background_edge # Move down through rows, then right through columns &15d7 e8 INX &15d8 e0 9c CPX #&9c &15da d0 f3 BNE &15cf ; plot_background_loop &15dc 60 RTS ; add_column_of_new_object_to_foreground_buffer &15dd a0 00 LDY #&00 ; add_column_of_new_object_to_foreground_buffer_row_loop &15df 84 72 STY &72 ; offset &15e1 a5 77 LDA &77 ; y &15e3 a0 ff LDY #&ff &15e5 c9 89 CMP #&89 # Does the object need to be clipped bottom right? &15e7 90 0c BCC &15f5 ; skip_applying_mask &15e9 c9 8c CMP #&8c &15eb 90 01 BCC &15ee ; apply_mask &15ed 60 RTS ; apply_mask &15ee 29 03 AND #&03 &15f0 a8 TAY &15f1 b9 02 15 LDA &1502,Y ; top_right_to_bottom_left_edge &15f4 a8 TAY ; skip_applying_mask &15f5 84 78 STY &78 ; foreground_mask &15f7 a0 00 LDY #&00 &15f9 b1 73 LDA (&73),Y ; object_sprite_address &15fb 25 78 AND &78 ; foreground_mask &15fd 85 76 STA &76 ; pixel_value &15ff 84 75 STY &75 ; mask &1601 a0 04 LDY #&04 ; add_column_of_new_object_to_foreground_buffer_pixel_loop &1603 18 CLC &1604 2c 0d 16 BIT &160d ; #&88 &1607 d0 01 BNE &160a ; pixel_not_colour_0 &1609 38 SEC # Set bit of mask if pixel is colour 0 ; pixel_not_colour_0 &160a 26 75 ROL &75 ; mask &160c 0a ASL A &160d 88 DEY &160e d0 f3 BNE &1603 ; add_column_of_new_object_to_foreground_buffer_pixel_loop &1610 a5 75 LDA &75 ; mask &1612 0a ASL A &1613 0a ASL A &1614 0a ASL A &1615 0a ASL A &1616 05 75 ORA &75 ; mask # Convert mask to colour 3 &1618 85 75 STA &75 ; mask &161a a4 72 LDY &72 ; offset # Always zero &161c b1 70 LDA (&70),Y ; foreground_buffer_address &161e 25 75 AND &75 ; mask &1620 05 76 ORA &76 ; pixel_value &1622 91 70 STA (&70),Y ; foreground_buffer_address &1624 e6 73 INC &73 ; object_sprite_address_low &1626 d0 02 BNE &162a ; skip_page &1628 e6 74 INC &74 ; object_sprite_address_high ; skip_page &162a c8 INY &162b e6 77 INC &77 ; y &162d ca DEX &162e d0 af BNE &15df ; add_column_of_new_object_to_foreground_buffer_row_loop &1630 60 RTS ; start_adding_wall_to_foreground_buffer &1631 95 54 STA &54,X ; foreground_walls_length &1633 94 53 STY &53,X ; foreground_walls_foreground_y &1635 a9 04 LDA #&04 ; 3 + 1 # If carry clear, start from middle of wall &1637 90 02 BCC &163b ; set_walls_width_remaining &1639 a9 07 LDA #&07 ; 6 + 1 # If carry set, start from left of wall ; set_walls_width_remaining &163b 95 52 STA &52,X ; foreground_walls_width_remaining ; continue_adding_wall_to_foreground_buffer &163d b5 53 LDA &53,X ; foreground_walls_foreground_y &163f 38 SEC &1640 e9 20 SBC #&20 &1642 85 70 STA &70 ; foreground_buffer_address_low # Calculate offset into foreground buffer &1644 85 77 STA &77 ; y &1646 a9 04 LDA #&04 ; &0400 = foreground_buffer &1648 85 71 STA &71 ; foreground_buffer_address_high &164a b4 52 LDY &52,X ; foreground_walls_width_remaining &164c 88 DEY &164d 30 12 BMI &1661 ; leave # Leave if end of wall &164f 94 52 STY &52,X ; foreground_walls_width_remaining &1651 b5 53 LDA &53,X ; foreground_walls_foreground_y &1653 18 CLC &1654 79 af 16 ADC &16af,Y ; wall_column_y_deltas &1657 95 53 STA &53,X ; foreground_walls_foreground_y &1659 c9 b4 CMP #&b4 &165b 90 05 BCC &1662 ; is_still_on_screen # Has the wall gone beyond the bottom of the screen? &165d a9 00 LDA #&00 &165f 95 52 STA &52,X ; foreground_walls_width_remaining # If so, set to zero to stop adding wall ; leave &1661 60 RTS ; is_still_on_screen &1662 8a TXA &1663 48 PHA ; wall_slot &1664 b9 c4 16 LDA &16c4,Y ; wall_sprite_heights &1667 aa TAX ; wall_sprite_height &1668 b9 b6 16 LDA &16b6,Y ; wall_sprite_addresses_low &166b 85 73 STA &73 ; object_sprite_address_low &166d b9 bd 16 LDA &16bd,Y ; wall_sprite_addresses_high &1670 85 74 STA &74 ; object_sprite_address_high &1672 a5 70 LDA &70 ; foreground_buffer_address_low &1674 c9 e0 CMP #&e0 # Does the wall go above the top of the foreground? &1676 90 21 BCC &1699 ; skip_clipping_wall &1678 8a TXA ; wall_sprite_height &1679 18 CLC &167a 65 70 ADC &70 ; foreground_buffer_address_low &167c aa TAX &167d 10 02 BPL &1681 ; bottom_of_wall_is_in_foreground # Is the bottom of the wall in the foreground? ; leave_after_pla &167f 68 PLA ; wall_slot # If not, don't plot wall &1680 60 RTS ; bottom_of_wall_is_in_foreground &1681 f0 fc BEQ &167f ; leave_after_pla &1683 a5 70 LDA &70 ; foreground_buffer_address_low # Calculate start of clipped sprite &1685 49 ff EOR #&ff &1687 18 CLC &1688 69 01 ADC #&01 &168a 18 CLC &168b 65 73 ADC &73 ; object_sprite_address_low &168d 85 73 STA &73 ; object_sprite_address_low &168f 90 02 BCC &1693 ; skip_page &1691 e6 74 INC &74 ; object_sprite_address_high ; skip_page &1693 a9 00 LDA #&00 &1695 85 70 STA &70 ; foreground_buffer_address_low # Set to zero to start plotting at top of foreground &1697 85 77 STA &77 ; y ; skip_clipping_wall &1699 20 dd 15 JSR &15dd ; add_column_of_new_object_to_foreground_buffer &169c 68 PLA ; wall_slot &169d aa TAX &169e b5 52 LDA &52,X ; foreground_walls_width_remaining &16a0 c9 02 CMP #&02 &16a2 d0 0a BNE &16ae ; leave &16a4 b5 54 LDA &54,X ; foreground_walls_length &16a6 f0 06 BEQ &16ae ; leave &16a8 d6 54 DEC &54,X ; foreground_walls_length &16aa a9 04 LDA #&04 &16ac 95 52 STA &52,X ; foreground_walls_width_remaining # Repeat brickwork in middle of wall ; leave &16ae 60 RTS ; wall_column_y_deltas ; 0 1 2 3 4 5 6 ; r2 r1 m1 m2 m1 l2 l1 &16af 00 08 08 08 08 08 03 ; wall_sprite_addresses_low ; 0 1 2 3 4 5 6 ; r2 r1 m1 m2 m1 l2 l1 &16b6 87 6b 33 4f 33 17 00 ; wall_sprite_addresses_high ; 0 1 2 3 4 5 6 ; r2 r1 m1 m2 m1 l2 l1 &16bd 30 30 30 30 30 30 30 ; wall_sprite_heights ; 0 1 2 3 4 5 6 ; r2 r1 m1 m2 m1 l2 l1 &16c4 17 1c 1c 1c 1c 1c 17 ; consider_updating_foreground_part_of_large_wall &16cb a5 5e LDA &5e ; distance_before_large_wall &16cd d0 0a BNE &16d9 ; skip_resetting_distance_before_large_wall &16cf ad 68 09 LDA &0968 ; large_wall_background_parts_data_address_low &16d2 d0 01 BNE &16d5 ; reset_distance_before_large_wall &16d4 60 RTS ; reset_distance_before_large_wall &16d5 a9 25 LDA #&25 &16d7 85 5e STA &5e ; distance_before_large_wall &16d9 c6 5e DEC &5e ; distance_before_large_wall ; skip_resetting_distance_before_large_wall &16db a5 5e LDA &5e ; distance_before_large_wall &16dd c9 1e CMP #&1e &16df 90 01 BCC &16e2 ; update_foreground_part_of_large_wall &16e1 60 RTS ; update_foreground_part_of_large_wall &16e2 ac 68 09 LDY &0968 ; large_wall_background_parts_data_address_low &16e5 a2 00 LDX #&00 # Start with part 0 if electric wall &16e7 c0 b0 CPY #&b0 ; &38b0 = electric_wall_background_parts_data &16e9 f0 02 BEQ &16ed ; set_wall_part &16eb a2 04 LDX #&04 # Start with part 4 if large wall ; set_wall_part &16ed 86 79 STX &79 ; wall_part &16ef dd 61 17 CMP &1761,X ; large_wall_foreground_parts_distance &16f2 d0 0b BNE &16ff ; consider_adding_second_part_of_large_wall ; add_first_part_of_large_wall # Add bottom row &16f4 a9 09 LDA #&09 # Length of row &16f6 bc 69 17 LDY &1769,X ; large_wall_foreground_parts_foreground_y &16f9 a2 00 LDX #&00 # Use first wall slot &16fb 18 CLC # Clear carry to start from middle of wall &16fc 4c 31 16 JMP &1631 ; start_adding_wall_to_foreground_buffer ; consider_adding_second_part_of_large_wall # This is the second from bottom row &16ff a2 00 LDX #&00 # Use first wall slot &1701 20 3d 16 JSR &163d ; continue_adding_wall_to_foreground_buffer &1704 e6 79 INC &79 ; wall_part # 1 (electric) or 5 (large) &1706 a6 79 LDX &79 ; wall_part &1708 a5 5e LDA &5e ; distance_before_large_wall &170a dd 61 17 CMP &1761,X ; large_wall_foreground_parts_distance &170d d0 0b BNE &171a ; consider_adding_third_part_of_large_wall ; add_second_part_of_large_wall # Add second from bottom row &170f a9 09 LDA #&09 # Length of row &1711 bc 69 17 LDY &1769,X ; large_wall_foreground_parts_foreground_y &1714 a2 03 LDX #&03 # Use second wall slot &1716 18 CLC # Clear carry to start from middle of wall &1717 4c 31 16 JMP &1631 ; start_adding_wall_to_foreground_buffer ; consider_adding_third_part_of_large_wall &171a a2 03 LDX #&03 # Use second wall slot &171c 20 3d 16 JSR &163d ; continue_adding_wall_to_foreground_buffer &171f e6 79 INC &79 ; wall_part # 2 (electric) or 6 (large) &1721 a6 79 LDX &79 ; wall_part &1723 a5 5e LDA &5e ; distance_before_large_wall &1725 dd 61 17 CMP &1761,X ; large_wall_foreground_parts_distance &1728 d0 10 BNE &173a ; consider_adding_fourth_part_of_large_wall ; add_third_part_of_large_wall # Add second from top row &172a bc 69 17 LDY &1769,X ; large_wall_foreground_parts_foreground_y &172d 8a TXA ; wall_part &172e 49 04 EOR #&04 &1730 aa TAX &1731 a9 09 LDA #&09 # Length of row &1733 e0 04 CPX #&04 # Set carry to start from left of wall if electric wall &1735 a2 06 LDX #&06 # Use third wall slot &1737 4c 31 16 JMP &1631 ; start_adding_wall_to_foreground_buffer ; consider_adding_fourth_part_of_large_wall &173a a2 06 LDX #&06 # Use third wall slot &173c 20 3d 16 JSR &163d ; continue_adding_wall_to_foreground_buffer &173f e6 79 INC &79 ; wall_part # 3 (electric) or 7 (large) &1741 a6 79 LDX &79 ; wall_part &1743 a5 5e LDA &5e ; distance_before_large_wall &1745 dd 61 17 CMP &1761,X ; large_wall_foreground_parts_distance &1748 d0 0b BNE &1755 ; continue_fourth_part_of_large_wall ; add_fourth_part_of_large_wall # Add top row &174a a9 09 LDA #&09 # Length of row &174c bc 69 17 LDY &1769,X ; large_wall_foreground_parts_foreground_y &174f a2 09 LDX #&09 # Use fourth wall slot &1751 38 SEC # Set carry to start from left of wall &1752 4c 31 16 JMP &1631 ; start_adding_wall_to_foreground_buffer ; continue_fourth_part_of_large_wall &1755 a5 5e LDA &5e ; distance_before_large_wall &1757 d0 03 BNE &175c ; not_end_of_large_wall # If zero, set to zero to stop adding large wall &1759 8d 68 09 STA &0968 ; large_wall_background_parts_data_address_low ; not_end_of_large_wall &175c a2 09 LDX #&09 # Use fourth wall slot &175e 4c 3d 16 JMP &163d ; continue_adding_wall_to_foreground_buffer ; large_wall_foreground_parts_distance ; 0 1 2 3 4 5 6 7 ; electric -> large ----> &1761 1d 1b 12 0a 1d 1b 19 12 ; large_wall_foreground_parts_foreground_y ; 0 1 2 3 4 5 6 7 ; electric -> large ----> &1769 04 04 41 71 04 04 04 31 ; add_sprite_to_background_buffer # Called with X = sprite_height &1771 a5 73 LDA &73 ; background_sprite_address_low &1773 85 80 STA &80 ; initial_background_sprite_address_low &1775 a5 74 LDA &74 ; background_sprite_address_high &1777 85 81 STA &81 ; initial_background_sprite_address_high &1779 a0 00 LDY #&00 ; add_sprite_to_background_buffer_loop &177b 84 72 STY &72 ; row_in_group &177d a5 76 LDA &76 ; background_x # Sections start from top right of background &177f a0 ff LDY #&ff &1781 c9 13 CMP #&13 &1783 b0 03 BCS &1788 ; add_column &1785 4c cf 17 JMP &17cf ; move_to_next_column # Don't add anything above top of screen ; add_column &1788 d0 06 BNE &1790 ; skip_masking_column &178a a4 72 LDY &72 ; row_in_group &178c b9 0e 15 LDA &150e,Y ; inverse_top_right_to_bottom_left_edge # Apply diagonal edge / to top of background &178f a8 TAY ; skip_masking_column &1790 84 77 STY &77 ; background_mask &1792 a0 00 LDY #&00 &1794 b1 73 LDA (&73),Y ; background_sprite_address &1796 25 77 AND &77 ; background_mask &1798 85 77 STA &77 ; panel_pixel_value &179a 84 78 STY &78 ; mask &179c a0 04 LDY #&04 ; add_sprite_to_background_buffer_pixel_loop &179e 18 CLC &179f 2c 0d 16 BIT &160d ; #&88 &17a2 d0 01 BNE &17a5 ; pixel_not_colour_0 &17a4 38 SEC # Set bit of mask if pixel is colour 0 ; pixel_not_colour_0 &17a5 26 78 ROL &78 ; mask &17a7 0a ASL A &17a8 88 DEY &17a9 d0 f3 BNE &179e ; add_sprite_to_background_buffer_pixel_loop &17ab a5 78 LDA &78 ; mask &17ad 0a ASL A &17ae 0a ASL A &17af 0a ASL A &17b0 0a ASL A &17b1 05 78 ORA &78 ; mask # Convert mask to colour 3 &17b3 85 78 STA &78 ; mask &17b5 a4 72 LDY &72 ; row_in_group &17b7 b1 70 LDA (&70),Y ; background_buffer_address &17b9 25 78 AND &78 ; mask &17bb 05 77 ORA &77 ; panel_pixel_value &17bd 91 70 STA (&70),Y ; background_buffer_address &17bf a5 73 LDA &73 ; background_sprite_address_low &17c1 18 CLC &17c2 65 75 ADC &75 ; background_sprite_width &17c4 85 73 STA &73 ; background_sprite_address_low &17c6 90 02 BCC &17ca ; skip_page &17c8 e6 74 INC &74 ; background_sprite_address_high ; skip_page &17ca c8 INY # Move down a row &17cb c0 04 CPY #&04 &17cd d0 ac BNE &177b ; add_sprite_to_background_buffer_loop ; move_to_next_column &17cf a5 80 LDA &80 ; initial_background_sprite_address_low &17d1 85 73 STA &73 ; background_sprite_address_low &17d3 a5 81 LDA &81 ; initial_background_sprite_address_high &17d5 85 74 STA &74 ; background_sprite_address_high &17d7 e6 73 INC &73 ; background_sprite_address_low &17d9 d0 02 BNE &17dd ; skip_page &17db e6 74 INC &74 ; background_sprite_address_high ; skip_page &17dd a5 70 LDA &70 ; background_buffer_address_low &17df 38 SEC &17e0 e9 04 SBC #&04 &17e2 85 70 STA &70 ; background_buffer_address_low &17e4 e6 76 INC &76 ; background_x &17e6 a5 76 LDA &76 ; background_x &17e8 c9 28 CMP #&28 &17ea 90 01 BCC &17ed ; not_last_column ; leave &17ec 60 RTS ; not_last_column &17ed ca DEX &17ee f0 fc BEQ &17ec ; leave &17f0 4c 71 17 JMP &1771 ; add_sprite_to_background_buffer ; consider_updating_background_part_of_large_wall &17f3 a2 07 LDX #&07 ; consider_updating_background_part_of_large_wall_part_loop &17f5 bd 00 09 LDA &0900,X ; background_wall_parts_rows_remaining # Non-zero if this part is being plotted &17f8 d0 2a BNE &1824 ; update_background_wall_parts &17fa ca DEX &17fb 10 f8 BPL &17f5 ; consider_updating_background_part_of_large_wall_part_loop &17fd ad 69 09 LDA &0969 ; large_wall_needs_initialising # Zero if large wall needs initialising &1800 f0 01 BEQ &1803 ; consider_initialising_large_wall &1802 60 RTS ; consider_initialising_large_wall &1803 ac 68 09 LDY &0968 ; large_wall_background_parts_data_address_low &1806 d0 01 BNE &1809 ; initialise_large_wall &1808 60 RTS ; initialise_large_wall &1809 a9 01 LDA #&01 &180b 8d 69 09 STA &0969 ; large_wall_needs_initialising # Set to non-zero to indicate initialising not necessary &180e 84 70 STY &70 ; background_wall_data_address_low &1810 a9 38 LDA #&38 ; &38b0 = electric_wall_background_parts_data &1812 85 71 STA &71 ; background_wall_data_address_high &1814 c0 18 CPY #&18 ; &3918 = large_wall_background_parts_data &1816 d0 02 BNE &181a ; skip_page &1818 e6 71 INC &71 ; background_wall_data_address_high ; skip_page &181a a0 67 LDY #&67 ; copy_background_wall_data_loop &181c b1 70 LDA (&70),Y ; background_wall_data_address &181e 99 00 09 STA &0900,Y ; background_wall_parts_data &1821 88 DEY &1822 10 f8 BPL &181c ; copy_background_wall_data_loop ; update_background_wall_parts &1824 a2 07 LDX #&07 ; update_background_wall_parts_loop &1826 86 79 STX &79 ; wall_part &1828 bd 00 09 LDA &0900,X ; background_wall_parts_rows_remaining # Non-zero if this part is being plotted &182b f0 05 BEQ &1832 ; consider_next_part &182d 20 36 18 JSR &1836 ; update_background_wall_part &1830 a6 79 LDX &79 ; wall_part &1832 ca DEX &1833 10 f1 BPL &1826 ; update_background_wall_parts_loop &1835 60 RTS ; update_background_wall_part &1836 bd 28 09 LDA &0928,X ; background_wall_parts_distance &1839 f0 04 BEQ &183f ; add_part &183b de 28 09 DEC &0928,X ; background_wall_parts_distance &183e 60 RTS ; add_part &183f 20 a4 18 JSR &18a4 ; add_part_of_large_wall_to_background_buffer &1842 bd 30 09 LDA &0930,X ; background_wall_parts_repeats_remaining &1845 d0 01 BNE &1848 ; consider_repeat &1847 60 RTS ; consider_repeat &1848 bc 48 09 LDY &0948,X ; background_wall_parts_repeat_type # Zero to repeat single block of sprite &184b f0 3f BEQ &188c ; consider_starting_repeat &184d bd 50 09 LDA &0950,X ; background_wall_parts_row_to_start_special_repeat &1850 c0 01 CPY #&01 # Two to use special block &1852 d0 03 BNE &1857 ; compare_height &1854 bd 38 09 LDA &0938,X ; background_wall_parts_row_to_start_repeat ; compare_height &1857 dd 00 09 CMP &0900,X ; background_wall_parts_rows_remaining &185a f0 01 BEQ &185d ; consider_special_repeat &185c 60 RTS ; consider_special_repeat &185d c0 01 CPY #&01 &185f d0 0f BNE &1870 ; use_special_block &1861 bd 30 09 LDA &0930,X ; background_wall_parts_repeats_remaining &1864 c9 01 CMP #&01 # If this is the last repeat, &1866 f0 21 BEQ &1889 ; consider_starting_repeat_after_dec # use regular (i.e. last) block &1868 a9 02 LDA #&02 &186a 9d 48 09 STA &0948,X ; background_wall_parts_repeat_type # Set to two to use special block &186d 4c 8c 18 JMP &188c ; consider_starting_repeat ; use_special_block &1870 de 48 09 DEC &0948,X ; background_wall_parts_repeat_type &1873 de 30 09 DEC &0930,X ; background_wall_parts_repeats_remaining &1876 fe 08 09 INC &0908,X ; background_wall_parts_start_x &1879 bd 60 09 LDA &0960,X ; background_wall_parts_rows_after_first_repeat &187c 9d 00 09 STA &0900,X ; background_wall_parts_rows_remaining &187f 20 a4 18 JSR &18a4 ; add_part_of_large_wall_to_background_buffer &1882 bd 58 09 LDA &0958,X ; background_wall_parts_rows_after_second_repeat &1885 9d 00 09 STA &0900,X ; background_wall_parts_rows_remaining &1888 60 RTS ; consider_starting_repeat_after_dec &1889 de 48 09 DEC &0948,X ; background_wall_parts_repeat_type # Set to zero to repeat single block of sprite ; consider_starting_repeat &188c bd 00 09 LDA &0900,X ; background_wall_parts_rows_remaining &188f dd 38 09 CMP &0938,X ; background_wall_parts_row_to_start_repeat &1892 f0 01 BEQ &1895 ; start_repeat &1894 60 RTS ; start_repeat &1895 de 30 09 DEC &0930,X ; background_wall_parts_repeats_remaining &1898 bd 40 09 LDA &0940,X ; background_wall_parts_rows_after_repeat &189b 9d 00 09 STA &0900,X ; background_wall_parts_rows_remaining &189e fe 08 09 INC &0908,X ; background_wall_parts_start_x &18a1 4c 36 18 JMP &1836 ; update_background_wall_part ; add_part_of_large_wall_to_background_buffer &18a4 a9 26 LDA #&26 &18a6 38 SEC &18a7 fd 08 09 SBC &0908,X ; background_wall_parts_start_x &18aa 0a ASL A &18ab 0a ASL A &18ac 85 70 STA &70 ; background_buffer_address_low &18ae a9 05 LDA #&05 ; &0500 = background_buffer &18b0 85 71 STA &71 ; background_buffer_address_high &18b2 de 00 09 DEC &0900,X ; background_wall_parts_rows_remaining &18b5 bd 00 09 LDA &0900,X ; background_wall_parts_rows_remaining &18b8 0a ASL A &18b9 0a ASL A &18ba 85 73 STA &73 ; size &18bc bc 10 09 LDY &0910,X ; background_wall_parts_width &18bf 84 75 STY &75 ; background_sprite_width &18c1 a9 00 LDA #&00 ; multiplication_loop &18c3 18 CLC &18c4 65 73 ADC &73 ; size &18c6 88 DEY &18c7 d0 fa BNE &18c3 ; multiplication_loop &18c9 18 CLC &18ca 7d 18 09 ADC &0918,X ; background_wall_parts_sprite_address_low &18cd 85 73 STA &73 ; background_sprite_address_low &18cf bd 20 09 LDA &0920,X ; background_wall_parts_sprite_address_high &18d2 69 00 ADC #&00 &18d4 85 74 STA &74 ; background_sprite_address_high &18d6 bd 08 09 LDA &0908,X ; background_wall_parts_start_x &18d9 85 76 STA &76 ; background_x &18db c9 28 CMP #&28 &18dd b0 05 BCS &18e4 ; skip_plotting_column &18df a6 75 LDX &75 ; background_sprite_width &18e1 20 71 17 JSR &1771 ; add_sprite_to_background_buffer ; skip_plotting_column &18e4 a6 79 LDX &79 ; wall_part &18e6 bd 08 09 LDA &0908,X ; background_wall_parts_start_x &18e9 38 SEC &18ea e9 01 SBC #&01 &18ec 9d 08 09 STA &0908,X ; background_wall_parts_start_x &18ef 60 RTS ; add_or_update_new_objects # Called with Y = 0 to update new objects &18f0 88 DEY # or Y = type of new object to add, A = fy &18f1 10 03 BPL &18f6 ; add_new_object &18f3 4c 7f 19 JMP &197f ; update_new_objects ; add_new_object &18f6 a2 03 LDX #&03 &18f8 85 7f STA &7f ; new_object_foreground_y &18fa 98 TYA &18fb 29 03 AND #&03 &18fd a8 TAY ; find_free_slot_for_new_object_loop &18fe bd 24 3f LDA &3f24,X ; new_objects_width_remaining # Zero if no object in slot &1901 f0 06 BEQ &1909 ; found_slot &1903 ca DEX &1904 10 f8 BPL &18fe ; find_free_slot_for_new_object_loop &1906 4c 7f 19 JMP &197f ; update_new_objects ; found_slot &1909 a5 7f LDA &7f ; new_object_foreground_y &190b 9d 20 3f STA &3f20,X ; new_objects_foreground_y &190e a9 03 LDA #&03 &1910 9d 24 3f STA &3f24,X ; new_objects_width_remaining &1913 b9 d6 19 LDA &19d6,Y ; object_type_sprite_addresses_low &1916 9d 28 3f STA &3f28,X ; new_objects_sprite_address_low &1919 b9 da 19 LDA &19da,Y ; object_type_heights &191c 9d 2c 3f STA &3f2c,X ; new_objects_height &191f a9 07 LDA #&07 &1921 38 SEC &1922 e5 7f SBC &7f ; new_object_foreground_y &1924 a8 TAY # screen_y = 263 - new_object_foreground_y &1925 a2 a7 LDX #&a7 &1927 20 5f 12 JSR &125f ; calculate_screen_address # Calculate screen address of top left of object &192a a5 70 LDA &70 ; screen_address_low &192c a6 7e LDX &7e ; object_slot &192e 9d 70 3e STA &3e70,X ; objects_screen_address_low &1931 a5 71 LDA &71 ; screen_address_high &1933 9d 80 3e STA &3e80,X ; objects_screen_address_high &1936 a0 02 LDY #&02 &1938 b1 85 LDA (&85),Y ; level_data_address # Third byte of level data sets silo properties &193a c9 c0 CMP #&c0 # Zero to check player's position for firing rocket &193c 90 06 BCC &1944 ; set_objects_data # Top bit set to always fire rocket at given z &193e a9 ff LDA #&ff # Or &c0 to never fire rocket &1940 9d 00 3e STA &3e00,X ; objects_z # Set to &ff to remove object &1943 60 RTS ; set_objects_data &1944 9d b0 3e STA &3eb0,X ; objects_silo_firing_position, objects_turret_initial_screen_y &1947 a9 03 LDA #&03 &1949 38 SEC &194a e5 7f SBC &7f ; new_object_foreground_y &194c a8 TAY # screen_y = 259 - new_object_foreground_y &194d a2 aa LDX #&aa &194f 20 5f 12 JSR &125f ; calculate_screen_address # Calculate screen address of centre of silo &1952 a5 70 LDA &70 ; screen_address_low &1954 a6 7e LDX &7e ; object_slot &1956 9d c0 3e STA &3ec0,X ; objects_silo_centre_screen_address_low &1959 a5 71 LDA &71 ; screen_address_high &195b 9d d0 3e STA &3ed0,X ; objects_silo_centre_screen_address_high &195e bd 60 3e LDA &3e60,X ; objects_type &1961 c9 02 CMP #&02 ; OBJECT_TURRET &1963 f0 01 BEQ &1966 ; is_turret ; leave &1965 60 RTS ; is_turret &1966 bd b0 3e LDA &3eb0,X ; objects_turret_initial_screen_y &1969 d0 fa BNE &1965 ; leave # Never branches &196b a9 01 LDA #&01 &196d 9d a0 3e STA &3ea0,X ; objects_turret_can_fire # Set to non-zero to allow turret to fire &1970 a9 fc LDA #&fc &1972 38 SEC &1973 e5 7f SBC &7f ; new_object_foreground_y # screen_y = 252 - new_object_screen_y &1975 9d b0 3e STA &3eb0,X ; objects_turret_initial_screen_y &1978 bd 00 3e LDA &3e00,X ; objects_z &197b 9d c0 3e STA &3ec0,X ; objects_turret_initial_z &197e 60 RTS ; update_new_objects &197f a2 03 LDX #&03 ; update_new_objects_loop &1981 86 7f STX &7f ; new_object_slot &1983 bd 24 3f LDA &3f24,X ; new_objects_width_remaining # Zero if no object in slot &1986 f0 03 BEQ &198b ; consider_next_new_object &1988 20 91 19 JSR &1991 ; update_new_object ; consider_next_new_object &198b a6 7f LDX &7f ; new_object_slot &198d ca DEX &198e 10 f1 BPL &1981 ; update_new_objects_loop &1990 60 RTS ; update_new_object # Plot next column of new object &1991 de 24 3f DEC &3f24,X ; new_objects_width_remaining &1994 a9 02 LDA #&02 &1996 38 SEC &1997 fd 24 3f SBC &3f24,X ; new_objects_width_remaining &199a a8 TAY &199b bd 28 3f LDA &3f28,X ; new_objects_sprite_address_low &199e c0 00 CPY #&00 &19a0 f0 07 BEQ &19a9 ; skip_adding_offset ; add_offset_loop # Calculate start of column &19a2 18 CLC &19a3 7d 2c 3f ADC &3f2c,X ; new_objects_height &19a6 88 DEY &19a7 d0 f9 BNE &19a2 ; add_offset_loop ; skip_adding_offset &19a9 85 73 STA &73 ; object_sprite_address_low &19ab a0 31 LDY #&31 &19ad bd 28 3f LDA &3f28,X ; new_objects_sprite_address_low &19b0 c9 ca CMP #&ca &19b2 d0 02 BNE &19b6 ; not_boss &19b4 a0 3c LDY #&3c ; &3cca = sprite_boss ; not_boss &19b6 84 74 STY &74 ; object_sprite_address_high &19b8 bd 20 3f LDA &3f20,X ; new_objects_foreground_y &19bb 85 77 STA &77 ; y &19bd 85 70 STA &70 ; foreground_buffer_address_low &19bf a9 04 LDA #&04 ; &0400 = foreground_buffer &19c1 85 71 STA &71 ; foreground_buffer_address_high &19c3 bd 2c 3f LDA &3f2c,X ; new_objects_height &19c6 aa TAX &19c7 20 dd 15 JSR &15dd ; add_column_of_new_object_to_foreground_buffer &19ca a6 7f LDX &7f ; new_object_slot &19cc bd 20 3f LDA &3f20,X ; new_objects_foreground_y &19cf 18 CLC &19d0 69 04 ADC #&04 &19d2 9d 20 3f STA &3f20,X ; new_objects_foreground_y &19d5 60 RTS ; object_type_sprite_addresses_low &19d6 78 ; &01 : &3178 = sprite_fuel &19d7 b4 ; &02 : &31b4 = sprite_turret &19d8 e4 ; &03 : &31e4 = sprite_silo &19d9 ca ; &04 : &3cca = sprite_boss ; object_type_heights ; 1 2 3 4 &19da 14 10 0c 10 ; add_or_update_large_or_electric_wall # Called with Y zero to update, non-zero to add &19de ad 74 09 LDA &0974 ; large_wall_updates_remaining &19e1 f0 03 BEQ &19e6 ; skip_updating_large_wall_updates_remaining &19e3 ce 74 09 DEC &0974 ; large_wall_updates_remaining ; skip_updating_large_wall_updates_remaining &19e6 c0 00 CPY #&00 &19e8 d0 01 BNE &19eb ; add_large_or_electric_wall &19ea 60 RTS ; add_large_or_electric_wall &19eb 8c 68 09 STY &0968 ; large_wall_background_parts_data_address_low &19ee a9 00 LDA #&00 &19f0 8d 69 09 STA &0969 ; large_wall_needs_initialising # Set to zero to indicate large wall needs initialising &19f3 a9 32 LDA #&32 &19f5 8d 74 09 STA &0974 ; large_wall_updates_remaining &19f8 8d 75 09 STA &0975 ; unused # Unused variable &19fb 60 RTS ; add_or_update_small_wall # Called with Y zero to update, non-zero to add &19fc a2 00 LDX #&00 # Use wall slot 0 &19fe c0 00 CPY #&00 &1a00 f0 04 BEQ &1a06 ; update_small_wall &1a02 38 SEC # Set carry to start from left of wall &1a03 4c 31 16 JMP &1631 ; start_adding_wall_to_foreground_buffer ; update_small_wall &1a06 ad 74 09 LDA &0974 ; large_wall_updates_remaining &1a09 f0 01 BEQ &1a0c ; to_continue_adding_wall_to_foreground_buffer &1a0b 60 RTS ; to_continue_adding_wall_to_foreground_buffer &1a0c 4c 3d 16 JMP &163d ; continue_adding_wall_to_foreground_buffer ; update_panel &1a0f bd 80 09 LDA &0980,X ; panels_length &1a12 d0 01 BNE &1a15 ; add_column_of_panel_to_background_buffer &1a14 60 RTS ; add_column_of_panel_to_background_buffer &1a15 a9 26 LDA #&26 &1a17 38 SEC &1a18 fd 81 09 SBC &0981,X ; panels_x &1a1b 0a ASL A &1a1c 0a ASL A &1a1d 85 70 STA &70 ; background_buffer_address_low &1a1f a9 05 LDA #&05 ; &0500 = background_buffer &1a21 85 71 STA &71 ; background_buffer_address_high &1a23 bd 81 09 LDA &0981,X ; panels_x &1a26 85 76 STA &76 ; background_x &1a28 bd 82 09 LDA &0982,X ; panels_sprite_address_low &1a2b 38 SEC &1a2c e9 38 SBC #&38 &1a2e 9d 82 09 STA &0982,X ; panels_sprite_address_low &1a31 85 73 STA &73 ; background_sprite_address_low &1a33 bd 83 09 LDA &0983,X ; panels_sprite_address_high &1a36 e9 00 SBC #&00 &1a38 9d 83 09 STA &0983,X ; panels_sprite_address_high &1a3b 85 74 STA &74 ; background_sprite_address_high &1a3d de 80 09 DEC &0980,X ; panels_length &1a40 de 81 09 DEC &0981,X ; panels_x &1a43 a2 0e LDX #&0e &1a45 86 75 STX &75 ; background_sprite_width &1a47 4c 71 17 JMP &1771 ; add_sprite_to_background_buffer ; add_background_panel &1a4a bd 80 09 LDA &0980,X ; panels_length &1a4d f0 01 BEQ &1a50 ; found_free_slot_for_background_panel &1a4f 60 RTS ; found_free_slot_for_background_panel &1a50 a9 1a LDA #&1a &1a52 9d 80 09 STA &0980,X ; panels_length &1a55 a9 1f LDA #&1f &1a57 9d 81 09 STA &0981,X ; panels_x &1a5a a9 b0 LDA #&b0 ; &38b0 = sprite_panel + 26 * &38 &1a5c 9d 82 09 STA &0982,X ; panels_sprite_address_low &1a5f a9 38 LDA #&38 &1a61 9d 83 09 STA &0983,X ; panels_sprite_address_high &1a64 60 RTS ; add_or_update_background_panels # Called with Y = 0 from update_world &1a65 c0 00 CPY #&00 # or Y = number of panels to add &1a67 f0 08 BEQ &1a71 ; update_background_panel &1a69 8c 88 09 STY &0988 ; panels_remaining &1a6c a2 04 LDX #&04 # Add new panel in furthest panel slot &1a6e 20 4a 1a JSR &1a4a ; add_background_panel ; update_background_panel &1a71 a2 04 LDX #&04 # Update furthest panel &1a73 20 0f 1a JSR &1a0f ; update_panel &1a76 a2 00 LDX #&00 # Update nearest panel &1a78 20 0f 1a JSR &1a0f ; update_panel &1a7b ad 88 09 LDA &0988 ; panels_remaining &1a7e f0 07 BEQ &1a87 ; leave &1a80 ad 84 09 LDA &0984 ; panels_length + 4 # Has the furthest panel reached the clip boundary? &1a83 c9 0d CMP #&0d &1a85 f0 01 BEQ &1a88 ; convert_furthest_panel_into_nearest_panel ; leave &1a87 60 RTS ; convert_furthest_panel_into_nearest_panel # If so, move the furthest panel into the nearest panel &1a88 a2 03 LDX #&03 ; shuffle_panel_data_loop &1a8a bd 84 09 LDA &0984,X ; panels_length + 4 # Furthest panel &1a8d 9d 80 09 STA &0980,X ; panels_length # Nearest panel &1a90 ca DEX &1a91 10 f7 BPL &1a8a ; shuffle_panel_data_loop &1a93 a9 00 LDA #&00 # Remove furthest panel &1a95 8d 84 09 STA &0984 ; panels_length + 4 &1a98 ce 88 09 DEC &0988 ; panels_remaining &1a9b d0 01 BNE &1a9e ; add_next_panel &1a9d 60 RTS ; add_next_panel &1a9e a2 04 LDX #&04 # Add new panel in furthest panel slot &1aa0 4c 4a 1a JMP &1a4a ; add_background_panel ; consider_adding_new_objects &1aa3 a5 86 LDA &86 ; level_data_address_high &1aa5 d0 03 BNE &1aaa ; skip_initialising_level_data_address &1aa7 20 98 1b JSR &1b98 ; initialise_level_data_address ; skip_initialising_level_data_address &1aaa a0 00 LDY #&00 &1aac b1 85 LDA (&85),Y ; level_data_address # First byte of level data is z position of next object &1aae cd 0a 3f CMP &3f0a ; distance_since_checkpoint &1ab1 f0 01 BEQ &1ab4 ; add_next_object &1ab3 60 RTS ; add_next_object &1ab4 c8 INY ; 1 &1ab5 b1 85 LDA (&85),Y ; level_data_address # Second byte of level data is object type &1ab7 c9 ff CMP #&ff # &ff indicates checkpoint or end of level data &1ab9 d0 03 BNE &1abe ; add_object &1abb 4c a8 1b JMP &1ba8 ; set_checkpoint_or_restart_level_data ; add_object &1abe 85 7f STA &7f ; object_type &1ac0 a2 09 LDX #&09 ; find_slot_for_new_object_loop &1ac2 bd 00 3e LDA &3e00,X ; objects_z # Negative if no object in slot &1ac5 10 05 BPL &1acc ; consider_next_slot &1ac7 bd 90 3e LDA &3e90,X ; objects_rocket_ttl # Negative if no rocket in slot &1aca 30 03 BMI &1acf ; found_free_slot_for_new_object ; consider_next_slot &1acc ca DEX &1acd 10 f3 BPL &1ac2 ; find_slot_for_new_object_loop ; found_free_slot_for_new_object &1acf 86 7e STX &7e ; object_slot &1ad1 a5 7f LDA &7f ; object_type &1ad3 9d 60 3e STA &3e60,X ; objects_type &1ad6 f0 58 BEQ &1b30 ; move_to_next_object &1ad8 c9 04 CMP #&04 ; OBJECT_ELECTRIC_WALL &1ada 90 0a BCC &1ae6 ; calculate_position_of_regular_object &1adc c9 08 CMP #&08 ; OBJECT_BOSS &1ade f0 06 BEQ &1ae6 ; calculate_position_of_regular_object &1ae0 20 cc 1b JSR &1bcc ; calculate_position_of_wall_or_fighter &1ae3 4c 30 1b JMP &1b30 ; move_to_next_object ; calculate_position_of_regular_object &1ae6 c9 03 CMP #&03 ; OBJECT_SILO &1ae8 08 PHP ; is silo &1ae9 a9 03 LDA #&03 # Fuel, turret and boss are three columns wide &1aeb 28 PLP ; is silo &1aec 08 PHP ; is silo &1aed d0 02 BNE &1af1 ; set_objects_width_remaining &1aef a9 02 LDA #&02 # Silo is two columns wide ; set_objects_width_remaining &1af1 9d 10 3e STA &3e10,X ; objects_width_remaining &1af4 a0 03 LDY #&03 &1af6 b1 85 LDA (&85),Y ; level_data_address # Fourth byte of level data sets x and z from foreground_y &1af8 4a LSR A &1af9 85 70 STA &70 ; y_divided_by_two &1afb 4a LSR A &1afc 4a LSR A &1afd 85 7f STA &7f ; y_divided_by_eight &1aff a9 20 LDA #&20 &1b01 38 SEC &1b02 e5 7f SBC &7f ; y_divided_by_eight &1b04 28 PLP ; is silo &1b05 08 PHP ; is silo &1b06 d0 02 BNE &1b0a ; set_objects_z &1b08 69 01 ADC #&01 ; set_objects_z &1b0a 9d 00 3e STA &3e00,X ; objects_z # z = &20 - (foreground_y / 8) &1b0d a5 70 LDA &70 ; y_divided_by_two &1b0f 18 CLC &1b10 69 14 ADC #&14 &1b12 28 PLP ; is silo &1b13 08 PHP ; is silo &1b14 d0 02 BNE &1b18 ; set_objects_min_x &1b16 e9 01 SBC #&01 ; set_objects_min_x &1b18 9d 20 3e STA &3e20,X ; objects_min_x # min_x = &14 + (foreground_y / 2) &1b1b 18 CLC &1b1c 69 0c ADC #&0c &1b1e 9d 30 3e STA &3e30,X ; objects_max_x # max_x = &20 + (foreground_y / 2) &1b21 a9 00 LDA #&00 &1b23 9d 40 3e STA &3e40,X ; objects_min_y &1b26 a9 14 LDA #&14 &1b28 28 PLP ; is silo &1b29 d0 02 BNE &1b2d ; set_objects_max_y &1b2b a9 00 LDA #&00 ; set_objects_max_y &1b2d 9d 50 3e STA &3e50,X ; objects_max_y ; move_to_next_object &1b30 a0 01 LDY #&01 &1b32 20 43 1b JSR &1b43 ; initialise_new_object &1b35 a5 85 LDA &85 ; level_data_address_low &1b37 18 CLC &1b38 69 04 ADC #&04 # Move to next object in level data &1b3a 85 85 STA &85 ; level_data_address_low &1b3c 90 02 BCC &1b40 ; skip_page &1b3e e6 86 INC &86 ; level_data_address_high ; skip_page &1b40 4c a3 1a JMP &1aa3 ; consider_adding_new_objects ; initialise_new_object &1b43 b1 85 LDA (&85),Y ; level_data_address # Second byte of level data is object type &1b45 d0 07 BNE &1b4e ; not_panel # If zero, &1b47 c8 INY ; 2 &1b48 b1 85 LDA (&85),Y ; level_data_address # Third byte of level data sets number of panels &1b4a a8 TAY &1b4b 4c 65 1a JMP &1a65 ; add_or_update_background_panels ; not_panel &1b4e c9 04 CMP #&04 ; OBJECT_ELECTRIC_WALL &1b50 90 04 BCC &1b56 ; add_regular_object &1b52 c9 08 CMP #&08 ; OBJECT_BOSS &1b54 d0 0b BNE &1b61 ; add_wall_or_fighter ; add_regular_object &1b56 85 7f STA &7f ; object_type &1b58 c8 INY &1b59 c8 INY ; 3 &1b5a b1 85 LDA (&85),Y ; level_data_address # Fourth byte of level data sets foreground_y &1b5c a4 7f LDY &7f ; object_type &1b5e 4c f0 18 JMP &18f0 ; add_or_update_new_objects ; add_wall_or_fighter &1b61 c9 06 CMP #&06 ; OBJECT_SMALL_WALL &1b63 b0 0b BCS &1b70 ; add_small_wall &1b65 a0 b0 LDY #&b0 ; &38b0 = electric_wall_background_parts_data &1b67 c9 04 CMP #&04 ; OBJECT_ELECTRIC_WALL &1b69 f0 02 BEQ &1b6d ; to_add_or_update_large_or_electric_wall &1b6b a0 18 LDY #&18 ; &3918 = large_wall_background_parts_data ; to_add_or_update_large_or_electric_wall &1b6d 4c de 19 JMP &19de ; add_or_update_large_or_electric_wall # Y is non-zero to add wall ; add_small_wall &1b70 d0 0e BNE &1b80 ; leave # Never branches &1b72 c8 INY ; 2 &1b73 b1 85 LDA (&85),Y ; level_data_address # Third byte of level data sets length of small wall &1b75 85 7f STA &7f ; wall_length &1b77 c8 INY ; 3 &1b78 b1 85 LDA (&85),Y ; level_data_address # Fourth byte of level data sets foreground_y &1b7a a8 TAY &1b7b a5 7f LDA &7f ; wall_length &1b7d 4c fc 19 JMP &19fc ; add_or_update_small_wall # Y is non-zero to add wall ; leave &1b80 60 RTS ; update_world &1b81 a0 00 LDY #&00 # Zero to update new objects &1b83 20 f0 18 JSR &18f0 ; add_or_update_new_objects &1b86 a0 00 LDY #&00 # Zero to update large or electric wall &1b88 20 de 19 JSR &19de ; add_or_update_large_or_electric_wall &1b8b a0 00 LDY #&00 # Zero to update small wall &1b8d 20 fc 19 JSR &19fc ; add_or_update_small_wall &1b90 a0 00 LDY #&00 # Zero to update background panels &1b92 20 65 1a JSR &1a65 ; add_or_update_background_panels &1b95 4c a3 1a JMP &1aa3 ; consider_adding_new_objects ; initialise_level_data_address &1b98 a9 00 LDA #&00 &1b9a 85 85 STA &85 ; level_data_address_low &1b9c 85 00 STA &00 ; initial_level_data_address_low &1b9e 8d 0a 3f STA &3f0a ; distance_since_checkpoint &1ba1 a5 14 LDA &14 ; level_data_base_address_high &1ba3 85 86 STA &86 ; level_data_address_high &1ba5 85 01 STA &01 ; initial_level_data_address_high &1ba7 60 RTS ; set_checkpoint_or_restart_level_data &1ba8 a0 02 LDY #&02 &1baa b1 85 LDA (&85),Y ; level_data_address # Third byte of level data is zero for checkpoint, &1bac d0 ea BNE &1b98 ; initialise_level_data_address # or non-zero to indicate end of level &1bae a5 85 LDA &85 ; level_data_address_low &1bb0 18 CLC &1bb1 69 04 ADC #&04 # Move to next object in level data &1bb3 85 85 STA &85 ; level_data_address_low &1bb5 85 00 STA &00 ; initial_level_data_address_low &1bb7 a5 86 LDA &86 ; level_data_address_high &1bb9 69 00 ADC #&00 &1bbb 85 86 STA &86 ; level_data_address_high &1bbd 85 01 STA &01 ; initial_level_data_address_high &1bbf a9 00 LDA #&00 &1bc1 8d 0a 3f STA &3f0a ; distance_since_checkpoint &1bc4 a9 01 LDA #&01 &1bc6 8d 75 3f STA &3f75 ; reached_checkpoint # Set to non-zero to indicate checkpoint reached &1bc9 85 06 STA &06 ; initial_reached_checkpoint &1bcb 60 RTS ; calculate_position_of_wall_or_fighter &1bcc c9 06 CMP #&06 ; OBJECT_SMALL_WALL &1bce f0 03 BEQ &1bd3 ; calculate_position_of_small_wall &1bd0 4c 11 1c JMP &1c11 ; consider_calculating_position_of_large_wall ; calculate_position_of_small_wall &1bd3 a0 03 LDY #&03 &1bd5 b1 85 LDA (&85),Y ; level_data_address # Fourth byte of level data sets x and z from foreground_y &1bd7 38 SEC &1bd8 e9 20 SBC #&20 &1bda 4a LSR A &1bdb 48 PHA ; y_divided_by_two &1bdc 4a LSR A &1bdd 4a LSR A &1bde 85 7f STA &7f ; y_divided_by_eight &1be0 a9 1f LDA #&1f &1be2 38 SEC &1be3 e5 7f SBC &7f ; y_divided_by_eight &1be5 9d 00 3e STA &3e00,X ; objects_z # z = &1f - ((foreground_y - &20) / 8) &1be8 68 PLA ; y_divided_by_two &1be9 18 CLC &1bea 69 17 ADC #&17 &1bec 9d 20 3e STA &3e20,X ; objects_min_x # min_x = &17 + ((foreground_y - &20) / 2) &1bef 18 CLC &1bf0 69 1f ADC #&1f &1bf2 85 7f STA &7f ; x &1bf4 a0 02 LDY #&02 &1bf6 b1 85 LDA (&85),Y ; level_data_address # Third byte of object data sets length of small wall &1bf8 0a ASL A &1bf9 0a ASL A &1bfa 0a ASL A &1bfb 18 CLC &1bfc 65 7f ADC &7f ; x &1bfe 9d 30 3e STA &3e30,X ; objects_max_x &1c01 a9 00 LDA #&00 &1c03 9d 40 3e STA &3e40,X ; objects_min_y &1c06 a9 14 LDA #&14 &1c08 9d 50 3e STA &3e50,X ; objects_max_y &1c0b a9 02 LDA #&02 &1c0d 9d 10 3e STA &3e10,X ; objects_width_remaining &1c10 60 RTS ; consider_calculating_position_of_large_wall &1c11 c9 05 CMP #&05 ; OBJECT_LARGE_WALL &1c13 f0 03 BEQ &1c18 ; calculate_position_of_large_wall &1c15 4c 3c 1c JMP &1c3c ; consider_calculating_position_of_fighter ; calculate_position_of_large_wall &1c18 a9 29 LDA #&29 &1c1a 9d 00 3e STA &3e00,X ; objects_z &1c1d a9 23 LDA #&23 # This is the opening at the top of the wall &1c1f 9d 20 3e STA &3e20,X ; objects_min_x # x:(&23, &35) y:(&30, &40) &1c22 a9 35 LDA #&35 &1c24 9d 30 3e STA &3e30,X ; objects_max_x &1c27 a9 30 LDA #&30 &1c29 9d 40 3e STA &3e40,X ; objects_min_y &1c2c a9 40 LDA #&40 &1c2e 9d 50 3e STA &3e50,X ; objects_max_y &1c31 a9 02 LDA #&02 &1c33 9d 10 3e STA &3e10,X ; objects_width_remaining &1c36 a9 85 LDA #&85 ; OBJECT_LARGE_WALL | &80 # Top bit set to check for passing, not collision &1c38 9d 60 3e STA &3e60,X ; objects_type &1c3b 60 RTS ; consider_calculating_position_of_fighter &1c3c c9 09 CMP #&09 ; OBJECT_FIGHTER &1c3e d0 03 BNE &1c43 ; calculate_position_of_electric_wall &1c40 4c 94 29 JMP &2994 ; to_calculate_position_of_fighter ; calculate_position_of_electric_wall &1c43 a9 29 LDA #&29 &1c45 9d 00 3e STA &3e00,X ; objects_z &1c48 a9 1b LDA #&1b # This is the opening in the middle of the wall &1c4a 9d 20 3e STA &3e20,X ; objects_min_x # x:(&1b, &33) y:(&20, &28) &1c4d a9 33 LDA #&33 &1c4f 9d 30 3e STA &3e30,X ; objects_max_x &1c52 a9 20 LDA #&20 &1c54 9d 40 3e STA &3e40,X ; objects_min_y &1c57 a9 28 LDA #&28 &1c59 9d 50 3e STA &3e50,X ; objects_max_y &1c5c a9 02 LDA #&02 &1c5e 9d 10 3e STA &3e10,X ; objects_width_remaining &1c61 a9 84 LDA #&84 ; OBJECT_ELECTRIC_WALL | &80 # Top bit set to check for passing, not collision &1c63 9d 60 3e STA &3e60,X ; objects_type &1c66 a0 02 LDY #&02 &1c68 b1 85 LDA (&85),Y ; level_data_address # Third byte of object data is always one &1c6a f0 0b BEQ &1c77 ; find_second_slot_for_electric_wall # Never branches &1c6c a9 01 LDA #&01 &1c6e 8d 82 3f STA &3f82 ; electric_fence_state # Set to non-zero to indicate electric fence needs plotting &1c71 a9 1c LDA #&1c &1c73 8d 83 3f STA &3f83 ; electric_fence_cooldown &1c76 60 RTS ; find_second_slot_for_electric_wall # Unused code; never called &1c77 a9 41 LDA #&41 &1c79 9d 50 3e STA &3e50,X ; objects_max_y # Would make middle opening extend to top of wall &1c7c a2 09 LDX #&09 ; find_free_object_slot_loop &1c7e bd 00 3e LDA &3e00,X ; objects_z &1c81 30 03 BMI &1c86 ; found_free_slot &1c83 ca DEX &1c84 10 f8 BPL &1c7e ; find_free_object_slot_loop ; found_free_slot &1c86 a9 29 LDA #&29 &1c88 9d 00 3e STA &3e00,X ; objects_z &1c8b a9 1b LDA #&1b # This would be another opening, at the top of the wall &1c8d 9d 20 3e STA &3e20,X ; objects_min_x # x:(&1b, &4b) y:(&30, &40) &1c90 a9 4b LDA #&4b &1c92 9d 30 3e STA &3e30,X ; objects_max_x &1c95 a9 30 LDA #&30 &1c97 9d 40 3e STA &3e40,X ; objects_min_y &1c9a a9 40 LDA #&40 &1c9c 9d 50 3e STA &3e50,X ; objects_max_y &1c9f a9 02 LDA #&02 &1ca1 9d 10 3e STA &3e10,X ; objects_width_remaining &1ca4 a9 84 LDA #&84 ; OBJECT_ELECTRIC_WALL | &80 # Top bit set to check for passing, not collision &1ca6 9d 60 3e STA &3e60,X ; objects_type &1ca9 60 RTS ; to_calculate_screen_address &1caa 4c 5f 12 JMP &125f ; calculate_screen_address ; to_plot_masked_sprite &1cad 4c 1b 1e JMP &1e1b ; plot_masked_sprite ; to_plot_sprite &1cb0 4c a1 1e JMP &1ea1 ; plot_sprite ; to_buffer_sprite &1cb3 4c bd 1d JMP &1dbd ; buffer_sprite ; to_rnd &1cb6 4c c6 12 JMP &12c6 ; rnd ; to_set_palette &1cb9 4c 55 23 JMP &2355 ; set_palette ; to_wait_for_vsync &1cbc 4c e0 12 JMP &12e0 ; wait_for_vsync ; to_check_for_keypress &1cbf 4c a2 12 JMP &12a2 ; check_for_keypress ; to_start_level &1cc2 4c 52 13 JMP &1352 ; start_level ; to_wipe_screen # Unused vector &1cc5 4c f6 11 JMP &11f6 ; wipe_screen ; to_start_game &1cc8 4c 3b 13 JMP &133b ; start_game ; to_plot_shadow_column_loop &1ccb 4c 4a 1f JMP &1f4a ; plot_shadow_column_loop ; to_update_turrets &1cce 4c 8e 27 JMP &278e ; update_turrets ; to_start_firing_sound &1cd1 4c 61 21 JMP &2161 ; start_firing_sound ; consider_moving_player &1cd4 ad 02 3f LDA &3f02 ; player_y &1cd7 d0 14 BNE &1ced ; skip_resetting_player &1cd9 a9 98 LDA #&98 &1cdb 8d 02 3f STA &3f02 ; player_y &1cde a9 15 LDA #&15 &1ce0 8d 03 3f STA &3f03 ; player_x &1ce3 a9 11 LDA #&11 &1ce5 8d 40 3f STA &3f40 ; background_sound_frequency &1ce8 a9 ef LDA #&ef ; 1110 1111 # Set channel 0 volume to 0 (silence) &1cea 20 6a 23 JSR &236a ; write_to_sound_chip ; skip_resetting_player &1ced ad 6d 3f LDA &3f6d ; player_fuel &1cf0 d0 11 BNE &1d03 ; move_player # Is the player out of fuel? &1cf2 ad 02 3f LDA &3f02 ; player_y &1cf5 38 SEC &1cf6 e9 03 SBC #&03 # If so, move the player downwards &1cf8 c9 90 CMP #&90 &1cfa 90 06 BCC &1d02 ; leave &1cfc 8d 02 3f STA &3f02 ; player_y &1cff ee 40 3f INC &3f40 ; background_sound_frequency ; leave &1d02 60 RTS ; move_player &1d03 a6 30 LDX &30 ; key_up &1d05 20 91 0e JSR &0e91 ; check_for_movement # Returns not equal if key pressed or joystick up &1d08 f0 10 BEQ &1d1a ; up_not_pressed &1d0a ad 02 3f LDA &3f02 ; player_y &1d0d 18 CLC &1d0e 69 03 ADC #&03 &1d10 c9 c8 CMP #&c8 # Don't allow player to move above top of world &1d12 b0 06 BCS &1d1a ; up_not_pressed &1d14 8d 02 3f STA &3f02 ; player_y &1d17 ce 40 3f DEC &3f40 ; background_sound_frequency ; up_not_pressed &1d1a a6 31 LDX &31 ; key_down &1d1c 20 91 0e JSR &0e91 ; check_for_movement # Returns not equal if key pressed or joystick down &1d1f f0 10 BEQ &1d31 ; down_not_pressed &1d21 ad 02 3f LDA &3f02 ; player_y &1d24 38 SEC &1d25 e9 03 SBC #&03 &1d27 c9 98 CMP #&98 # Don't allow player to move below ground &1d29 90 06 BCC &1d31 ; down_not_pressed &1d2b 8d 02 3f STA &3f02 ; player_y &1d2e ee 40 3f INC &3f40 ; background_sound_frequency ; down_not_pressed &1d31 a6 33 LDX &33 ; key_right &1d33 20 91 0e JSR &0e91 ; check_for_movement # Returns not equal if key pressed or joystick right &1d36 f0 0d BEQ &1d45 ; right_not_pressed &1d38 ad 03 3f LDA &3f03 ; player_x &1d3b 18 CLC &1d3c 69 02 ADC #&02 &1d3e c9 46 CMP #&46 # Don't allow player to move off right edge of world &1d40 b0 03 BCS &1d45 ; right_not_pressed &1d42 8d 03 3f STA &3f03 ; player_x ; right_not_pressed &1d45 a6 32 LDX &32 ; key_left &1d47 20 91 0e JSR &0e91 ; check_for_movement # Returns not equal if key pressed or joystick left &1d4a f0 0d BEQ &1d59 ; left_not_pressed &1d4c ad 03 3f LDA &3f03 ; player_x &1d4f 38 SEC &1d50 e9 02 SBC #&02 &1d52 c9 15 CMP #&15 # Don't allow player to move off left edge of world &1d54 90 03 BCC &1d59 ; left_not_pressed &1d56 8d 03 3f STA &3f03 ; player_x ; left_not_pressed &1d59 60 RTS ; update_player &1d5a ad 03 3f LDA &3f03 ; player_x &1d5d 29 02 AND #&02 &1d5f 08 PHP ; evenness &1d60 a9 39 LDA #&39 &1d62 85 7c STA &7c ; player_sprite_address_high &1d64 a9 80 LDA #&80 ; &3980 = sprite_player_odd &1d66 28 PLP ; evenness &1d67 f0 02 BEQ &1d6b ; set_player_sprite_address_low &1d69 a9 e8 LDA #&e8 ; &39e8 = sprite_player_even ; set_player_sprite_address_low &1d6b 85 7b STA &7b ; player_sprite_address_low &1d6d 20 8b 29 JSR &298b ; to_unplot_player # Unplot player &1d70 20 97 29 JSR &2997 ; to_consider_updating_fighter &1d73 ae 03 3f LDX &3f03 ; player_x &1d76 ad 02 3f LDA &3f02 ; player_y &1d79 38 SEC &1d7a ed 03 3f SBC &3f03 ; player_x &1d7d a8 TAY &1d7e 20 5f 12 JSR &125f ; calculate_screen_address &1d81 a5 70 LDA &70 ; screen_address_low &1d83 48 PHA ; screen_address_low &1d84 8d 04 3f STA &3f04 ; player_screen_address_low &1d87 a5 71 LDA &71 ; screen_address_high &1d89 48 PHA ; screen_address_high &1d8a 8d 05 3f STA &3f05 ; player_screen_address_high &1d8d a9 00 LDA #&00 ; &0600 = player_buffer &1d8f 85 72 STA &72 ; buffer_address_low &1d91 a9 06 LDA #&06 &1d93 85 73 STA &73 ; buffer_address_high &1d95 a9 04 LDA #&04 &1d97 85 74 STA &74 ; sprite_width &1d99 a9 0d LDA #&0d &1d9b 85 75 STA &75 ; sprite_height &1d9d 20 bd 1d JSR &1dbd ; buffer_sprite # Buffer player &1da0 68 PLA ; screen_address_high &1da1 85 71 STA &71 ; screen_address_high &1da3 68 PLA ; screen_address_low &1da4 85 70 STA &70 ; screen_address_low &1da6 a5 7b LDA &7b ; player_sprite_address_low &1da8 85 72 STA &72 ; sprite_address_low &1daa a5 7c LDA &7c ; player_sprite_address_high &1dac 85 73 STA &73 ; sprite_address_high &1dae a9 04 LDA #&04 &1db0 85 74 STA &74 ; sprite_width &1db2 a9 0d LDA #&0d &1db4 85 75 STA &75 ; sprite_height &1db6 4c 1b 1e JMP &1e1b ; plot_masked_sprite # Plot player ; unused ; z a : / &1db9 9e be b7 97 # Unused keycodes ; buffer_sprite &1dbd a5 71 LDA &71 ; screen_address_high &1dbf 48 PHA ; screen_address_high &1dc0 a5 70 LDA &70 ; screen_address_low &1dc2 48 PHA ; screen_address_low &1dc3 29 03 AND #&03 &1dc5 a8 TAY &1dc6 45 70 EOR &70 ; screen_address_low &1dc8 85 70 STA &70 ; screen_address_low &1dca a9 00 LDA #&00 &1dcc 85 77 STA &77 ; buffer_offset &1dce a5 75 LDA &75 ; sprite_height &1dd0 85 78 STA &78 ; rows ; buffer_sprite_row_loop &1dd2 b1 70 LDA (&70),Y ; screen_address &1dd4 c8 INY &1dd5 84 76 STY &76 ; row_in_group &1dd7 a4 77 LDY &77 ; buffer_offset &1dd9 91 72 STA (&72),Y ; buffer_address &1ddb c8 INY # Move down a row &1ddc 84 77 STY &77 ; buffer_offset &1dde a4 76 LDY &76 ; row_in_group &1de0 98 TYA &1de1 29 03 AND #&03 &1de3 d0 13 BNE &1df8 ; not_group &1de5 a0 00 LDY #&00 &1de7 a5 70 LDA &70 ; screen_address_low &1de9 18 CLC &1dea 69 40 ADC #&40 # Move down a group &1dec 85 70 STA &70 ; screen_address_low &1dee a5 71 LDA &71 ; screen_address_high &1df0 69 01 ADC #&01 &1df2 10 02 BPL &1df6 ; skip_wraparound &1df4 e9 3f SBC #&3f ; skip_wraparound &1df6 85 71 STA &71 ; screen_address_high ; not_group &1df8 c6 78 DEC &78 ; rows &1dfa d0 d6 BNE &1dd2 ; buffer_sprite_row_loop &1dfc 68 PLA ; screen_address_low &1dfd 18 CLC &1dfe 69 08 ADC #&08 # Move right four pixels &1e00 85 70 STA &70 ; screen_address_low &1e02 68 PLA ; screen_address_high &1e03 69 00 ADC #&00 &1e05 10 02 BPL &1e09 ; skip_wraparound &1e07 e9 3f SBC #&3f ; skip_wraparound &1e09 85 71 STA &71 ; screen_address_high &1e0b a5 72 LDA &72 ; buffer_address_low &1e0d 18 CLC &1e0e 65 75 ADC &75 ; sprite_height &1e10 85 72 STA &72 ; buffer_address_low &1e12 90 02 BCC &1e16 ; skip_page &1e14 e6 73 INC &73 ; buffer_address_high ; skip_page &1e16 c6 74 DEC &74 ; sprite_width &1e18 d0 a3 BNE &1dbd ; buffer_sprite &1e1a 60 RTS ; plot_masked_sprite &1e1b a5 71 LDA &71 ; screen_address_high &1e1d d0 01 BNE &1e20 ; plot_masked_sprite_column_loop &1e1f 60 RTS ; plot_masked_sprite_column_loop &1e20 a5 71 LDA &71 ; screen_address_high &1e22 48 PHA ; screen_address_high &1e23 a5 70 LDA &70 ; screen_address_low &1e25 48 PHA ; screen_address_low &1e26 29 03 AND #&03 &1e28 85 76 STA &76 ; row_in_group &1e2a 45 70 EOR &70 ; screen_address_low &1e2c 85 70 STA &70 ; screen_address_low &1e2e a0 00 LDY #&00 &1e30 a5 75 LDA &75 ; sprite_height &1e32 85 78 STA &78 ; rows ; plot_masked_sprite_row_loop &1e34 b1 72 LDA (&72),Y ; sprite_address &1e36 c8 INY &1e37 84 77 STY &77 ; sprite_offset &1e39 85 79 STA &79 ; sprite_pixel_value &1e3b a0 00 LDY #&00 &1e3d 84 7a STY &7a ; mask &1e3f a0 04 LDY #&04 ; plot_masked_sprite_pixel_loop &1e41 18 CLC &1e42 2c 0d 16 BIT &160d ; #&88 &1e45 d0 01 BNE &1e48 ; pixel_not_colour_0 &1e47 38 SEC # Set bit of mask if pixel is colour 0 ; pixel_not_colour_0 &1e48 26 7a ROL &7a ; mask &1e4a 0a ASL A &1e4b 88 DEY &1e4c d0 f3 BNE &1e41 ; plot_masked_sprite_pixel_loop &1e4e a5 7a LDA &7a ; mask &1e50 0a ASL A &1e51 0a ASL A &1e52 0a ASL A &1e53 0a ASL A &1e54 05 7a ORA &7a ; mask # Convert mask to colour 3 &1e56 85 7a STA &7a ; mask &1e58 a4 76 LDY &76 ; row_in_group &1e5a b1 70 LDA (&70),Y ; screen_address &1e5c 25 7a AND &7a ; mask &1e5e 05 79 ORA &79 ; sprite_pixel_value &1e60 91 70 STA (&70),Y ; screen_address &1e62 c8 INY # Move down a row &1e63 c0 04 CPY #&04 &1e65 d0 13 BNE &1e7a ; not_group &1e67 a0 00 LDY #&00 &1e69 a5 70 LDA &70 ; screen_address_low &1e6b 18 CLC &1e6c 69 40 ADC #&40 # Move down a group &1e6e 85 70 STA &70 ; screen_address_low &1e70 a5 71 LDA &71 ; screen_address_high &1e72 69 01 ADC #&01 &1e74 10 02 BPL &1e78 ; skip_wraparound &1e76 e9 3f SBC #&3f ; skip_wraparound &1e78 85 71 STA &71 ; screen_address_high ; not_group &1e7a 84 76 STY &76 ; row_in_group &1e7c a4 77 LDY &77 ; sprite_offset &1e7e c6 78 DEC &78 ; rows &1e80 d0 b2 BNE &1e34 ; plot_masked_sprite_row_loop &1e82 68 PLA ; screen_address_low &1e83 18 CLC &1e84 69 08 ADC #&08 # Move right four pixels &1e86 85 70 STA &70 ; screen_address_low &1e88 68 PLA ; screen_address_high &1e89 69 00 ADC #&00 &1e8b 10 02 BPL &1e8f ; skip_wraparound &1e8d e9 3f SBC #&3f ; skip_wraparound &1e8f 85 71 STA &71 ; screen_address_high &1e91 a5 72 LDA &72 ; sprite_address_low &1e93 18 CLC &1e94 65 75 ADC &75 ; sprite_height &1e96 85 72 STA &72 ; sprite_address_low &1e98 90 02 BCC &1e9c ; skip_page &1e9a e6 73 INC &73 ; sprite_address_high ; skip_page &1e9c c6 74 DEC &74 ; sprite_width &1e9e d0 80 BNE &1e20 ; plot_masked_sprite_column_loop &1ea0 60 RTS ; plot_sprite &1ea1 a5 71 LDA &71 ; screen_address_high &1ea3 d0 01 BNE &1ea6 ; plot_sprite_column_loop &1ea5 60 RTS ; plot_sprite_column_loop &1ea6 a5 71 LDA &71 ; screen_address_high &1ea8 48 PHA ; screen_address_high &1ea9 a5 70 LDA &70 ; screen_address_low &1eab 48 PHA ; screen_address_low &1eac 29 03 AND #&03 &1eae 85 76 STA &76 ; row_in_group &1eb0 45 70 EOR &70 ; screen_address_low &1eb2 85 70 STA &70 ; screen_address_low &1eb4 a0 00 LDY #&00 &1eb6 a5 75 LDA &75 ; sprite_height &1eb8 85 78 STA &78 ; rows ; plot_sprite_row_loop &1eba b1 72 LDA (&72),Y ; sprite_address &1ebc c8 INY &1ebd 84 77 STY &77 ; sprite_offset &1ebf a4 76 LDY &76 ; row_in_group &1ec1 91 70 STA (&70),Y ; screen_address &1ec3 c8 INY # Move down a row &1ec4 c0 04 CPY #&04 &1ec6 d0 13 BNE &1edb ; not_group &1ec8 a0 00 LDY #&00 &1eca a5 70 LDA &70 ; screen_address_low &1ecc 18 CLC &1ecd 69 40 ADC #&40 # Move down a group &1ecf 85 70 STA &70 ; screen_address_low &1ed1 a5 71 LDA &71 ; screen_address_high &1ed3 69 01 ADC #&01 &1ed5 10 02 BPL &1ed9 ; skip_wraparound &1ed7 e9 3f SBC #&3f ; skip_wraparound &1ed9 85 71 STA &71 ; screen_address_high ; not_group &1edb 84 76 STY &76 ; row_in_group &1edd a4 77 LDY &77 ; sprite_offset &1edf c6 78 DEC &78 ; rows &1ee1 d0 d7 BNE &1eba ; plot_sprite_row_loop &1ee3 68 PLA ; screen_address_low &1ee4 18 CLC &1ee5 69 08 ADC #&08 # Move right four pixels &1ee7 85 70 STA &70 ; screen_address_low &1ee9 68 PLA ; screen_address_high &1eea 69 00 ADC #&00 &1eec 10 02 BPL &1ef0 ; skip_wraparound &1eee e9 3f SBC #&3f ; skip_wraparound &1ef0 85 71 STA &71 ; screen_address_high &1ef2 a5 72 LDA &72 ; sprite_address_low &1ef4 18 CLC &1ef5 65 75 ADC &75 ; sprite_height &1ef7 85 72 STA &72 ; sprite_address_low &1ef9 90 02 BCC &1efd ; skip_page &1efb e6 73 INC &73 ; sprite_address_high ; skip_page &1efd c6 74 DEC &74 ; sprite_width &1eff d0 a5 BNE &1ea6 ; plot_sprite_column_loop &1f01 60 RTS ; update_player_shadow &1f02 20 8e 29 JSR &298e ; to_unplot_player_shadow &1f05 20 83 20 JSR &2083 ; update_missiles &1f08 ae 03 3f LDX &3f03 ; player_x &1f0b a9 90 LDA #&90 # Plot shadow on ground (y = &90) &1f0d 38 SEC &1f0e ed 03 3f SBC &3f03 ; player_x &1f11 a8 TAY &1f12 20 5f 12 JSR &125f ; calculate_screen_address &1f15 a5 70 LDA &70 ; screen_address_low &1f17 48 PHA ; screen_address_low &1f18 8d 06 3f STA &3f06 ; player_shadow_screen_address_low &1f1b a5 71 LDA &71 ; screen_address_high &1f1d 48 PHA ; screen_address_high &1f1e 8d 07 3f STA &3f07 ; player_shadow_screen_address_high &1f21 a9 34 LDA #&34 ; &0634 = player_shadow_buffer &1f23 85 72 STA &72 ; buffer_address_low &1f25 a9 06 LDA #&06 &1f27 85 73 STA &73 ; buffer_address_high &1f29 a9 04 LDA #&04 &1f2b 85 74 STA &74 ; sprite_width &1f2d a9 0d LDA #&0d &1f2f 85 75 STA &75 ; sprite_height &1f31 20 bd 1d JSR &1dbd ; buffer_sprite # Buffer player shadow &1f34 68 PLA ; screen_address_low &1f35 85 71 STA &71 ; screen_address_high &1f37 68 PLA ; screen_address_high &1f38 85 70 STA &70 ; screen_address_low &1f3a a5 7b LDA &7b ; player_sprite_address_low # Use player sprite to generate shadow &1f3c 85 72 STA &72 ; sprite_address_low &1f3e a5 7c LDA &7c ; player_sprite_address_high &1f40 85 73 STA &73 ; sprite_address_high &1f42 a9 04 LDA #&04 &1f44 85 74 STA &74 ; sprite_width &1f46 a9 0d LDA #&0d &1f48 85 75 STA &75 ; sprite_height ; plot_shadow_column_loop &1f4a a5 71 LDA &71 ; screen_address_high &1f4c 48 PHA ; screen_address_high &1f4d a5 70 LDA &70 ; screen_address_low &1f4f 48 PHA ; screen_address_low &1f50 29 03 AND #&03 &1f52 a8 TAY &1f53 45 70 EOR &70 ; screen_address_low &1f55 85 70 STA &70 ; screen_address_low &1f57 a9 00 LDA #&00 &1f59 85 77 STA &77 ; sprite_offset &1f5b a5 75 LDA &75 ; sprite_height &1f5d 85 78 STA &78 ; rows ; plot_shadow_row_loop &1f5f 84 76 STY &76 ; row_in_group &1f61 b1 70 LDA (&70),Y ; screen_address &1f63 85 6e STA &6e ; sprite_pixel_value &1f65 a0 00 LDY #&00 &1f67 84 7a STY &7a ; mask &1f69 a0 04 LDY #&04 ; calculate_clipped_shadow_sprite_pixel_loop &1f6b 38 SEC &1f6c 2c 0d 16 BIT &160d ; #&88 &1f6f f0 01 BEQ &1f72 ; pixel_is_colour_0 &1f71 18 CLC ; pixel_is_colour_0 &1f72 26 7a ROL &7a ; mask &1f74 06 6e ASL &6e ; sprite_pixel_value &1f76 a5 6e LDA &6e ; sprite_pixel_value &1f78 88 DEY &1f79 d0 f0 BNE &1f6b ; calculate_clipped_shadow_sprite_pixel_loop &1f7b a5 7a LDA &7a ; mask &1f7d 0a ASL A &1f7e 0a ASL A &1f7f 0a ASL A &1f80 0a ASL A &1f81 05 7a ORA &7a ; mask # Convert mask to colour 3 &1f83 85 6d STA &6d ; unused # Unused variable &1f85 a4 77 LDY &77 ; sprite_offset &1f87 31 72 AND (&72),Y ; sprite_address # Clip shadow sprite to put beneath other sprites &1f89 c8 INY &1f8a 84 77 STY &77 ; sprite_offset &1f8c a0 00 LDY #&00 &1f8e 84 7a STY &7a ; mask &1f90 a0 04 LDY #&04 # &1f90 - &1fff is identical to &1f90 - &1fff in main binary ; plot_shadow_pixel_loop &1f92 18 CLC &1f93 2c 0d 16 BIT &160d ; #&88 &1f96 d0 01 BNE &1f99 ; pixel_not_colour_0 &1f98 38 SEC # Set bit of mask if pixel is colour 0 ; pixel_not_colour_0 &1f99 26 7a ROL &7a ; mask &1f9b 0a ASL A &1f9c 88 DEY &1f9d d0 f3 BNE &1f92 ; plot_shadow_pixel_loop &1f9f a5 7a LDA &7a ; mask &1fa1 0a ASL A &1fa2 0a ASL A &1fa3 0a ASL A &1fa4 0a ASL A &1fa5 05 7a ORA &7a ; mask # Convert mask to colour 3 &1fa7 85 7a STA &7a ; mask &1fa9 29 f0 AND #&f0 # Convert colour 3 to colour 2 (black) &1fab 49 f0 EOR #&f0 # Invert &1fad 85 79 STA &79 ; shadow &1faf a5 7a LDA &7a ; mask &1fb1 a4 76 LDY &76 ; row_in_group &1fb3 31 70 AND (&70),Y ; screen_address &1fb5 05 79 ORA &79 ; shadow &1fb7 91 70 STA (&70),Y ; screen_address &1fb9 c8 INY # Move down a row &1fba c0 04 CPY #&04 &1fbc d0 13 BNE &1fd1 ; not_group &1fbe a0 00 LDY #&00 &1fc0 a5 70 LDA &70 ; screen_address_low &1fc2 18 CLC &1fc3 69 40 ADC #&40 # Move down a group &1fc5 85 70 STA &70 ; screen_address_low &1fc7 a5 71 LDA &71 ; screen_address_high &1fc9 69 01 ADC #&01 &1fcb 10 02 BPL &1fcf ; skip_wraparound &1fcd e9 3f SBC #&3f ; skip_wraparound &1fcf 85 71 STA &71 ; screen_address_high ; not_group &1fd1 c6 78 DEC &78 ; rows &1fd3 d0 8a BNE &1f5f ; plot_shadow_row_loop &1fd5 68 PLA ; screen_address_low &1fd6 18 CLC &1fd7 69 08 ADC #&08 # Move right four pixels &1fd9 85 70 STA &70 ; screen_address_low &1fdb 68 PLA ; screen_address_high &1fdc 69 00 ADC #&00 &1fde 10 02 BPL &1fe2 ; skip_wraparound &1fe0 e9 3f SBC #&3f ; skip_wraparound &1fe2 85 71 STA &71 ; screen_address_high &1fe4 a5 72 LDA &72 ; sprite_address_low &1fe6 18 CLC &1fe7 65 75 ADC &75 ; sprite_height &1fe9 85 72 STA &72 ; sprite_address_low &1feb 90 02 BCC &1fef ; skip_page &1fed e6 73 INC &73 ; sprite_address_high ; skip_page &1fef c6 74 DEC &74 ; sprite_width &1ff1 d0 01 BNE &1ff4 ; to_plot_shadow_column_loop &1ff3 60 RTS ; to_plot_shadow_column_loop &1ff4 4c 4a 1f JMP &1f4a ; plot_shadow_column_loop ; check_for_player_collision_with_objects &1ff7 a9 00 LDA #&00 &1ff9 85 70 STA &70 ; player_hit_wall &1ffb 85 71 STA &71 ; player_passed_wall &1ffd a2 09 LDX #&09 ; check_for_player_collision_with_objects_loop &1fff 86