Cyborg Warriors disassembly =========================== Cyborg Warriors was written by Tony Oakden, and published by Superior Software for the BBC Micro in 1991. It is a side-scrolling shooter for one or two players. 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 =============== The game uses a double buffered screen. The sprites are stored in a page wide sprite sheet, which can be displayed using the following BASIC program: 10 MODE 5 20 VDU 23;8193;0;0;0;23;8202;0;0;0; 30 *LOAD CYBORG4 3C00 40 GOTO 40 Interesting pokes ================= &15e2 = &a9 infinite lives &15c3 = &10 invulnerability BASIC loader ============ ; CYBLOAD ; 000e00 000e00 000369 &0e00 0d # Start of BASIC program &0e01 00 0a 15 f4 20 28 43 29 20 54 6f 6e 79 20 4f 61 ; 10REM (C) Tony Oakden &0e11 6b 64 65 6e 0d &0e16 00 14 15 f4 20 31 34 74 68 20 4d 61 72 63 68 20 ; 20REM 14th March 1991 &0e26 31 39 39 31 0d &0e2b 00 1e 1b f4 20 46 6f 72 20 53 75 70 65 72 69 6f ; 30REM For Superior Software &0e3b 72 20 53 6f 66 74 77 61 72 65 0d &0e46 00 28 06 eb 35 0d ; 40MODE5 &0e4c 00 32 12 ef 32 33 2c 31 2c 30 3b 30 3b 30 3b 30 ; 50VDU23,1,0;0;0;0 # Turn cursor off &0e5c 3b 0d &0e5e 00 3c 11 ef 31 39 2c 32 2c 36 2c 30 2c 30 2c 30 ; 60VDU19,2,6,0,0,0 # Set colour 2 to cyan &0e6e 0d &0e6f 00 46 11 ef 31 39 2c 33 2c 35 2c 30 2c 30 2c 30 ; 70VDU19,3,5,0,0,0 # Set colour 3 to magenta &0e7f 0d &0e80 00 50 12 2a 46 58 31 37 38 2c 32 35 35 2c 32 35 ; 80*FX178,255,255 # Enable keyboard interrupts &0e90 35 0d &0e92 00 5a 0c 2a 46 58 32 31 34 2c 31 0d ; 90*FX214,1 # Set bell duration to 1 &0e9e 00 64 06 fb 31 0d ; 100COLOUR1 &0ea4 00 78 15 f1 8a 37 2c 31 34 29 3b 22 4c 4f 41 44 ; 120PRINTTAB(7,14);"LOADING" &0eb4 49 4e 47 22 0d &0eb9 00 82 06 fb 32 0d ; 130COLOUR2 &0ebf 00 8c 1d f1 8a 33 2c 31 36 29 3b 22 43 59 42 4f ; 140PRINTTAB(3,16);"CYBORG WARRIORS" &0ecf 52 47 20 57 41 52 52 49 4f 52 53 22 0d &0edc 00 96 06 fb 33 0d ; 150COLOUR3 &0ee2 00 a0 19 f1 8a 35 2c 31 38 29 3b 22 50 4c 45 41 ; 160PRINTTAB(5,18);"PLEASE WAIT" &0ef2 53 45 20 57 41 49 54 22 0d &0efb 00 aa 12 ef 32 38 2c 31 2c 32 38 2c 31 30 2c 32 ; 170VDU28,1,28,10,24 # Define text window &0f0b 34 0d &0f0d 00 be 16 2a 4c 4f 41 44 20 43 59 42 4f 52 47 31 ; 190*LOAD CYBORG1 5F80 # Load loading screen &0f1d 20 35 46 38 30 0d &0f23 00 c8 10 54 25 3d 91 3a 2a 46 58 31 35 2c 30 0d ; 200T%=TIME:*FX15,0 # Flush all buffers &0f33 00 cd 1b f5 20 fd 20 91 3e 54 25 2b 38 30 30 20 ; 205REPEAT UNTIL TIME>T%+800 # Wait for eight seconds &0f43 84 20 a6 20 28 30 29 3e 2d 31 0d OR INKEY (0)>-1 # or keypress &0f4e 00 d2 15 2a 4c 4f 41 44 20 43 59 42 4f 52 47 32 ; 210*LOAD CYBORG2 880 &0f5e 20 38 38 30 0d &0f63 00 dc 15 2a 4c 4f 41 44 20 43 59 42 4f 52 47 33 ; 220*LOAD CYBORG3 100 &0f73 20 31 30 30 0d &0f78 00 e6 2e f4 20 4d 4f 44 49 46 59 20 53 43 52 45 ; 230REM MODIFY SCREEN DISPLAY READY FOR THE GAME &0f88 45 4e 20 44 49 53 50 4c 41 59 20 52 45 41 44 59 &0f98 20 46 4f 52 20 54 48 45 20 47 41 4d 45 0d &0fa6 00 f0 23 ef 32 33 2c 30 2c 38 2c 30 3b 30 3b 30 ; 240VDU23,0,8,0;0;0;0, # R8: Interlace and delay register &0fb6 3b 30 2c 32 33 2c 30 2c 37 2c 32 36 3b 30 3b 30 23,0,7,26;0;0;0 # R7: Vertical sync position &0fc6 3b 30 0d &0fc9 00 fa 3e 3f 26 46 45 30 30 3d 31 32 3a 3f 26 46 ; 250?&FE00=12:?&FE01=&D: # R12: Displayed screen start address register (high) &0fd9 45 30 31 3d 26 44 3a 3f 26 46 45 30 30 3d 31 33 ; ?&FE00=13:?&FE01=&8: # R13: Displayed screen start address register (low) &0fe9 3a 3f 26 46 45 30 31 3d 26 38 3a 3f 26 46 45 30 ; ?&FE00=6:?&FE01=19 # R6: Vertical displayed register &0ff9 30 3d 36 3a 3f 26 46 45 30 31 3d 31 39 0d &1007 01 04 15 2a 4c 4f 41 44 20 54 4f 50 53 54 52 20 ; 260*LOAD TOPSTR 6840 # Load score section &1017 36 38 34 30 0d &101c 01 0e 15 2a 4c 4f 41 44 20 42 4f 54 53 54 52 20 ; 270*LOAD BOTSTR 7C40 # Load status section &102c 37 43 34 30 0d &1031 01 18 29 e2 20 31 2c 31 2c 32 2c 34 2c 38 2c 38 ; 280ENVELOPE 1,1,2,4,8,8,8,8,-10,-1,1,-15,126,50 &1041 2c 38 2c 38 2c 2d 31 30 2c 2d 31 2c 31 2c 2d 31 &1051 35 2c 31 32 36 2c 35 30 0d &105a 01 22 29 e2 20 32 2c 31 2c 36 2c 34 2c 38 2c 38 ; 290ENVELOPE 2,1,6,4,8,8,8,8,-10,-1,1,-15,126,50 &106a 2c 38 2c 38 2c 2d 31 30 2c 2d 31 2c 31 2c 2d 31 &107a 35 2c 31 32 36 2c 35 30 0d &1083 01 2c 2c e2 20 34 2c 33 2c 32 2c 32 2c 2d 32 2c ; 300ENVELOPE 4,3,2,2,-2,1,1,1,122,-10,-5,-2,120,120 &1093 31 2c 31 2c 31 2c 31 32 32 2c 2d 31 30 2c 2d 35 &10a3 2c 2d 32 2c 31 32 30 2c 31 32 30 0d &10af 01 36 2b e2 20 33 2c 31 2c 31 2c 30 2c 2d 31 2c ; 310ENVELOPE 3,1,1,0,-1,4,3,3,126,-3,0,-126,126,60 &10bf 34 2c 33 2c 33 2c 31 32 36 2c 2d 33 2c 30 2c 2d &10cf 31 32 36 2c 31 32 36 2c 36 30 0d &10da 01 40 05 20 0d ; 320 &10df 01 43 14 21 26 33 37 34 20 3d 26 41 32 32 41 30 ; 323!&374 =&A22A008D # Populate toggle_sound_suppressed &10ef 30 38 44 0d &10f3 01 44 14 21 26 33 37 38 20 3d 26 32 32 32 45 32 ; 324!&378 =&222E20AE &1103 30 41 45 0d &1107 01 45 14 21 26 33 37 43 20 3d 26 30 30 36 30 46 ; 325!&37C =&0060F9B0 &1117 39 42 30 0d &111b 01 b8 10 2a 52 55 4e 20 43 59 42 4f 52 47 34 0d ; 440*RUN CYBORG4 # Run main game &112b ff # End of BASIC program ; unused &112c 8d f2 9a 9d f2 9a 8d 12 00 03 f0 10 c5 f1 04 ac &113c f2 1d ac f1 29 c5 f2 04 de f1 29 c5 f2 10 f7 f1 &114c 29 f7 f2 1d de f0 04 de f1 10 c5 12 00 01 f0 11 &115c c5 f1 06 ae f2 10 ae f1 1c c5 f2 10 de Game disassembly ================ ; CYBORG3 ; 000100 000100 0000c0 ; strings ; 0 1 2 3 4 5 6 7 8 9 a b c d e &0100 0f 14 1f 30 39 46 53 60 6f 80 8b 97 a2 aa b6 &010f 20 60 ; &00 @ &6020 &0111 4f 46 46 ; "OFF" &0114 c0 5f ; &01 @ &5fc0 &0116 53 4f 55 4e 44 20 4f 4e 20 ; "SOUND ON " &011f 60 4f ; &02 @ &4f60 &0121 43 59 42 4f 52 47 20 57 41 52 52 49 4f 52 53 ; "CYBORG WARRIORS" &0130 60 53 ; &03 @ &5360 &0132 4f 50 54 49 4f 4e 53 ; "OPTIONS" &0139 00 57 ; &04 @ &5700 &013b 31 3e 20 4b 45 59 42 4f 41 52 44 ; "1> KEYBOARD" &0146 80 59 ; &05 @ &5980 &0148 32 3e 20 4a 4f 59 53 54 49 43 4b ; "2> JOYSTICK" &0153 00 5c ; &06 @ &5c00 &0155 33 3e 20 32 20 50 4c 41 59 45 52 ; "3> 2 PLAYER" &0160 b0 64 ; &07 @ &64b0 &0162 53 50 41 43 45 20 54 4f 20 50 4c 41 59 ; "SPACE TO PLAY" &016f e0 65 ; &08 @ &65e0 &0171 4c 20 54 4f 20 53 4b 49 50 20 4c 45 56 45 4c ; "L TO SKIP LEVEL" &0180 18 5c ; &09 @ &5c18 &0182 47 41 4d 45 20 4f 56 45 52 ; "GAME OVER" &018b 90 4f ; &0a @ &4f90 &018d 48 49 47 48 20 53 43 4f 52 45 ; "HIGH SCORE" &0197 18 75 ; &0b @ &7518 &0199 47 41 4d 45 20 4f 56 45 52 ; "GAME OVER" &01a2 18 5c ; &0c @ &5c18 &01a4 4c 45 56 45 4c 20 ; "LEVEL " &01aa d0 64 ; &0d @ &64d0 &01ac 45 4e 54 45 52 20 4e 41 4d 45 ; "ENTER NAME" ; unused # Unused code &01b6 b5 42 LDA &42,X ; lasers_x &01b8 15 46 ORA &46,X ; lasers_x + 4 &01ba 15 4a ORA &4a,X ; lasers_x + 4 * 2 &01bc f0 0d BEQ &01cb &01be 8a TXA &01bf 18 CLC # &0374 - &037f is set at lines 323 - 325 of CYBLOAD ; toggle_sound_suppressed &0374 8d 00 2a STA &2a00 ; sound_suppressed ; wait_for_s_released &0377 a2 ae LDX #&ae ; S &0379 20 2e 22 JSR &222e ; check_for_keypress &037c b0 f9 BCS &0377 ; wait_for_s_released # Suppress auto-repeat &037e 60 RTS ; CU ; 000400 000400 000400 ; number_sprites &0400 0e 0a a0 a0 a0 aa aa ee ; "0" &0408 04 0c 40 40 40 44 44 ee ; "1" &0410 0e 02 20 e0 e0 88 88 ee ; "2" &0418 0e 02 20 e0 e0 22 22 ee ; "3" &0420 08 08 80 a0 e0 ee 22 22 ; "4" &0428 0e 08 80 e0 e0 22 22 ee ; "5" &0430 0e 08 80 e0 e0 aa aa ee ; "6" &0438 0e 02 20 20 20 22 22 22 ; "7" &0440 0e 0a a0 e0 e0 aa aa ee ; "8" &0448 0e 0a a0 e0 e0 22 22 22 ; "9" ; sprite_fireball_group_0 &0450 00 33 67 cf df 67 33 00 cc 5f af 5f 1f af 4f dd &0460 10 0a 8e 6c 9e 5d aa 01 10 04 6c 88 26 18 02 50 ; sprite_explosion_one_group_0 &0470 00 00 00 00 00 00 00 01 00 00 00 00 00 03 03 6f &0480 00 00 00 00 00 00 00 00 ; mask_explosion_one_group_0 &0488 ff ff ff ff ff ff ff ee ff ff ff ff ff cc cc 00 &0498 ff ff ff ff ff ff ff ff ; sprite_explosion_two_group_0 &04a0 00 00 00 10 10 00 00 01 00 00 00 26 26 8e 8e dd &04b0 00 00 00 04 04 00 00 08 ; mask_explosion_two_group_0 &04b8 ff ff ff ee ee ff ff ee ff ff ff 99 99 00 00 00 &04c8 ff ff ff bb bb ff ff 77 ; sprite_explosion_three_group_0 &04d0 00 00 00 00 00 22 22 00 00 10 10 00 04 04 00 20 &04e0 00 00 00 00 88 88 00 00 ; mask_explosion_three_group_0 &04e8 ff ff ff ff ff dd dd ff ff ee ee ff bb bb ff dd &04f8 ff ff ff ff 77 77 ff ff ; sprite_rocket_group_0 &0500 00 00 00 00 00 00 11 fe 00 00 00 00 00 00 ff f0 &0510 00 00 00 00 11 10 ee f0 00 33 47 8f 0f f0 50 f0 ; mask_rocket_group_0 &0520 ff ff ff ff ff ee 88 00 ff ff ff ff ff 00 00 00 &0530 ff ff ff ee cc 00 00 00 cc 88 00 00 00 00 00 00 ; write_high_score_value &0540 84 73 STY &73 ; offset &0542 be 00 0b LDX &0b00,Y ; high_score_values &0545 a0 00 LDY #&00 ; plot_number_loop &0547 bd 00 04 LDA &0400,X ; number_sprites &054a 91 00 STA (&00),Y ; screen_address &054c e8 INX &054d c8 INY &054e c0 08 CPY #&08 &0550 30 f5 BMI &0547 ; plot_number_loop &0552 98 TYA &0553 18 CLC &0554 65 00 ADC &00 ; screen_address_low &0556 85 00 STA &00 ; screen_address_low &0558 a4 73 LDY &73 ; offset &055a c8 INY &055b c6 7b DEC &7b ; count &055d 10 e1 BPL &0540 ; write_high_score_value &055f a5 00 LDA &00 ; screen_address_low &0561 69 a8 ADC #&a8 &0563 85 00 STA &00 ; screen_address_low &0565 a5 01 LDA &01 ; screen_address_high &0567 69 01 ADC #&01 &0569 85 01 STA &01 ; screen_address_high &056b c6 79 DEC &79 ; rank &056d 60 RTS ; unused &056e 00 00 ; sprite_explosion_one_group_1 &0570 01 01 01 00 00 00 00 01 6f 6a 6a 17 97 99 f9 e8 &0580 00 00 00 88 88 88 88 00 ; mask_explosion_one_group_1 &0588 ee ee ee ff ff ff ff ee 00 11 11 88 00 00 00 11 &0598 ff ff ff 77 77 77 77 ff ; sprite_explosion_two_group_1 &05a0 01 01 01 04 00 00 00 01 dd 49 49 02 54 36 36 7e &05b0 08 88 88 00 0c 0c 04 0c ; mask_explosion_two_group_1 &05b8 ee ee ee bb ff ff ff ee 00 00 00 00 88 88 00 00 &05c8 77 77 77 ff 33 33 33 33 ; sprite_explosion_three_group_1 &05d0 04 04 01 01 80 00 11 15 a8 88 00 00 00 00 00 22 &05e0 00 40 40 00 08 08 04 04 ; mask_explosion_three_group_1 &05e8 bb bb ee ee ff ff ee aa 55 77 ff ff ff ff ff dd &05f8 ff bb bb ff 77 77 bb bb ; sprite_rocket_group_1 &0600 e0 10 00 00 00 00 00 00 70 f0 00 00 00 00 00 00 &0610 f0 e0 10 01 00 00 00 00 f0 50 f0 0f 0f 07 03 00 ; mask_rocket_group_1 &0620 00 88 ee ff ff ff ff ff 00 00 00 ff ff ff ff ff &0630 00 00 00 cc ee ff ff ff 00 00 00 00 00 00 88 cc ; replot_weapon_selector # Called with X = player &0640 b4 9e LDY &9e,X ; players_selected_weapon_screen_offset &0642 a9 00 LDA #&00 &0644 20 5d 06 JSR &065d ; plot_weapon_selector &0647 c8 INY &0648 20 5d 06 JSR &065d ; plot_weapon_selector &064b b5 0e LDA &0e,X ; players_selected_weapon &064d 29 fc AND #&fc &064f 0a ASL A &0650 0a ASL A &0651 7d 6a 06 ADC &066a,X ; weapon_selector_base_screen_offsets &0654 95 9e STA &9e,X ; players_selected_weapon_screen_offset &0656 a8 TAY &0657 a9 ff LDA #&ff &0659 20 5d 06 JSR &065d ; plot_weapon_selector &065c c8 INY ; plot_weapon_selector &065d 99 eb 7e STA &7eeb,Y ; buffer_two + &140 * 18 + 8 * 5 + 3 &0660 99 f3 7e STA &7ef3,Y ; buffer_two + &140 * 18 + 8 * 6 + 3 &0663 99 eb 65 STA &65eb,Y ; buffer_one + &140 * 18 + 8 * 5 + 3 &0666 99 f3 65 STA &65f3,Y ; buffer_one + &140 * 18 + 8 * 6 + 3 &0669 60 RTS ; weapon_selector_base_screen_offsets &066a 00 b0 ; tab_string # Stored backwards &066c 0b 05 1f ; TAB(&05, &0b) ; unused &066f 00 ; sprite_explosion_one_group_2 &0670 01 01 01 00 00 00 00 00 e9 03 4b 62 66 66 66 00 &0680 00 00 00 00 00 00 00 00 ; mask_explosion_one_group_2 &0688 ee ee ee ff ff ff ff ff 00 00 00 99 99 99 99 ff &0698 ff ff ff ff ff ff ff ff ; sprite_explosion_two_group_2 &06a0 01 00 00 00 00 00 00 00 67 4b 4b 71 71 8d 8d 46 &06b0 88 8a 44 44 04 04 00 00 ; mask_explosion_two_group_2 &06b8 ee ff ff ff ff ff ff ff 00 00 00 88 88 00 00 99 &06c8 77 55 bb bb bb bb ff ff ; sprite_explosion_three_group_2 &06d0 04 00 02 82 80 00 00 00 22 00 00 00 00 00 00 04 &06e0 88 88 00 00 88 88 04 04 ; mask_explosion_three_group_2 &06e8 bb ff dd 55 77 ff ff ff dd ff ff ff ff ff ff bb &06f8 77 77 ff ff 77 77 bb bb ; weapon_slot_sprites &0700 80 80 80 80 80 80 80 80 00 10 00 10 00 10 00 10 # Empty slot &0710 80 91 a2 d5 c4 a2 91 80 88 10 00 dc 00 10 00 98 # Multidirectional laser &0720 93 81 80 80 80 80 81 93 08 9c 4e 36 26 5e 8c 18 # Antimatter torpedo &0730 91 a2 91 a2 91 a2 91 80 00 98 4c be 4c 98 00 10 # Smart bomb ; to_write_high_scores &0740 4c 8c 07 JMP &078c ; write_high_scores ; get_name &0743 a2 0d LDX #&0d ; "ENTER NAME" @ &64d0 &0745 a0 00 LDY #&00 &0747 20 6c 22 JSR &226c ; to_plot_string &074a a2 02 LDX #&02 ; write_tab_loop &074c bd 6c 06 LDA &066c,X ; tab_string &074f 20 ee ff JSR &ffee ; OSWRCH # TAB(&05, &0b) &0752 ca DEX &0753 10 f7 BPL &074c ; write_tab_loop &0755 78 SEI &0756 a9 81 LDA #&81 # Enable System VIA CA2 (keyboard) interrupts &0758 8d 4e fe STA &fe4e ; System VIA interrupt enable register &075b 58 CLI &075c a9 0f LDA #&0f ; Flush input buffer &075e a2 01 LDX #&01 &0760 20 f4 ff JSR &fff4 ; OSBYTE &0763 a9 00 LDA #&00 ; Input line of text &0765 a2 87 LDX #&87 ; &0787 = input_block &0767 a0 07 LDY #&07 &0769 20 f1 ff JSR &fff1 ; OSWORD # Returns Y = length of input ; pad_name_loop &076c a9 20 LDA #&20 ; " " &076e 99 b2 03 STA &03b2,Y ; name &0771 c8 INY &0772 c0 08 CPY #&08 &0774 30 f6 BMI &076c ; pad_name_loop &0776 a0 00 LDY #&00 &0778 a6 76 LDX &76 ; high_score_offset ; copy_name_loop &077a b9 b2 03 LDA &03b2,Y ; name &077d 9d 80 08 STA &0880,X ; high_score_names &0780 e8 INX &0781 c8 INY &0782 c0 08 CPY #&08 &0784 30 f4 BMI &077a ; copy_name_loop &0786 60 RTS ; input_block &0787 b2 03 ; &03b2 = name &0789 08 ; 8 characters maximum &078a 20 ; " " &0789 80 ; write_high_scores &078c a9 f0 LDA #&f0 ; &51f0 = buffer_one + &140 * 2 + 8 * 6 &078e 85 00 STA &00 ; screen_address_low &0790 a9 51 LDA #&51 &0792 85 01 STA &01 ; screen_address_high &0794 a9 06 LDA #&06 &0796 85 79 STA &79 ; rank ; write_high_scores_loop &0798 a5 79 LDA &79 ; rank &079a 0a ASL A &079b 0a ASL A &079c 0a ASL A &079d 48 PHA &079e aa TAX &079f a9 07 LDA #&07 &07a1 85 7b STA &7b ; count ; write_name_loop &07a3 bd 80 08 LDA &0880,X ; high_score_names &07a6 86 75 STX &75 ; offset &07a8 20 72 22 JSR &2272 ; plot_character &07ab a6 75 LDX &75 ; offset &07ad e8 INX &07ae c6 7b DEC &7b ; count &07b0 10 f1 BPL &07a3 ; write_name_loop &07b2 a5 00 LDA &00 ; screen_address_low &07b4 18 CLC &07b5 69 20 ADC #&20 # Sixteen pixel gap between names and scores &07b7 85 00 STA &00 ; screen_address_low &07b9 90 02 BCC &07bd ; skip_page &07bb e6 01 INC &01 ; screen_address_high ; skip_page &07bd 68 PLA &07be a8 TAY &07bf a9 06 LDA #&06 &07c1 85 7b STA &7b ; count &07c3 20 40 05 JSR &0540 ; write_high_score_value # Returns sign of rank &07c6 10 d0 BPL &0798 ; write_high_scores_loop &07c8 60 RTS ; unused &07c9 00 00 00 00 00 00 00 ; sprite_explosion_three_group_3 &07d0 44 44 00 00 04 04 00 00 04 00 00 00 00 04 04 04 &07e0 80 80 00 00 08 08 00 00 ; mask_explosion_three_group_3 &07e8 bb bb ff ff bb bb ff ff bb ff ff ff ff bb bb bb &07f8 77 77 ff ff 77 77 ff ff ; CYBORG2 ; 000880 000880 000380 ; high_score_names &0880 52 20 48 61 6e 73 6f 6e ; "R Hanson" &0888 20 4a 65 6d 69 6d 61 20 ; " Jemima " &0890 44 20 53 75 6d 6d 65 72 ; "D Summer" &0898 48 20 48 69 6b 69 6e 69 ; "H Hikini" &08a0 4a 6f 65 42 6c 61 64 65 ; "JoeBlade" &08a8 57 20 44 6f 62 73 6f 6e ; "W Dobson" &08b0 54 20 4f 61 6b 64 65 6e ; "T Oakden" ; unused &08b8 00 00 00 00 00 00 00 00 ; OS envelope storage area &08c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &08f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # &08c0 - &08ff is set at lines 280 - 310 of CYBLOAD ; envelope_1 # Standard laser #08c0 01 02 04 08 08 08 08 f6 ff 01 f1 7e 32 00 00 00 ; envelope_2 # Multidirectional laser #08d0 01 06 04 08 08 08 08 f6 ff 01 f1 7e 32 00 00 00 ; envelope_3 # Explosion #08e0 01 01 00 ff 04 03 03 7e fd 00 82 7e 3c 00 00 00 ; envelope_4 # Torpedo, bonus #08f0 03 02 02 fe 01 01 01 7a f6 fb fe 78 78 00 00 00 ; movement_patterns ; 0 1 2 3 4 5 6 7 8 9 a b c d e f &0900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; &00 &0910 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ; &01 &0920 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ; &02 &0930 00 00 ff ff ff ff fe fe fe fe ff ff ff ff 00 00 ; &03 &0940 00 00 01 01 01 01 02 02 02 02 01 01 01 01 00 00 ; &04 &0950 02 02 01 01 01 01 00 00 00 00 ff ff ff ff fe fe ; &05 &0960 fe fe ff ff ff ff 00 00 00 00 01 01 01 01 02 02 ; &06 &0970 00 00 01 01 01 01 01 01 02 02 02 02 03 03 03 03 ; &07 &0980 fd fd fd fd fe fe fe fe ff ff ff ff ff ff 00 00 ; &08 &0990 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 ; &09 &09a0 fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe ; &0a &09b0 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ; &0b &09c0 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ; &0c &09d0 ff ff ff ff ff ff ff ff 01 01 01 01 01 01 01 01 ; &0d &09e0 01 01 01 01 01 01 01 01 ff ff ff ff ff ff ff ff ; &0e &09f0 ff 00 ff 00 ff 00 ff 00 01 00 01 00 01 00 01 00 ; &0f &0a00 01 00 01 00 01 00 01 00 ff 00 ff 00 ff 00 ff 00 ; &10 &0a10 ff 00 00 00 ff 00 00 00 ff 00 00 00 ff 00 00 00 ; &11 &0a20 03 02 00 00 00 00 00 00 00 00 00 00 00 00 fe fd ; &12 &0a30 ff ff fe 00 00 00 00 00 00 00 00 00 00 02 01 01 ; &13 &0a40 00 fe fe ff ff ff ff 00 00 00 00 00 01 00 01 00 ; &14 &0a50 00 00 00 00 00 00 00 00 00 00 00 00 02 02 02 02 ; &15 &0a60 fe fe fe fe fe fe fe fe fe fe 00 00 00 00 00 00 ; &16 &0a70 02 02 02 02 02 02 02 02 02 02 00 00 00 00 00 00 ; &17 ; unused &0a80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0a90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0aa0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ab0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ac0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ad0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0ae0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &0af0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; high_score_values &0b00 00 00 00 10 28 00 00 00 ; 0002500 &0b08 00 00 00 28 00 00 00 00 ; 0005000 &0b10 00 00 08 00 00 00 00 00 ; 0010000 &0b18 00 00 28 28 00 00 00 00 ; 0055000 &0b20 00 08 00 00 00 00 00 00 ; 0100000 &0b28 00 28 00 00 00 00 00 00 ; 0500000 &0b30 08 00 00 00 00 00 00 00 ; 1000000 ; check_for_high_score &0b38 a9 00 LDA #&00 &0b3a a2 82 LDX #&82 ; players_score ; check_for_high_score_player_loop &0b3c 85 9c STA &9c ; player &0b3e 8e 4f 0b STX &0b4f ; score_to_check &0b41 8e 99 0b STX &0b99 ; score_to_copy &0b44 a9 00 LDA #&00 ; check_for_high_score_rank_loop &0b46 85 79 STA &79 ; rank &0b48 0a ASL A &0b49 0a ASL A &0b4a 0a ASL A &0b4b aa TAX &0b4c a0 00 LDY #&00 ; check_for_high_score_digit_loop &0b4e b9 82 00 LDA &0082,Y ; players_score # actually LDA score_to_check,Y &0b51 dd 00 0b CMP &0b00,X ; high_score_values &0b54 30 66 BMI &0bbc ; is_lower &0b56 f0 02 BEQ &0b5a ; consider_next_digit &0b58 10 06 BPL &0b60 ; consider_higher_rank # Always branches ; consider_next_digit &0b5a e8 INX &0b5b c8 INY &0b5c c0 07 CPY #&07 &0b5e 30 ee BMI &0b4e ; check_for_high_score_digit_loop ; consider_higher_rank &0b60 e6 79 INC &79 ; rank &0b62 a5 79 LDA &79 ; rank &0b64 c9 07 CMP #&07 &0b66 30 de BMI &0b46 ; check_for_high_score_rank_loop ; add_new_high_score &0b68 a9 01 LDA #&01 ; shuffle_scores_rank_loop &0b6a 85 7b STA &7b ; rank_to_shuffle &0b6c c5 79 CMP &79 ; rank &0b6e f0 1c BEQ &0b8c ; skip_shuffling_scores &0b70 0a ASL A &0b71 0a ASL A &0b72 0a ASL A &0b73 aa TAX &0b74 a0 07 LDY #&07 ; shuffle_scores_digit_loop &0b76 bd 00 0b LDA &0b00,X ; high_score_values &0b79 9d f8 0a STA &0af8,X ; high_score_values - 8 &0b7c bd 80 08 LDA &0880,X ; high_score_names &0b7f 9d 78 08 STA &0878,X ; high_score_names - 8 &0b82 e8 INX &0b83 88 DEY &0b84 10 f0 BPL &0b76 ; shuffle_scores_digit_loop &0b86 e6 7b INC &7b ; rank_to_shuffle &0b88 a5 7b LDA &7b ; rank_to_shuffle &0b8a d0 de BNE &0b6a ; shuffle_scores_rank_loop ; skip_shuffling_scores &0b8c c6 7b DEC &7b ; rank_to_shuffle &0b8e a5 7b LDA &7b ; rank_to_shuffle &0b90 0a ASL A &0b91 0a ASL A &0b92 0a ASL A &0b93 85 76 STA &76 ; high_score_offset &0b95 a0 00 LDY #&00 &0b97 aa TAX ; copy_high_score_loop &0b98 b9 82 00 LDA &0082,Y ; players_score # actually LDA score_to_copy,Y &0b9b 9d 00 0b STA &0b00,X ; high_score_values &0b9e a9 2e LDA #&2e ; "." &0ba0 9d 80 08 STA &0880,X ; high_score_names &0ba3 e8 INX &0ba4 c8 INY &0ba5 c0 08 CPY #&08 &0ba7 30 ef BMI &0b98 ; copy_high_score_loop &0ba9 20 a6 22 JSR &22a6 ; to_plot_high_score_screen &0bac 20 43 07 JSR &0743 ; get_name &0baf e6 7a INC &7a ; unused # Unnecessary code ; consider_next_player &0bb1 a2 89 LDX #&89 ; player_two_score &0bb3 e6 9c INC &9c ; player &0bb5 a5 9c LDA &9c ; player &0bb7 c9 02 CMP #&02 &0bb9 d0 81 BNE &0b3c ; check_for_high_score_player_loop &0bbb 60 RTS ; is_lower &0bbc a5 79 LDA &79 ; rank &0bbe d0 a8 BNE &0b68 ; add_new_high_score &0bc0 f0 ef BEQ &0bb1 ; consider_next_player ; play_explosion_sound &0bc2 a9 03 LDA #&03 # Use envelope 3 for explosion ; play_sound_with_envelope &0bc4 a2 10 LDX #&10 # Use channel 0 &0bc6 8e 0e 22 STX &220e ; explosion_and_firing_sound (channel) &0bc9 a2 05 LDX #&05 &0bcb a0 00 LDY #&00 ; play_sound_with_envelope_pitch_and_duration &0bcd 8d 10 22 STA &2210 ; explosion_and_firing_sound + 2 (volume) &0bd0 8c 12 22 STY &2212 ; explosion_and_firing_sound + 4 (pitch) &0bd3 8e 14 22 STX &2214 ; explosion_and_firing_sound + 6 (duration) &0bd6 a2 0e LDX #&0e ; &220e = explosion_and_firing_sound ; play_sound &0bd8 a0 22 LDY #&22 &0bda ad 00 2a LDA &2a00 ; sound_suppressed &0bdd d0 05 BNE &0be4 ; skip_sound &0bdf a9 07 LDA #&07 ; Generate a sound &0be1 20 f1 ff JSR &fff1 ; OSWORD ; skip_sound &0be4 a4 73 LDY &73 ; tmp_y &0be6 a6 74 LDX &74 ; tmp_x &0be8 60 RTS ; play_bonus_sound &0be9 a2 16 LDX #&16 ; &2216 = bonus_sound &0beb d0 eb BNE &0bd8 ; play_sound # Always branches ; level_waves_data_addresses_low_table ; 0 1 2 3 4 5 6 7 &0bed 00 24 48 6c 90 b4 d8 fc ; Weapons ; ======= ; damage turns between uses ; &00 standard laser 2 4 ; &04 multidirectional laser 2 4 ; &08 antimatter torpedo 32 20 ; &0c smart bomb * 20 (destroys up to one enemy per frame for ten frames) ; weapon_damages ; 0 4 8 c &0bf5 02 02 20 28 ; weapon_cooldowns ; 0 4 8 c &0bf9 04 04 14 14 ; unused &0bfd 10 ; previous_irq1_vector_low &0bfe 10 ; previous_irq1_vector_high &0bff 10 ; CYBORG4 ; 001200 001200 003c00 ; entry_point &1200 a2 1e LDX #&1e ; &221e = load_cu_string # *LOAD CU &1202 a0 22 LDY #&22 &1204 20 f7 ff JSR &fff7 ; OSCLI &1207 a9 8c LDA #&8c ; Select tape filing system &1209 20 f4 ff JSR &fff4 ; OSBYTE &120c a9 1a LDA #&1a ; Restore default windows &120e 20 ee ff JSR &ffee ; OSWRCH &1211 78 SEI &1212 a9 7f LDA #&7f &1214 8d 6e fe STA &fe6e ; User VIA interrupt enable register # Disable all User VIA interrupts &1217 8d 4e fe STA &fe4e ; System VIA interrupt enable register # Disable all System VIA interrupts &121a a9 c2 LDA #&c2 # Enable System VIA Timer 1 and CA1 (v-sync) interrupts &121c 8d 4e fe STA &fe4e ; System VIA interrupt enable register &121f a9 a0 LDA #&a0 # Enable User VIA Timer 2 interrupts &1221 8d 6e fe STA &fe6e ; User VIA interrupt enable register &1224 85 c4 STA &c4 ; palette_state # Set to non-zero to set top of screen colours next &1226 ad 04 02 LDA &0204 ; irq1_vector_low &1229 8d fe 0b STA &0bfe ; previous_irq1_vector_low &122c ad 05 02 LDA &0205 ; irq1_vector_high &122f 8d ff 0b STA &0bff ; previous_irq1_vector_high &1232 a9 e2 LDA #&e2 ; &1ae2 = irq1_handler &1234 8d 04 02 STA &0204 ; irq1_vector_low &1237 a9 1a LDA #&1a &1239 8d 05 02 STA &0205 ; irq1_vector_high &123c 58 CLI &123d a2 16 LDX #&16 &123f a9 00 LDA #&00 &1241 a8 TAY ; wipe_4f00_to_64ff_loop # Wipe &4f00 - &64ff (most of buffer one) &1242 99 00 4f STA &4f00,Y # actually STA wipe_address,Y &1245 88 DEY &1246 d0 fa BNE &1242 ; wipe_4f00_to_64ff_loop &1248 ee 44 12 INC &1244 ; wipe_address_high &124b ca DEX &124c d0 f4 BNE &1242 ; wipe_4f00_to_64ff_loop &124e a2 9f LDX #&9f ; wipe_0001_to_009f_loop # Wipe &0001 - &009f (variables) &1250 95 00 STA &00,X &1252 ca DEX &1253 d0 fb BNE &1250 ; wipe_0001_to_009f_loop &1255 ca DEX ; &ff &1256 9a TXS # Reset stack pointer ; start_new_game &1257 a9 02 LDA #&02 # Use magenta for colour 3 &1259 85 96 STA &96 ; colour_scheme &125b 20 69 22 JSR &2269 ; to_title_screen_after_checking_for_high_score &125e a9 00 LDA #&00 &1260 a2 9a LDX #&9a ; wipe_game_variables_loop # Wipe &0001 - &009a (variables) &1262 95 00 STA &00,X &1264 ca DEX &1265 d0 fb BNE &1262 ; wipe_game_variables_loop &1267 a8 TAY &1268 20 a7 21 JSR &21a7 ; plot_weapon_slots &126b a0 01 LDY #&01 &126d 20 a7 21 JSR &21a7 ; plot_weapon_slots &1270 a2 01 LDX #&01 # For each player, ; replot_weapon_selectors_loop &1272 20 40 06 JSR &0640 ; replot_weapon_selector # replot weapon selector &1275 ca DEX &1276 10 fa BPL &1272 ; replot_weapon_selectors_loop ; start_new_level &1278 a5 9b LDA &9b ; level_number &127a 29 07 AND #&07 &127c aa TAX &127d bd ed 0b LDA &0bed,X ; level_waves_data_addresses_low_table &1280 8d 81 16 STA &1681 ; level_waves_data_address_low &1283 20 6f 22 JSR &226f ; to_reset_screen_for_new_level &1286 20 72 1b JSR &1b72 ; prepare_shifted_horizon_sprites # Leaves with A = 0 &1289 a2 05 LDX #&05 # Set to non-zero to use buffer two &128b 86 94 STX &94 ; buffer_to_use &128d a2 47 LDX #&47 ; wipe_progress_bar &128f 9d 00 7e STA &7e00,X ; buffer_two + &140 * 17 + 8 * 16 &1292 9d 00 65 STA &6500,X ; buffer_one + &140 * 17 + 8 * 16 &1295 ca DEX &1296 10 f7 BPL &128f ; wipe_progress_bar &1298 85 70 STA &70 ; frame_counter &129a 85 71 STA &71 ; level_position &129c 85 90 STA &90 ; next_enemy_to_add &129e 85 c2 STA &c2 ; players_bonuses_collected &12a0 85 c3 STA &c3 ; player_two_bonuses &12a2 a2 30 LDX #&30 ; remove_lasers_loop &12a4 95 42 STA &42,X ; lasers_x &12a6 ca DEX &12a7 10 fb BPL &12a4 ; remove_lasers_loop &12a9 85 04 STA &04 ; players_firing_intent # Set to zero to indicate not wanting to fire &12ab 85 05 STA &05 ; players_firing_intent + 1 &12ad 20 ab 1f JSR &1fab ; remove_player_one &12b0 20 be 1f JSR &1fbe ; remove_player_two &12b3 20 9e 17 JSR &179e ; plot_lives ; plot_level_number &12b6 a5 9b LDA &9b ; level_number &12b8 0a ASL A &12b9 0a ASL A &12ba 0a ASL A &12bb 69 08 ADC #&08 &12bd 8d c3 12 STA &12c3 ; level_number_sprite_address_low &12c0 a0 07 LDY #&07 ; plot_level_number_loop &12c2 b9 90 04 LDA &0490,Y ; number_sprites + &90 # actually LDA level_number_sprite_address,Y &12c5 99 f0 7d STA &7df0,Y ; buffer_two + &140 * 17 + 8 * 14 &12c8 99 f0 64 STA &64f0,Y ; buffer_one + &140 * 17 + 8 * 14 &12cb 88 DEY &12cc 10 f4 BPL &12c2 ; plot_level_number_loop &12ce a2 04 LDX #&04 ; SPRITE_PLAYER_TWO &12d0 86 29 STX &29 ; players_or_enemies_type + 1 # Player two uses slot 1 &12d2 e8 INX &12d3 a9 00 LDA #&00 ; SPRITE_PLAYER_ONE &12d5 85 28 STA &28 ; players_or_enemies_type # Player one uses slot 0 ; remove_enemies_loop &12d7 95 12 STA &12,X ; player_or_enemies_x + 2 # Set to zero to indicate no enemy in slot &12d9 ca DEX &12da 10 fb BPL &12d7 ; remove_enemies_loop ; main_game_loop &12dc a5 9b LDA &9b ; level_number &12de 29 07 AND #&07 &12e0 85 96 STA &96 ; colour_scheme &12e2 78 SEI &12e3 a9 21 LDA #&21 # Disable System VIA CA2 (keyboard) and Timer 2 interrupts &12e5 8d 4e fe STA &fe4e ; System VIA interrupt enable register &12e8 58 CLI &12e9 a2 96 LDX #&96 ; COPY &12eb 20 2e 22 JSR &222e ; check_for_keypress &12ee 90 0e BCC &12fe ; copy_not_pressed # If COPY pressed, ; delete_not_pressed &12f0 a2 8f LDX #&8f ; ESCAPE &12f2 20 2e 22 JSR &222e ; check_for_keypress &12f5 b0 1d BCS &1314 ; to_start_new_game # End game if ESCAPE pressed &12f7 a2 a6 LDX #&a6 ; DELETE &12f9 20 2e 22 JSR &222e ; check_for_keypress &12fc 90 f2 BCC &12f0 ; delete_not_pressed # Pause until DELETE pressed ; copy_not_pressed &12fe a5 99 LDA &99 ; game_over_timer &1300 f0 3e BEQ &1340 ; update_game # Zero if game not over &1302 a0 ff LDY #&ff &1304 a2 09 LDX #&09 ; "GAME OVER" @ &5c18 # Plot "GAME OVER" in buffer one &1306 20 6c 22 JSR &226c ; to_plot_string &1309 a0 ff LDY #&ff &130b a2 0b LDX #&0b ; "GAME OVER" @ &7518 # Plot "GAME OVER" in buffer two &130d 20 6c 22 JSR &226c ; to_plot_string &1310 c6 99 DEC &99 ; game_over_timer &1312 d0 72 BNE &1386 ; skip_updating_firing_cooldowns ; to_start_new_game &1314 4c 57 12 JMP &1257 ; start_new_game ; finish_smart_bomb # Also called when boss is destroyed &1317 a9 00 LDA #&00 &1319 85 72 STA &72 ; smart_bomb_or_boss_active # Set to zero to indicate no boss or smart bomb active &131b 85 93 STA &93 ; group_of_enemies_added # Set to zero to indicate no group of enemies (boss) &131d a5 71 LDA &71 ; level_position &131f c9 23 CMP #&23 # Is the player at the end of the level? &1321 d0 53 BNE &1376 ; skip_updating_smart_bomb # (i.e. has destroyed the boss) ; level_completed &1323 a9 64 LDA #&64 &1325 85 71 STA &71 ; count ; level_completed_loop &1327 a2 01 LDX #&01 ; move_players_right_loop &1329 b5 9c LDA &9c,X ; players_lives &132b f0 02 BEQ &132f ; skip_moving_player_right &132d f6 10 INC &10,X ; players_or_enemies_x # If so, move active players right &132f ca DEX ; skip_moving_player_right &1330 10 f7 BPL &1329 ; move_players_right_loop &1332 e6 70 INC &70 ; frame_counter &1334 20 21 17 JSR &1721 ; replot_screen &1337 c6 71 DEC &71 ; count &1339 10 ec BPL &1327 ; level_completed_loop &133b e6 9b INC &9b ; level_number &133d 4c 78 12 JMP &1278 ; start_new_level ; update_game &1340 a5 9c LDA &9c ; players_lives &1342 05 9d ORA &9d ; players_lives + 1 &1344 d0 04 BNE &134a ; game_not_over # If both player one and player two have no lives, &1346 a9 60 LDA #&60 &1348 85 99 STA &99 ; game_over_timer # Display "GAME OVER" for 96 frames ; game_not_over &134a a5 72 LDA &72 ; smart_bomb_or_boss_active &134c 10 28 BPL &1376 ; skip_updating_smart_bomb # Negative if smart bomb active or boss is exploding &134e e6 c5 INC &c5 ; smart_bomb_timer &1350 a5 c5 LDA &c5 ; smart_bomb_timer &1352 c9 0b CMP #&0b &1354 10 c1 BPL &1317 ; finish_smart_bomb &1356 4a LSR A # Destroy an enemy every two frames &1357 a8 TAY &1358 a5 c5 LDA &c5 ; smart_bomb_timer &135a 18 CLC &135b 69 08 ADC #&08 ; smart_bomb_colours - level_colours &135d 85 96 STA &96 ; colour_scheme &135f b9 22 00 LDA &0022,Y ; players_or_enemies_energy + 2 &1362 84 75 STY &75 ; sprite_to_update &1364 30 46 BMI &13ac ; consider_updating_player_one # Don't explode enemy if enemy is already exploding &1366 a5 9c LDA &9c ; players_lives &1368 f0 03 BEQ &136d ; skip_exploding_enemy_by_player_one # If player one is alive, &136a 20 c9 1e JSR &1ec9 ; explode_enemy # Explode enemy and score for player one ; skip_exploding_enemy_by_player_one &136d a5 9d LDA &9d ; players_lives + 1 &136f f0 05 BEQ &1376 ; skip_exploding_enemy_by_player_two # If player two is alive, &1371 a4 75 LDY &75 ; sprite_to_update &1373 20 d1 1e JSR &1ed1 ; explode_enemy_by_player_two # Explode enemy and score for player two ; skip_exploding_enemy_by_player_two ; skip_updating_smart_bomb &1376 c6 02 DEC &02 ; players_firing_cooldown &1378 10 04 BPL &137e ; skip_floor_one &137a a9 00 LDA #&00 &137c 85 02 STA &02 ; players_firing_cooldown ; skip_floor_one &137e c6 03 DEC &03 ; players_firing_cooldown + 1 &1380 10 04 BPL &1386 ; skip_floor_two &1382 a9 00 LDA #&00 &1384 85 03 STA &03 ; players_firing_cooldown + 1 ; skip_floor_two ; skip_updating_firing_cooldowns &1386 e6 70 INC &70 ; frame_counter &1388 f0 06 BEQ &1390 ; update_level_position &138a a5 70 LDA &70 ; frame_counter &138c 29 3f AND #&3f &138e d0 1c BNE &13ac ; consider_updating_player_one # Every 64 frames, update level position ; update_level_position &1390 a5 71 LDA &71 ; level_position &1392 c9 23 CMP #&23 &1394 f0 16 BEQ &13ac ; consider_updating_player_one # Don't update level position at boss &1396 e6 71 INC &71 ; level_position &1398 29 07 AND #&07 &139a c9 07 CMP #&07 &139c d0 0e BNE &13ac ; consider_updating_player_one # Every 8 positions, consider adding bonuses &139e a9 01 LDA #&01 &13a0 a6 9c LDX &9c ; players_lives &13a2 f0 02 BEQ &13a6 ; skip_player_one_bonus # Don't add bonus for player one if player one is dead &13a4 85 97 STA &97 ; player_one_due_bonus # Set to non-zero to create bonus when possible ; skip_player_one_bonus &13a6 a6 9d LDX &9d ; players_lives + 1 &13a8 f0 02 BEQ &13ac ; skip_player_two_bonus # Don't add bonus for player two if player two is dead &13aa 85 98 STA &98 ; player_two_due_bonus # Set to non-zero to create bonus when possible ; skip_player_two_bonus ; consider_updating_player_one &13ac a5 9c LDA &9c ; players_lives &13ae f0 08 BEQ &13b8 ; to_update_player_two # Don't update player one if player one is dead &13b0 a5 30 LDA &30 ; players_or_enemies_timer &13b2 10 07 BPL &13bb ; update_player_one # Negative if player one is moving onto screen &13b4 e6 10 INC &10 ; players_or_enemies_x &13b6 c6 30 DEC &30 ; players_or_enemies_timer ; to_consider_updating_player_two &13b8 4c 11 14 JMP &1411 ; consider_updating_player_two ; update_player_one &13bb c6 30 DEC &30 ; players_or_enemies_timer &13bd 10 04 BPL &13c3 ; skip_floor &13bf a9 00 LDA #&00 &13c1 85 30 STA &30 ; players_or_enemies_timer ; skip_floor &13c3 a9 00 LDA #&00 # Set to zero to indicate not able to change weapon &13c5 85 73 STA &73 ; player_in_position_to_change_weapon ; check_if_left_pressed &13c7 a2 ff LDX #&ff ; SHIFT &13c9 20 2e 22 JSR &222e ; check_for_keypress &13cc 90 0c BCC &13da ; check_if_right_pressed # If SHIFT pressed, &13ce a5 10 LDA &10 ; players_or_enemies_x &13d0 c9 1c CMP #&1c # If player one is at the left of the screen, &13d2 d0 04 BNE &13d8 ; move_player_one_left &13d4 c6 73 DEC &73 ; player_in_position_to_change_weapon # Set to non-zero to indicate able to change weapon &13d6 d0 02 BNE &13da ; check_if_right_pressed # Always branches ; move_player_one_left &13d8 c6 10 DEC &10 ; players_or_enemies_x # Otherwise move player one left ; check_if_right_pressed &13da a5 10 LDA &10 ; players_or_enemies_x &13dc c9 5c CMP #&5c # If player one isn't at the right of the screen, &13de f0 09 BEQ &13e9 ; check_if_up_pressed &13e0 a2 9e LDX #&9e ; Z &13e2 20 2e 22 JSR &222e ; check_for_keypress &13e5 90 02 BCC &13e9 ; check_if_up_pressed # If Z pressed, &13e7 e6 10 INC &10 ; players_or_enemies_x # Move player one right ; check_if_up_pressed &13e9 a2 b7 LDX #&b7 ; * &13eb 20 2e 22 JSR &222e ; check_for_keypress &13ee 90 08 BCC &13f8 ; check_if_down_pressed # If * pressed, &13f0 a5 18 LDA &18 ; players_or_enemies_y &13f2 c9 02 CMP #&02 # If player one isn't at the top of the screen, &13f4 f0 02 BEQ &13f8 ; check_if_down_pressed &13f6 c6 18 DEC &18 ; players_or_enemies_y # Move player one up ; check_if_down_pressed &13f8 a2 97 LDX #&97 ; / &13fa 20 2e 22 JSR &222e ; check_for_keypress &13fd 90 08 BCC &1407 ; check_if_space_pressed # If / pressed, &13ff a5 18 LDA &18 ; players_or_enemies_y &1401 c9 18 CMP #&18 # If player bottom isn't at the top of the screen, &1403 f0 02 BEQ &1407 ; check_if_space_pressed &1405 e6 18 INC &18 ; players_or_enemies_y # Move player one down ; check_if_space_pressed &1407 a2 9d LDX #&9d ; SPACE &1409 20 2e 22 JSR &222e ; check_for_keypress &140c a2 00 LDX #&00 &140e 20 56 17 JSR &1756 ; consider_firing_or_changing_weapon ; consider_updating_player_two &1411 a5 9d LDA &9d ; players_lives + 1 # Don't update player two if player two is dead &1413 f0 08 BEQ &141d ; to_update_enemies_and_check_for_collisions &1415 a5 31 LDA &31 ; players_or_enemies_timer + 1 &1417 10 07 BPL &1420 ; update_player_two # Negative if player two is moving onto screen &1419 e6 11 INC &11 ; players_or_enemies_x + 1 &141b c6 31 DEC &31 ; players_or_enemies_timer + 1 ; to_update_enemies_and_check_for_collisions &141d 4c 88 14 JMP &1488 ; update_enemies_and_check_for_collisions ; update_player_two &1420 c6 31 DEC &31 ; players_or_enemies_timer + 1 &1422 10 04 BPL &1428 ; skip_floor &1424 a9 00 LDA #&00 &1426 85 31 STA &31 ; players_or_enemies_timer + 1 ; skip_floor &1428 a2 00 LDX #&00 # Set to zero to indicate not able to change weapon &142a 86 73 STX &73 ; player_in_position_to_change_weapon &142c e8 INX ; 1 &142d a9 80 LDA #&80 ; Read I/O device or buffer status &142f 20 f4 ff JSR &fff4 ; OSBYTE # Read analogue channel 1 (joystick x) &1432 98 TYA &1433 29 c0 AND #&c0 &1435 f0 13 BEQ &144a ; consider_moving_player_two_right &1437 c9 c0 CMP #&c0 &1439 d0 17 BNE &1452 ; check_joystick_vertically # If the joystick is to the left, &143b a5 11 LDA &11 ; players_or_enemies_x + 1 &143d c9 1c CMP #&1c # If player two is at the left of the screen, &143f d0 04 BNE &1445 ; move_player_two_left &1441 c6 73 DEC &73 ; player_in_position_to_change_weapon # Set to non-zero to indicate able to change weapon &1443 d0 0d BNE &1452 ; check_joystick_vertically # Always branches ; move_player_two_left &1445 c6 11 DEC &11 ; players_or_enemies_x + 1 # Otherwise move player two left &1447 4c 52 14 JMP &1452 ; check_joystick_vertically ; consider_moving_player_two_right # If the joystick is to the right, &144a a5 11 LDA &11 ; players_or_enemies_x + 1 &144c c9 5c CMP #&5c # If player two isn't at the right of the screen, &144e f0 02 BEQ &1452 ; check_joystick_vertically &1450 e6 11 INC &11 ; players_or_enemies_x + 1 # Move player two right ; check_joystick_vertically &1452 a2 02 LDX #&02 &1454 a9 80 LDA #&80 ; Read I/O device or buffer status &1456 20 f4 ff JSR &fff4 ; OSBYTE # Read analogue channel 2 (joystick y) &1459 98 TYA &145a 29 c0 AND #&c0 &145c f0 0f BEQ &146d ; consider_moving_player_two_down &145e c9 c0 CMP #&c0 &1460 d0 13 BNE &1475 ; check_joystick_fire # If the joystick is up, &1462 a5 19 LDA &19 ; players_or_enemies_y + 1 &1464 c9 02 CMP #&02 # If player two isn't at the top of the screen, &1466 f0 0d BEQ &1475 ; check_joystick_fire &1468 c6 19 DEC &19 ; players_or_enemies_y + 1 # Move player two up &146a 4c 75 14 JMP &1475 ; check_joystick_fire ; consider_moving_player_two_down # If the joystick is down, &146d a5 19 LDA &19 ; players_or_enemies_y + 1 &146f c9 18 CMP #&18 # If player two isn't at the bottom of the screen, &1471 f0 02 BEQ &1475 ; check_joystick_fire &1473 e6 19 INC &19 ; players_or_enemies_y + 1 # Move player two down ; check_joystick_fire &1475 a2 00 LDX #&00 &1477 a9 80 LDA #&80 ; Read I/O device or buffer status &1479 20 f4 ff JSR &fff4 ; OSBYTE # Read joystick buttons &147c 8a TXA &147d 29 03 AND #&03 &147f 18 CLC # Clear carry to indicate fire not pressed &1480 f0 01 BEQ &1483 ; fire_not_pressed &1482 38 SEC # Set carry to indicate fire pressed ; fire_not_pressed &1483 a2 01 LDX #&01 &1485 20 56 17 JSR &1756 ; consider_firing_or_changing_weapon ; update_enemies_and_check_for_collisions &1488 a5 10 LDA &10 ; players_or_enemies_x &148a 18 CLC &148b 69 05 ADC #&05 &148d 85 75 STA &75 ; player_one_maximum_x &148f a5 18 LDA &18 ; players_or_enemies_y &1491 69 07 ADC #&07 &1493 85 76 STA &76 ; player_one_maximum_y &1495 a5 11 LDA &11 ; players_or_enemies_x + 1 &1497 69 05 ADC #&05 &1499 85 77 STA &77 ; player_two_maximum_x &149b a5 19 LDA &19 ; players_or_enemies_y + 1 &149d 69 07 ADC #&07 &149f 85 78 STA &78 ; player_two_maximum_y &14a1 a2 05 LDX #&05 ; update_enemies_and_check_for_collisions_loop &14a3 b5 12 LDA &12,X ; player_or_enemies_x + 2 &14a5 d0 09 BNE &14b0 ; update_enemy # Non-zero if enemy is present ; to_consider_next_enemy &14a7 4c ec 15 JMP &15ec ; consider_next_enemy ; set_enemy_y &14aa 38 SEC &14ab f1 08 SBC (&08),Y ; y_pattern_table_address_low &14ad 4c 0b 15 JMP &150b ; after_applying_delta ; update_enemy &14b0 b5 22 LDA &22,X ; players_or_enemies_energy + 2 &14b2 30 f3 BMI &14a7 ; to_consider_next_enemy # Negative if enemy is exploding &14b4 f6 32 INC &32,X ; players_or_enemies_timer + 2 &14b6 b5 32 LDA &32,X ; players_or_enemies_timer + 2 &14b8 29 7f AND #&7f &14ba 4a LSR A &14bb 4a LSR A &14bc 4a LSR A &14bd 4a LSR A &14be 85 73 STA &73 ; movement_frame &14c0 b4 2a LDY &2a,X ; players_or_enemies_type + 2 &14c2 b9 01 25 LDA &2501,Y ; sprite_sizes_and_data + 1 &14c5 4a LSR A &14c6 4a LSR A &14c7 4a LSR A &14c8 85 95 STA &95 ; enemy_width &14ca b5 2a LDA &2a,X ; players_or_enemies_type + 2 &14cc 4a LSR A &14cd 4a LSR A &14ce a8 TAY &14cf b9 00 2a LDA &2a00,Y ; enemy_pattern_types - 5 &14d2 05 92 ORA &92 ; current_wave_type &14d4 85 74 STA &74 ; movement_flags &14d6 b9 00 2a LDA &2a00,Y ; enemy_pattern_types - 5 &14d9 0a ASL A &14da 0a ASL A &14db 0a ASL A &14dc 18 CLC &14dd 65 73 ADC &73 ; movement_frame &14df a8 TAY &14e0 b9 80 2c LDA &2c80,Y ; patterns_for_horizontal_movement &14e3 0a ASL A &14e4 0a ASL A &14e5 0a ASL A &14e6 0a ASL A &14e7 85 00 STA &00 ; x_pattern_table_address_low &14e9 a9 00 LDA #&00 &14eb 69 09 ADC #&09 ; &0900 = movement_patterns &14ed 85 01 STA &01 ; x_pattern_table_address_high &14ef b9 00 2b LDA &2b00,Y ; patterns_for_vertical_movement &14f2 0a ASL A &14f3 0a ASL A &14f4 0a ASL A &14f5 0a ASL A &14f6 85 08 STA &08 ; y_pattern_table_address_low &14f8 a9 09 LDA #&09 ; &0900 = movement_patterns &14fa 69 00 ADC #&00 &14fc 85 09 STA &09 ; y_pattern_table_address_high &14fe b5 32 LDA &32,X ; players_or_enemies_timer + 2 &1500 29 0f AND #&0f &1502 a8 TAY &1503 b5 1a LDA &1a,X ; players_or_enemies_y + 2 &1505 24 74 BIT &74 ; movement_flags &1507 30 a1 BMI &14aa ; apply_inverse_vertical_movement # If &80 set, subtract vertical movement &1509 71 08 ADC (&08),Y ; y_pattern_table_address # If &80 clear, add vertical movement ; set_enemy_y &150b 95 1a STA &1a,X ; players_or_enemies_y + 2 &150d c9 02 CMP #&02 &150f 10 0e BPL &151f ; not_off_top_of_screen # Remove enemy if enemy is beyond top of screen ; remove_enemy &1511 a9 00 LDA #&00 # Set to zero to remove enemy &1513 95 12 STA &12,X ; player_or_enemies_x + 2 &1515 e0 05 CPX #&05 &1517 f0 42 BEQ &155b ; check_for_collision_with_player_two &1519 85 72 STA &72 ; smart_bomb_or_boss_active # Set to zero to indicate no boss or smart bomb active &151b 85 93 STA &93 ; group_of_enemies_added # Set to zero to indicate no group of enemies (boss) &151d d0 3c BNE &155b ; check_for_collision_with_player_two ; not_off_top_of_screen &151f c9 1d CMP #&1d &1521 10 ee BPL &1511 ; remove_enemy # Remove enemy if enemy if beyond bottom of screen &1523 b5 12 LDA &12,X ; player_or_enemies_x + 2 &1525 24 74 BIT &74 ; movement_flags &1527 50 02 BVC &152b ; skip_applying_horizontal_movement # If &40 clear, don't add horizontal movement &1529 71 00 ADC (&00),Y ; x_pattern_table_address ; skip_applying_horizontal_movement &152b 18 CLC &152c 71 00 ADC (&00),Y ; x_pattern_table_address &152e f0 e1 BEQ &1511 ; remove_enemy # Remove enemy if enemy is beyond left of screen &1530 30 df BMI &1511 ; remove_enemy # Remove enemy if enemy is beyond left of screen &1532 95 12 STA &12,X ; player_or_enemies_x + 2 ; check_for_collision_with_player_one &1534 c5 75 CMP &75 ; player_one_maximum_x &1536 10 23 BPL &155b ; check_for_collision_with_player_two &1538 18 CLC &1539 65 95 ADC &95 ; enemy_width &153b c5 10 CMP &10 ; players_or_enemies_x &153d 30 1c BMI &155b ; check_for_collision_with_player_two &153f b5 1a LDA &1a,X ; players_or_enemies_y + 2 &1541 c5 76 CMP &76 ; player_one_maximum_y &1543 10 16 BPL &155b ; check_for_collision_with_player_two &1545 18 CLC &1546 75 3a ADC &3a,X ; enemies_height &1548 e9 01 SBC #&01 &154a c5 18 CMP &18 ; players_or_enemies_y &154c 30 0d BMI &155b ; check_for_collision_with_player_two ; player_one_collided &154e b5 2a LDA &2a,X ; players_or_enemies_type + 2 &1550 c9 24 CMP #&24 ; BONUS_PLAYER_TWO &1552 f0 07 BEQ &155b ; check_for_collision_with_player_two # Player one can't collect bonus for player two &1554 a0 00 LDY #&00 &1556 c9 20 CMP #&20 ; BONUS_PLAYER_ONE &1558 4c 84 15 JMP &1584 ; player_collided ; check_for_collision_with_player_two &155b 20 48 22 JSR &2248 ; consider_spawning_enemies &155e b5 12 LDA &12,X ; player_or_enemies_x + 2 &1560 c5 77 CMP &77 ; player_two_maximum_x &1562 10 0b BPL &156f ; consider_next_enemy_if_positive &1564 18 CLC &1565 65 95 ADC &95 ; enemy_width &1567 c5 11 CMP &11 ; players_or_enemies_x + 1 &1569 30 0d BMI &1578 ; consider_next_enemy_if_negative &156b b5 1a LDA &1a,X ; players_or_enemies_y + 2 &156d c5 78 CMP &78 ; player_two_maximum_y ; consider_next_enemy_if_positive &156f 10 7b BPL &15ec ; consider_next_enemy &1571 18 CLC &1572 75 3a ADC &3a,X ; enemies_height &1574 e9 01 SBC #&01 &1576 c5 19 CMP &19 ; players_or_enemies_y + 1 ; consider_next_enemy_if_negative &1578 30 72 BMI &15ec ; consider_next_enemy ; player_two_collided &157a a0 01 LDY #&01 &157c b5 2a LDA &2a,X ; players_or_enemies_type + 2 &157e c9 20 CMP #&20 ; BONUS_PLAYER_ONE &1580 f0 6a BEQ &15ec ; consider_next_enemy # Player two can't collect bonus for player one &1582 c9 24 CMP #&24 ; BONUS_PLAYER_TWO ; player_collided &1584 d0 3a BNE &15c0 ; player_collided_with_enemy ; player_collided_with_bonus &1586 b9 9c 00 LDA &009c,Y ; players_lives &1589 f0 61 BEQ &15ec ; consider_next_enemy &158b a9 00 LDA #&00 # Set to zero to remove bonus &158d 95 12 STA &12,X ; player_or_enemies_x + 2 &158f 86 78 STX &78 ; tmp_x &1591 98 TYA &1592 aa TAX &1593 f6 c2 INC &c2,X ; players_bonuses_collected &1595 b5 c2 LDA &c2,X ; players_bonuses_collected &1597 c9 02 CMP #&02 &1599 d0 0e BNE &15a9 ; not_extra_life_bonus ; extra_life_bonus &159b b5 9c LDA &9c,X ; players_lives &159d c9 0a CMP #&0a &159f f0 53 BEQ &15f4 ; score_bonus # Score 400 for collecting life bonus with 10 lives &15a1 f6 9c INC &9c,X ; players_lives &15a3 20 9e 17 JSR &179e ; plot_lives &15a6 4c b8 15 JMP &15b8 ; play_bonus_sound_and_consider_next_enemy ; not_extra_life_bonus &15a9 c9 03 CMP #&03 &15ab d0 47 BNE &15f4 ; score_bonus ; extra_weapon_bonus &15ad b5 c6 LDA &c6,X ; players_maximum_weapon &15af c9 03 CMP #&03 &15b1 f0 41 BEQ &15f4 ; score_bonus # Score 600 for collecting weapons bonus with all weapons &15b3 f6 c6 INC &c6,X ; players_maximum_weapon &15b5 20 a7 21 JSR &21a7 ; plot_weapon_slots ; play_bonus_sound_and_consider_next_enemy &15b8 20 e9 0b JSR &0be9 ; play_bonus_sound &15bb a6 78 LDX &78 ; tmp_x &15bd 4c ec 15 JMP &15ec ; consider_next_enemy ; player_collided_with_enemy &15c0 b9 9c 00 LDA &009c,Y ; players_lives &15c3 f0 27 BEQ &15ec ; consider_next_enemy &15c5 b9 30 00 LDA &0030,Y ; players_or_enemies_timer &15c8 30 22 BMI &15ec ; consider_next_enemy # Negative if player is moving onto screen &15ca c9 5a CMP #&5a &15cc 10 1e BPL &15ec ; consider_next_enemy # Player is invulnerable at start of new life &15ce a5 72 LDA &72 ; smart_bomb_or_boss_active # Zero if no boss or smart bomb active &15d0 d0 04 BNE &15d6 ; skip_killing_enemy # i.e. don't destroy part of boss on collision &15d2 a9 ff LDA #&ff &15d4 95 22 STA &22,X ; players_or_enemies_energy + 2 # Set to negative to indicate enemy is exploding ; skip_killing_enemy &15d6 a9 ff LDA #&ff &15d8 99 20 00 STA &0020,Y ; players_or_enemies_energy # Set to negative to indicate player is exploding &15db 99 30 00 STA &0030,Y ; players_or_enemies_timer # Set player moving onto screen &15de 86 73 STX &73 ; tmp_x &15e0 98 TYA &15e1 aa TAX &15e2 d6 9c DEC &9c,X ; players_lives &15e4 20 c2 0b JSR &0bc2 ; play_explosion_sound &15e7 a6 73 LDX &73 ; tmp_x &15e9 20 9e 17 JSR &179e ; plot_lives ; consider_next_enemy &15ec ca DEX &15ed 30 15 BMI &1604 ; update_status &15ef 4c a3 14 JMP &14a3 ; update_enemies_and_check_for_collisions_loop ; bonus_score_offsets ; p1 p2 &15f2 04 0b # Score x100 ; score_bonus &15f4 b9 c2 00 LDA &00c2,Y ; players_bonuses_collected # Score 200 or 800 for collecting score bonuses &15f7 0a ASL A &15f8 0a ASL A &15f9 0a ASL A &15fa 0a ASL A &15fb be f2 15 LDX &15f2,Y ; bonus_score_offsets &15fe 20 4b 22 JSR &224b ; increase_score &1601 4c b8 15 JMP &15b8 ; play_bonus_sound_and_consider_next_enemy ; update_status &1604 a5 70 LDA &70 ; frame_counter &1606 29 02 AND #&02 &1608 f0 34 BEQ &163e ; update_status_on_frames_0_and_1 ; update_status_on_frames_2_and_3 &160a a0 37 LDY #&37 &160c a2 06 LDX #&06 &160e 86 7b STX &7b ; score_length &1610 a5 70 LDA &70 ; frame_counter &1612 29 01 AND #&01 &1614 f0 04 BEQ &161a ; plot_score # Replot player one score on frame 2 ; plot_player_two_score # Replot player two score on frame 3 &1616 a0 af LDY #&af &1618 a2 0d LDX #&0d ; plot_score ; plot_score_digit_loop &161a b5 82 LDA &82,X ; players_score &161c 86 79 STX &79 ; score_offset &161e 8d 24 16 STA &1624 ; score_number_sprite_address_low &1621 a2 07 LDX #&07 ; plot_score_sprite_loop &1623 bd 00 04 LDA &0400,X ; number_sprites # actually LDA score_number_sprite_address,X &1626 99 88 68 STA &6888,Y ; buffer_two + 8 * 9 &1629 99 88 4f STA &4f88,Y ; buffer_one + 8 * 9 &162c 88 DEY &162d ca DEX &162e 10 f3 BPL &1623 ; plot_score_sprite_loop &1630 a6 79 LDX &79 ; score_offset &1632 ca DEX &1633 c6 7b DEC &7b ; score_length &1635 10 e3 BPL &161a ; plot_score_digit_loop &1637 4c 1b 17 JMP &171b ; to_replot_screen_and_main_game_loop ; next_enemy_cooldowns ; 0 1 2 3 &163a 00 01 03 05 ; update_status_on_frames_0_and_1 &163e a5 70 LDA &70 ; frame_counter &1640 29 01 AND #&01 &1641 f0 03 BEQ &1647 ; consider_adding_bonuses # Add bonuses and enemies on frame 0 &1644 4c 01 17 JMP &1701 ; update_progress_bar # Replot progress bar on frame 1 ; consider_adding_bonuses &1647 a5 97 LDA &97 ; player_one_due_bonus &1649 f0 0b BEQ &1656 ; skip_adding_player_one_bonus # Non-zero if bonus is due &164b a0 20 LDY #&20 ; BONUS_PLAYER_ONE &164d 20 eb 17 JSR &17eb ; add_enemy # Returns carry set if enemy added &1650 90 04 BCC &1656 ; skip_adding_player_one_bonus &1652 a9 00 LDA #&00 # Set to zero to suppress adding bonus &1654 85 97 STA &97 ; player_one_due_bonus ; skip_adding_player_one_bonus &1656 a5 98 LDA &98 ; player_two_due_bonus &1658 f0 0b BEQ &1665 ; skip_adding_player_two_bonus # Non-zero if bonus is due &165a a0 24 LDY #&24 &165c 20 eb 17 JSR &17eb ; add_enemy # Returns carry set if enemy added &165f 90 04 BCC &1665 ; skip_adding_player_two_bonus &1661 a9 00 LDA #&00 # Set to zero to suppress adding bonus &1663 85 98 STA &98 ; player_two_due_bonus ; skip_adding_player_two_bonus &1665 a5 70 LDA &70 ; frame_counter &1667 29 3f AND #&3f &1669 d0 06 BNE &1671 ; consider_adding_new_enemy # Is this the start of a new wave? &166b a5 72 LDA &72 ; smart_bomb_or_boss_active # Non-zero if boss or smart bomb active &166d d0 02 BNE &1671 ; consider_adding_new_enemy &166f 85 90 STA &90 ; next_enemy_to_add # Start adding enemies for the new wave ; consider_adding_new_enemy &1671 a5 90 LDA &90 ; next_enemy_to_add &1673 c9 06 CMP #&06 # Have all the enemies for this wave been added? &1675 f0 04 BEQ &167b ; to_to_replot_screen_and_main_game_loop &1677 c6 91 DEC &91 ; next_enemy_cooldown &1679 30 03 BMI &167e ; add_next_enemy # If not, is it time to add the next enemy? ; to_to_replot_screen_and_main_game_loop &167b 4c 1b 17 JMP &171b ; to_replot_screen_and_main_game_loop ; add_next_enemy &167e a6 71 LDX &71 ; level_position &1680 bd 00 26 LDA &2600,X ; level_waves_data # actually LDA level_waves_data_address,X &1683 85 76 STA &76 ; wave_type # Get wave type from on position in level &1685 0a ASL A &1686 0a ASL A &1687 0a ASL A &1688 85 00 STA &00 ; wave_data_address_low &168a a9 28 LDA #&28 ; &2800 = wave_data &168c 69 00 ADC #&00 &168e 85 01 STA &01 ; wave_data_address_high &1690 a0 06 LDY #&06 &1692 b1 00 LDA (&00),Y ; wave_data_address # Seventh byte of wave data sets flags for wave &1694 85 75 STA &75 ; wave_flags &1696 c8 INY &1697 b1 00 LDA (&00),Y ; wave_data_address # Eighth byte of wave data is non-zero for grouped boss &1699 85 77 STA &77 ; wave_group &169b a4 90 LDY &90 ; next_enemy_to_add &169d b1 00 LDA (&00),Y ; wave_data_address # First six bytes of wave data set enemy types and delay &169f 85 73 STA &73 ; byte_for_enemy &16a1 0a ASL A &16a2 0a ASL A &16a3 18 CLC &16a4 69 14 ADC #&14 ; SPRITE_FIRST_ENEMY &16a6 a8 TAY # Low six bits of enemy byte set enemy type &16a7 a5 73 LDA &73 ; byte_for_enemy &16a9 4a LSR A &16aa 4a LSR A &16ab 4a LSR A &16ac 4a LSR A &16ad 4a LSR A &16ae 4a LSR A # Top two bits of enemy byte set delay until next enemy &16af aa TAX &16b0 bd 3a 16 LDA &163a,X ; next_enemy_cooldowns &16b3 85 91 STA &91 ; next_enemy_cooldown &16b5 a5 90 LDA &90 ; next_enemy_to_add &16b7 d0 2e BNE &16e7 ; not_start_of_wave &16b9 a5 75 LDA &75 ; wave_flags &16bb 10 26 BPL &16e3 ; consider_adding_enemy_in_empty_slot # If top bit of flags set, &16bd a5 12 LDA &12 ; player_or_enemies_x + 2 # all enemies in wave must be destroyed &16bf 05 13 ORA &13 ; player_or_enemies_x + 3 &16c1 05 14 ORA &14 ; player_or_enemies_x + 4 &16c3 05 15 ORA &15 ; player_or_enemies_x + 5 &16c5 05 16 ORA &16 ; player_or_enemies_x + 6 &16c7 05 17 ORA &17 ; player_or_enemies_x + 7 &16c9 d0 50 BNE &171b ; to_replot_screen_and_main_game_loop # Have all the enemies been destroyed? &16cb a5 76 LDA &76 ; wave_type &16cd 85 92 STA &92 ; current_wave_type &16cf a5 75 LDA &75 ; wave_flags &16d1 29 02 AND #&02 # If &02 set, treat enemies as group (boss) &16d3 f0 16 BEQ &16eb ; add_next_enemy &16d5 24 72 BIT &72 ; smart_bomb_or_boss_active # Negative if smart bomb active &16d7 30 42 BMI &171b ; to_replot_screen_and_main_game_loop &16d9 a5 77 LDA &77 ; wave_group &16db 85 93 STA &93 ; group_of_enemies_added &16dd a9 01 LDA #&01 &16df 85 72 STA &72 ; smart_bomb_or_boss_active # Set to one to indicate boss present &16e1 d0 08 BNE &16eb ; add_next_enemy # Always branches ; consider_adding_enemy_in_empty_slot &16e3 a5 76 LDA &76 ; wave_type &16e5 85 92 STA &92 ; current_wave_type ; not_start_of_wave &16e7 a5 93 LDA &93 ; group_of_enemies_added # Non-zero if group of enemies already added &16e9 d0 05 BNE &16f0 ; skip_adding_enemy ; add_next_enemy &16eb 20 c6 17 JSR &17c6 ; add_enemy_or_group_of_enemies # Returns carry set if enemy added &16ee 90 2b BCC &171b ; to_replot_screen_and_main_game_loop ; skip_adding_enemy &16f0 e6 90 INC &90 ; next_enemy_to_add &16f2 a5 90 LDA &90 ; next_enemy_to_add &16f4 c9 06 CMP #&06 &16f6 d0 06 BNE &16fe ; to_consider_adding_new_enemy &16f8 a5 75 LDA &75 ; wave_flags &16fa d0 1f BNE &171b ; to_replot_screen_and_main_game_loop # If zero, add new enemies when old enemies destroyed &16fc 85 90 STA &90 ; next_enemy_to_add ; to_consider_adding_new_enemy &16fe 4c 71 16 JMP &1671 ; consider_adding_new_enemy ; update_progress_bar &1701 a5 71 LDA &71 ; level_position &1703 29 fc AND #&fc &1705 0a ASL A &1706 a8 TAY &1707 a5 71 LDA &71 ; level_position &1709 29 03 AND #&03 &170b aa TAX &170c bd 9a 17 LDA &179a,X ; progress_bar_pixel_values &170f a2 05 LDX #&05 ; plot_end_of_progress_bar_loop &1711 99 01 7e STA &7e01,Y ; buffer_two + &140 * 17 + 8 * 16 + 1 &1714 99 01 65 STA &6501,Y ; buffer_one + &140 * 17 + 8 * 16 + 1 &1717 c8 INY &1718 ca DEX &1719 10 f6 BPL &1711 ; plot_end_of_progress_bar_loop ; to_replot_screen_and_main_game_loop &171b 20 21 17 JSR &1721 ; replot_screen &171e 4c dc 12 JMP &12dc ; main_game_loop ; replot_screen &1721 20 4d 18 JSR &184d ; replot_background &1724 20 d4 1b JSR &1bd4 ; plot_sprites &1727 a9 01 LDA #&01 # Set to non-zero to wait for next v-sync &1729 85 77 STA &77 ; vsync_pending ; wait_for_vsync &172b a5 77 LDA &77 ; vsync_pending &172d d0 fc BNE &172b ; wait_for_vsync &172f a2 0d LDX #&0d # R13: Displayed screen start address register (low) &1731 8e 00 fe STX &fe00 ; video register number &1734 a5 70 LDA &70 ; frame_counter &1736 29 01 AND #&01 &1738 f0 14 BEQ &174e ; use_buffer_one ; use_buffer_two &173a a0 08 LDY #&08 # Set screen start address to &6840 (buffer_two) &173c a9 0d LDA #&0d &173e a2 00 LDX #&00 ; set_screen_start_address &1740 8c 01 fe STY &fe01 ; video register value &1743 86 94 STX &94 ; buffer_to_use # Zero if buffer two, non-zero if buffer one &1745 a2 0c LDX #&0c # R12: Displayed screen start address register (high) &1747 8e 00 fe STX &fe00 ; video register number &174a 8d 01 fe STA &fe01 ; video register value &174d 60 RTS ; use_buffer_one &174e a0 e8 LDY #&e8 # Set screen start address to &4f40 (buffer_one) &1750 a9 09 LDA #&09 &1752 d0 ec BNE &1740 ; set_screen_start_address # Always branches ; player_laser_offsets &1754 00 18 ; consider_firing_or_changing_weapon # Called with X = player &1756 90 3d BCC &1795 ; skip_firing &1758 a5 73 LDA &73 ; player_in_position_to_change_weapon # Zero if player is not in a position to change weapon &175a 35 38 AND &38,X ; players_suppress_weapon_change # Zero if change of weapon is suppressed &175c f0 2d BEQ &178b ; set_firing_intent ; change_weapon &175e a9 00 LDA #&00 &1760 bc 54 17 LDY &1754,X ; player_laser_offsets &1763 99 42 00 STA &0042,Y ; lasers_x # Set to zero to remove lasers &1766 99 46 00 STA &0046,Y ; lasers_x + 4 &1769 99 4a 00 STA &004a,Y ; lasers_x + 4 * 2 &176c 99 4e 00 STA &004e,Y ; lasers_x + 4 * 3 &176f 99 52 00 STA &0052,Y ; lasers_x + 4 * 4 &1772 99 56 00 STA &0056,Y ; lasers_x + 4 * 5 &1775 f6 0e INC &0e,X ; players_selected_weapon &1777 b5 c6 LDA &c6,X ; players_maximum_weapon &1779 0a ASL A &177a 0a ASL A &177b 69 03 ADC #&03 &177d d5 0e CMP &0e,X ; players_selected_weapon &177f 10 04 BPL &1785 ; skip_wraparound &1781 a9 00 LDA #&00 ; WEAPON_STANDARD &1783 95 0e STA &0e,X ; players_selected_weapon ; skip_wraparound &1785 20 40 06 JSR &0640 ; replot_weapon_selector &1788 4c 95 17 JMP &1795 ; set_firing ; set_firing_intent &178b a9 01 LDA #&01 # Set to non-zero to indicate wanting to fire &178d 95 04 STA &04,X ; players_firing_intent &178f a9 00 LDA #&00 # Set to zero to suppress change of weapon &1791 95 38 STA &38,X ; players_suppress_weapon_change &1793 f0 04 BEQ &1799 ; leave # Always branches ; set_firing &1795 a9 01 LDA #&01 # Set to non-zero to allow change of weapon &1797 95 38 STA &38,X ; players_suppress_weapon_change ; leave &1799 60 RTS ; progress_bar_pixel_values &179a 88 cc ee ff ; plot_lives &179e a5 9c LDA &9c ; players_lives &17a0 0a ASL A &17a1 0a ASL A &17a2 0a ASL A &17a3 8d b1 17 STA &17b1 ; player_one_lives_sprite_address_low &17a6 a5 9d LDA &9d ; players_lives + 1 &17a8 0a ASL A &17a9 0a ASL A &17aa 0a ASL A &17ab 8d ba 17 STA &17ba ; player_two_lives_sprite_address_low &17ae a0 07 LDY #&07 ; plot_lives_loop &17b0 b9 00 04 LDA &0400,Y ; number_sprites # actually LDA player_one_lives_sprite_address,Y &17b3 99 a0 7d STA &7da0,Y ; buffer_two + &140 * 17 + 8 * 4 # Plot player one lives &17b6 99 a0 64 STA &64a0,Y ; buffer_one + &140 * 17 + 8 * 4 &17b9 b9 00 04 LDA &0400,Y ; number_sprites # actually LDA player_two_lives_sprite_address,Y &17bc 99 b8 7e STA &7eb8,Y ; buffer_two + &140 * 17 + 8 * 39 # Plot player two lives &17bf 99 b8 65 STA &65b8,Y ; buffer_one + &140 * 17 + 8 * 39 &17c2 88 DEY &17c3 10 eb BPL &17b0 ; plot_lives_loop &17c5 60 RTS ; add_enemy_or_group_of_enemies &17c6 a2 05 LDX #&05 &17c8 a5 93 LDA &93 ; group_of_enemies_added # Non-zero if the wave is a group of enemies (boss) &17ca f0 1f BEQ &17eb ; add_enemy ; add_group_of_enemies_loop &17cc 8a TXA &17cd a8 TAY &17ce b1 00 LDA (&00),Y ; wave_data_address # Get byte for enemy &17d0 0a ASL A &17d1 0a ASL A &17d2 18 CLC &17d3 69 14 ADC #&14 ; SPRITE_FIRST_ENEMY &17d5 85 73 STA &73 ; enemy_sprite # Low six bits of enemy byte set enemy type &17d7 8a TXA &17d8 a0 07 LDY #&07 &17da 71 00 ADC (&00),Y ; wave_data_address # Add group base to enemy offset &17dc a8 TAY &17dd f0 08 BEQ &17e7 ; consider_adding_next_enemy_in_group # Don't add enemy if enemy is empty type &17df b9 5a 27 LDA &275a,Y ; grouped_enemies_x_positions - 6 &17e2 a4 73 LDY &73 ; enemy_sprite &17e4 20 fc 17 JSR &17fc ; add_enemy_to_slot_X_at_x_position_A ; consider_adding_next_enemy_in_group &17e7 ca DEX &17e8 10 e2 BPL &17cc ; add_group_of_enemies_loop &17ea 60 RTS ; add_enemy # Called with Y = enemy type &17eb a2 05 LDX #&05 ; find_empty_enemy_slot_loop &17ed b5 12 LDA &12,X ; player_or_enemies_x + 2 # Zero if no enemy in slot &17ef f0 09 BEQ &17fa ; add_enemy_to_slot &17f1 ca DEX &17f2 10 f9 BPL &17ed ; find_empty_enemy_slot_loop &17f4 18 CLC # Leave with carry clear to indicate unable to add enemy &17f5 60 RTS ; use_low_bits &17f6 a9 05 LDA #&05 &17f8 d0 19 BNE &1813 ; add_low_bits # Always branches ; add_enemy_to_slot &17fa a9 6a LDA #&6a # Add enemy at right of screen ; add_enemy_to_slot_X_at_x_position_A &17fc c0 00 CPY #&00 &17fe f0 47 BEQ &1847 ; leave_with_carry_set # Leave with carry set if enemy is empty type &1800 95 12 STA &12,X ; player_or_enemies_x + 2 &1802 94 2a STY &2a,X ; players_or_enemies_type + 2 &1804 b9 02 25 LDA &2502,Y ; sprite_sizes_and_data + 2 # Third byte of table sets y position of enemy &1807 f0 ed BEQ &17f6 ; use_low_bits # If zero, use low bits of frame counter &1809 10 12 BPL &181d ; consider_inversion # If positive, use value as absolute position ; use_high_and_low_bits &180b a5 70 LDA &70 ; frame_counter # If negative, use high and low bits of frame counter &180d 4a LSR A &180e 4a LSR A &180f 4a LSR A &1810 4a LSR A &1811 29 07 AND #&07 ; add_low_bits &1813 85 74 STA &74 ; tmp &1815 a5 70 LDA &70 ; frame_counter &1817 29 0f AND #&0f &1819 65 74 ADC &74 ; tmp &181b 69 04 ADC #&04 ; consider_inversion &181d 24 92 BIT &92 ; current_wave_type # If top bit of wave type set, invert vertical position &181f 10 07 BPL &1828 ; set_enemy_y &1821 85 73 STA &73 ; tmp &1823 38 SEC &1824 a9 1e LDA #&1e # Subtract from bottom of screen &1826 e5 73 SBC &73 ; tmp ; set_enemy_y &1828 95 1a STA &1a,X ; players_or_enemies_y + 2 &182a b9 03 25 LDA &2503,Y ; sprite_sizes_and_data + 3 # Low seven bits of fourth byte set enemy energy &182d 29 7f AND #&7f &182f 95 22 STA &22,X ; players_or_enemies_energy + 2 &1831 b9 00 25 LDA &2500,Y ; sprite_sizes_and_data # Low two bits of first byte set enemy height &1834 29 03 AND #&03 &1836 18 CLC &1837 69 01 ADC #&01 &1839 0a ASL A &183a 95 3a STA &3a,X ; enemies_height &183c b9 00 25 LDA &2500,Y ; sprite_sizes_and_data # Next three lowest bits set type of enemy spawned &183f 29 1c AND #&1c &1841 95 7c STA &7c,X ; enemies_spawn_type &1843 a9 00 LDA #&00 &1845 95 32 STA &32,X ; players_or_enemies_timer + 2 ; leave_with_carry_set &1847 38 SEC # Leave with carry set to indicate enemy added &1848 60 RTS ; shifted_horizon_addresses_high &1849 40 0e 10 0c ; plot_background &184d a5 94 LDA &94 ; buffer_to_use # Zero for buffer one, non-zero for buffer two &184f d0 03 BNE &1854 ; plot_background_in_buffer_two &1851 4c 55 19 JMP &1955 ; plot_background_in_buffer_one ; plot_background_in_buffer_two &1854 a2 00 LDX #&00 ; plot_left_sky_in_buffer_two_loop &1856 a9 00 LDA #&00 ; 0000 # Plot left sky &1858 9d 88 69 STA &6988,X ; buffer_two + &140 * 1 + 8 * 1 &185b 9d c8 6a STA &6ac8,X ; buffer_two + &140 * 2 + 8 * 1 &185e 9d 08 6c STA &6c08,X ; buffer_two + &140 * 3 + 8 * 1 &1861 9d 48 6d STA &6d48,X ; buffer_two + &140 * 4 + 8 * 1 &1864 9d 88 6e STA &6e88,X ; buffer_two + &140 * 5 + 8 * 1 &1867 9d c8 6f STA &6fc8,X ; buffer_two + &140 * 6 + 8 * 1 &186a 9d 08 71 STA &7108,X ; buffer_two + &140 * 7 + 8 * 1 &186d a9 ff LDA #&ff ; 3333 # Plot left distant ground &186f 9d c8 74 STA &74c8,X ; buffer_two + &140 * 10 + 8 * 1 &1872 ca DEX &1873 d0 e1 BNE &1856 ; plot_left_sky_in_buffer_two_loop ; plot_left_ground_in_buffer_two_loop &1875 a9 aa LDA #&aa ; 3030 # Plot left middle ground &1877 9d 09 76 STA &7609,X ; buffer_two + &140 * 11 + 8 * 1 + 1 &187a 9d 49 77 STA &7749,X ; buffer_two + &140 * 12 + 8 * 1 + 1 &187d a9 55 LDA #&55 ; 0303 # Plot left middle and near ground &187f 9d 08 76 STA &7608,X ; buffer_two + &140 * 11 + 8 * 1 &1882 9d 48 77 STA &7748,X ; buffer_two + &140 * 12 + 8 * 1 &1885 9d 88 78 STA &7888,X ; buffer_two + &140 * 13 + 8 * 1 &1888 9d c8 79 STA &79c8,X ; buffer_two + &140 * 14 + 8 * 1 &188b 9d 08 7b STA &7b08,X ; buffer_two + &140 * 15 + 8 * 1 &188e a9 00 LDA #&00 ; 0000 # Plot left near ground &1890 9d 89 78 STA &7889,X ; buffer_two + &140 * 13 + 8 * 1 + 1 &1893 9d c9 79 STA &79c9,X ; buffer_two + &140 * 14 + 8 * 1 + 1 &1896 9d 09 7b STA &7b09,X ; buffer_two + &140 * 15 + 8 * 1 + 1 &1899 ca DEX &189a ca DEX &189b d0 d8 BNE &1875 ; plot_left_ground_in_buffer_two_loop &189d a2 2f LDX #&2f ; plot_right_sky_in_buffer_two_loop &189f a9 00 LDA #&00 ; 0000 # Plot right sky &18a1 9d 88 6a STA &6a88,X ; buffer_two + &140 * 1 + 8 * 33 &18a4 9d c8 6b STA &6bc8,X ; buffer_two + &140 * 2 + 8 * 33 &18a7 9d 08 6d STA &6d08,X ; buffer_two + &140 * 3 + 8 * 33 &18aa 9d 48 6e STA &6e48,X ; buffer_two + &140 * 4 + 8 * 33 &18ad 9d 88 6f STA &6f88,X ; buffer_two + &140 * 5 + 8 * 33 &18b0 9d c8 70 STA &70c8,X ; buffer_two + &140 * 6 + 8 * 33 &18b3 9d 08 72 STA &7208,X ; buffer_two + &140 * 7 + 8 * 33 &18b6 a9 ff LDA #&ff ; 3333 # Plot right distant ground &18b8 9d c8 75 STA &75c8,X ; buffer_two + &140 * 10 + 8 * 33 &18bb ca DEX &18bc 10 e1 BPL &189f ; plot_right_sky_in_buffer_two_loop &18be a2 32 LDX #&32 ; plot_right_ground_in_buffer_two_loop &18c0 a9 aa LDA #&aa ; 3030 # Plot right middle ground &18c2 9d 05 77 STA &7705,X ; buffer_two + &140 * 11 + 8 * 32 + 5 &18c5 9d 45 78 STA &7845,X ; buffer_two + &140 * 12 + 8 * 32 + 5 &18c8 a9 55 LDA #&55 ; 0303 # Plot right middle and near ground &18ca 9d 04 77 STA &7704,X ; buffer_two + &140 * 11 + 8 * 32 + 4 &18cd 9d 44 78 STA &7844,X ; buffer_two + &140 * 12 + 8 * 32 + 4 &18d0 9d 84 79 STA &7984,X ; buffer_two + &140 * 13 + 8 * 32 + 4 &18d3 9d c4 7a STA &7ac4,X ; buffer_two + &140 * 14 + 8 * 32 + 4 &18d6 9d 04 7c STA &7c04,X ; buffer_two + &140 * 15 + 8 * 32 + 4 &18d9 a9 00 LDA #&00 ; 0000 # Plot right near ground &18db 9d 85 79 STA &7985,X ; buffer_two + &140 * 13 + 8 * 32 + 5 &18de 9d c5 7a STA &7ac5,X ; buffer_two + &140 * 14 + 8 * 32 + 5 &18e1 9d 05 7c STA &7c05,X ; buffer_two + &140 * 15 + 8 * 32 + 5 &18e4 ca DEX &18e5 ca DEX &18e6 d0 d8 BNE &18c0 ; plot_right_ground_in_buffer_two_loop &18e8 a5 70 LDA &70 ; frame_counter &18ea 29 03 AND #&03 &18ec aa TAX &18ed bd 49 18 LDA &1849,X ; shifted_horizon_addresses_high &18f0 8d 09 19 STA &1909 ; buffer_two_left_horizon_address_one &18f3 8d 19 19 STA &1919 ; buffer_two_right_horizon_address_one &18f6 18 CLC &18f7 69 01 ADC #&01 &18f9 8d 0f 19 STA &190f ; buffer_two_left_horizon_address_two &18fc 8d 1f 19 STA &191f ; buffer_two_right_horizon_address_two &18ff a5 70 LDA &70 ; frame_counter &1901 0a ASL A &1902 29 f8 AND #&f8 &1904 aa TAX &1905 a0 00 LDY #&00 ; plot_left_horizon_in_buffer_two_loop &1907 bd 00 40 LDA &4000,X # Plot left horizon # actually LDA buffer_two_left_horizon_address_one,X &190a 99 48 72 STA &7248,Y ; buffer_two + &140 * 8 + 8 * 1 &190d bd 00 41 LDA &4100,X # actually LDA buffer_two_left_horizon_address_two,X &1910 99 88 73 STA &7388,Y ; buffer_two + &140 * 9 + 8 * 1 &1913 e8 INX &1914 c8 INY &1915 d0 f0 BNE &1907 ; plot_left_horizon_in_buffer_two_loop ; plot_right_horizon_in_buffer_two_loop &1917 bd 00 40 LDA &4000,X # Plot right horizon # actually LDA buffer_two_right_horizon_address_one,X &191a 99 48 73 STA &7348,Y ; buffer_two + &140 * 8 + 8 * 33 &191d bd 00 41 LDA &4100,X # actually LDA buffer_two_right_horizon_address_two,X &1920 99 88 74 STA &7488,Y ; buffer_two + &140 * 9 + 8 * 33 &1923 e8 INX &1924 c8 INY &1925 c0 30 CPY #&30 &1927 d0 ee BNE &1917 ; plot_right_horizon_in_buffer_two_loop &1929 a9 44 LDA #&44 ; 0300 # Plot stars &192b 8d a7 69 STA &69a7 ; buffer_two + &140 * 1 + 8 * 4 + 7 &192e 8d 76 6b STA &6b76 ; buffer_two + &140 * 2 + 8 * 22 + 6 &1931 8d 70 6c STA &6c70 ; buffer_two + &140 * 3 + 8 * 14 &1934 8d f7 6c STA &6cf7 ; buffer_two + &140 * 3 + 8 * 30 + 7 &1937 8d d0 6d STA &6dd0 ; buffer_two + &140 * 4 + 8 * 18 &193a 8d a0 6f STA &6fa0 ; buffer_two + &140 * 5 + 8 * 36 &193d 8d 47 6f STA &6f47 ; buffer_two + &140 * 5 + 8 * 24 + 7 &1940 8d 2f 70 STA &702f ; buffer_two + &140 * 6 + 8 * 13 + 7 &1943 8d c3 6e STA &6ec3 ; buffer_two + &140 * 5 + 8 * 8 + 3 &1946 a9 74 LDA #&74 &1948 85 74 STA &74 ; distant_screen_address_high &194a a9 77 LDA #&77 &194c 85 09 STA &09 ; middle_screen_address_high &194e a9 7b LDA #&7b &1950 85 01 STA &01 ; screen_address_high &1952 4c 53 1a JMP &1a53 ; plot_background_in_either_buffer ; plot_background_in_buffer_one &1955 a2 00 LDX #&00 ; plot_left_sky_in_buffer_one_loop &1957 a9 00 LDA #&00 ; 0000 # Plot left sky &1959 9d 88 50 STA &5088,X ; buffer_one + &140 * 1 + 8 * 1 &195c 9d c8 51 STA &51c8,X ; buffer_one + &140 * 2 + 8 * 1 &195f 9d 08 53 STA &5308,X ; buffer_one + &140 * 3 + 8 * 1 &1962 9d 48 54 STA &5448,X ; buffer_one + &140 * 4 + 8 * 1 &1965 9d 88 55 STA &5588,X ; buffer_one + &140 * 5 + 8 * 1 &1968 9d c8 56 STA &56c8,X ; buffer_one + &140 * 6 + 8 * 1 &196b 9d 08 58 STA &5808,X ; buffer_one + &140 * 7 + 8 * 1 &196e a9 ff LDA #&ff &1970 9d c8 5b STA &5bc8,X ; buffer_one + &140 * 10 + 8 * 1 &1973 ca DEX &1974 d0 e1 BNE &1957 ; plot_left_sky_in_buffer_one_loop ; plot_left_ground_in_buffer_one_loop &1976 a9 aa LDA #&aa ; 3030 # Plot left middle and near ground &1978 9d 08 5d STA &5d08,X ; buffer_one + &140 * 11 + 8 * 1 &197b 9d 48 5e STA &5e48,X ; buffer_one + &140 * 12 + 8 * 1 &197e 9d 88 5f STA &5f88,X ; buffer_one + &140 * 13 + 8 * 1 &1981 9d c8 60 STA &60c8,X ; buffer_one + &140 * 14 + 8 * 1 &1984 9d 08 62 STA &6208,X ; buffer_one + &140 * 15 + 8 * 1 &1987 a9 55 LDA #&55 ; 0303 # Plot left middle ground &1989 9d 09 5d STA &5d09,X ; buffer_one + &140 * 11 + 8 * 1 + 1 &198c 9d 49 5e STA &5e49,X ; buffer_one + &140 * 12 + 8 * 1 + 1 &198f a9 00 LDA #&00 ; 0000 # Plot left near ground &1991 9d 89 5f STA &5f89,X ; buffer_one + &140 * 13 + 8 * 1 + 1 &1994 9d c9 60 STA &60c9,X ; buffer_one + &140 * 14 + 8 * 1 + 1 &1997 9d 09 62 STA &6209,X ; buffer_one + &140 * 15 + 8 * 1 + 1 &199a ca DEX &199b ca DEX &199c d0 d8 BNE &1976 ; plot_left_ground_in_buffer_one_loop &199e a2 2f LDX #&2f ; plot_right_sky_in_buffer_one_loop &19a0 a9 00 LDA #&00 ; 0000 # Plot right sky &19a2 9d 88 51 STA &5188,X ; buffer_one + &140 * 1 + 8 * 33 &19a5 9d c8 52 STA &52c8,X ; buffer_one + &140 * 2 + 8 * 33 &19a8 9d 08 54 STA &5408,X ; buffer_one + &140 * 3 + 8 * 33 &19ab 9d 48 55 STA &5548,X ; buffer_one + &140 * 4 + 8 * 33 &19ae 9d 88 56 STA &5688,X ; buffer_one + &140 * 5 + 8 * 33 &19b1 9d c8 57 STA &57c8,X ; buffer_one + &140 * 6 + 8 * 33 &19b4 9d 08 59 STA &5908,X ; buffer_one + &140 * 7 + 8 * 33 &19b7 a9 ff LDA #&ff ; 3333 # Plot right distant ground &19b9 9d c8 5c STA &5cc8,X ; buffer_one + &140 * 10 + 8 * 33 &19bc ca DEX &19bd 10 e1 BPL &19a0 ; plot_right_sky_in_buffer_one_loop &19bf a2 32 LDX #&32 ; plot_right_ground_in_buffer_one_loop &19c1 a9 aa LDA #&aa ; 3030 # Plot right middle and near ground &19c3 9d 04 5e STA &5e04,X ; buffer_one + &140 * 11 + 8 * 32 + 4 &19c6 9d 44 5f STA &5f44,X ; buffer_one + &140 * 12 + 8 * 32 + 4 &19c9 9d 84 60 STA &6084,X ; buffer_one + &140 * 13 + 8 * 32 + 4 &19cc 9d c4 61 STA &61c4,X ; buffer_one + &140 * 14 + 8 * 32 + 4 &19cf 9d 04 63 STA &6304,X ; buffer_one + &140 * 15 + 8 * 32 + 4 &19d2 a9 55 LDA #&55 ; 0303 # Plot right middle ground &19d4 9d 05 5e STA &5e05,X ; buffer_one + &140 * 11 + 8 * 32 + 5 &19d7 9d 45 5f STA &5f45,X ; buffer_one + &140 * 12 + 8 * 32 + 5 &19da a9 00 LDA #&00 ; 0000 # Plot right near ground &19dc 9d 85 60 STA &6085,X ; buffer_one + &140 * 13 + 8 * 32 + 5 &19df 9d c5 61 STA &61c5,X ; buffer_one + &140 * 14 + 8 * 32 + 5 &19e2 9d 05 63 STA &6305,X ; buffer_one + &140 * 15 + 8 * 32 + 5 &19e5 ca DEX &19e6 ca DEX &19e7 d0 d8 BNE &19c1 ; plot_right_ground_in_buffer_one_loop &19e9 a5 70 LDA &70 ; frame_counter &19eb 29 03 AND #&03 &19ed aa TAX &19ee bd 49 18 LDA &1849,X ; shifted_horizon_addresses_high &19f1 8d 0a 1a STA &1a0a ; buffer_one_left_horizon_address_one &19f4 8d 1a 1a STA &1a1a ; buffer_one_right_horizon_address_one &19f7 18 CLC &19f8 69 01 ADC #&01 &19fa 8d 10 1a STA &1a10 ; buffer_one_left_horizon_address_two &19fd 8d 20 1a STA &1a20 ; buffer_one_right_horizon_address_two &1a00 a5 70 LDA &70 ; frame_counter &1a02 0a ASL A &1a03 29 f8 AND #&f8 &1a05 aa TAX &1a06 a0 00 LDY #&00 ; plot_left_horizon_in_buffer_one_loop &1a08 bd 00 40 LDA &4000,X # Plot left horizon # actually LDA buffer_one_left_horizon_address_one,X &1a0b 99 48 59 STA &5948,Y ; buffer_one + &140 * 8 + 8 * 1 &1a0e bd 00 41 LDA &4100,X # actually LDA buffer_one_left_horizon_address_two,X &1a11 99 88 5a STA &5a88,Y ; buffer_one + &140 * 9 + 8 * 1 &1a14 e8 INX &1a15 c8 INY &1a16 d0 f0 BNE &1a08 ; plot_left_horizon_in_buffer_one_loop ; plot_right_horizon_in_buffer_one_loop &1a18 bd 00 40 LDA &4000,X # Plot right horizon # actually LDA buffer_one_right_horizon_address_one,X &1a1b 99 48 5a STA &5a48,Y ; buffer_one + &140 * 8 + 8 * 33 &1a1e bd 00 41 LDA &4100,X # actually LDA buffer_one_right_horizon_address_two,X &1a21 99 88 5b STA &5b88,Y ; buffer_one + &140 * 9 + 8 * 33 &1a24 e8 INX &1a25 c8 INY &1a26 c0 30 CPY #&30 &1a28 d0 ee BNE &1a18 ; plot_right_horizon_in_buffer_one_loop &1a2a a9 44 LDA #&44 ; 0300 # Plot stars &1a2c 8d a7 50 STA &50a7 ; buffer_one + &140 * 1 + 8 * 4 + 7 &1a2f 8d 76 52 STA &5276 ; buffer_one + &140 * 2 + 8 * 22 + 6 &1a32 8d 70 53 STA &5370 ; buffer_one + &140 * 3 + 8 * 14 &1a35 8d f7 53 STA &53f7 ; buffer_one + &140 * 3 + 8 * 30 + 7 &1a38 8d d0 54 STA &54d0 ; buffer_one + &140 * 4 + 8 * 18 &1a3b 8d a0 56 STA &56a0 ; buffer_one + &140 * 5 + 8 * 36 &1a3e 8d 47 56 STA &5647 ; buffer_one + &140 * 5 + 8 * 24 + 7 &1a41 8d 2f 57 STA &572f ; buffer_one + &140 * 6 + 8 * 13 + 7 &1a44 8d c3 55 STA &55c3 ; buffer_one + &140 * 5 + 8 * 8 + 3 &1a47 a9 5b LDA #&5b &1a49 85 74 STA &74 ; distant_screen_address_high &1a4b a9 5e LDA #&5e &1a4d 85 09 STA &09 ; middle_screen_address_high &1a4f a9 62 LDA #&62 &1a51 85 01 STA &01 ; screen_address_high ; plot_background_in_either_buffer ; plot_distant_markers &1a53 a2 08 LDX #&08 &1a55 a5 70 LDA &70 ; frame_counter &1a57 29 06 AND #&06 &1a59 49 06 EOR #&06 &1a5b c9 04 CMP #&04 &1a5d 10 01 BPL &1a60 ; skip_extra_distant_marker &1a5f e8 INX ; skip_extra_distant_marker &1a60 0a ASL A &1a61 0a ASL A &1a62 69 ce ADC #&ce &1a64 85 73 STA &73 ; distant_screen_address_low &1a66 a0 00 LDY #&00 ; plot_distant_markers_loop &1a68 a5 70 LDA &70 ; frame_counter &1a6a 29 01 AND #&01 &1a6c f0 04 BEQ &1a72 ; is_even ; is_odd &1a6e a9 bf LDA #&bf ; 3133 &1a70 d0 02 BNE &1a74 ; plot_distant_marker # Always branches ; is_even &1a72 a9 ef LDA #&ef ; 3331 ; plot_distant_marker &1a74 91 73 STA (&73),Y ; distant_screen_address &1a76 18 CLC &1a77 a5 73 LDA &73 ; distant_screen_address_low &1a79 69 20 ADC #&20 &1a7b 85 73 STA &73 ; distant_screen_address_low &1a7d 90 02 BCC &1a81 ; skip_page &1a7f e6 74 INC &74 ; distant_screen_address_high ; skip_page &1a81 ca DEX &1a82 10 e4 BPL &1a68 ; plot_distant_markers_loop ; plot_middle_markers &1a84 a2 03 LDX #&03 &1a86 a5 70 LDA &70 ; frame_counter &1a88 29 07 AND #&07 &1a8a 49 07 EOR #&07 &1a8c c9 06 CMP #&06 &1a8e 10 01 BPL &1a91 ; skip_extra_middle_marker &1a90 e8 INX ; skip_extra_middle_marker &1a91 0a ASL A &1a92 0a ASL A &1a93 0a ASL A &1a94 69 4d ADC #&4d &1a96 85 08 STA &08 ; middle_screen_address_low ; plot_middle_markers_loop &1a98 a0 00 LDY #&00 &1a9a a9 8b LDA #&8b ; 3011 &1a9c 91 08 STA (&08),Y ; middle_screen_address_low &1a9e c8 INY &1a9f a9 47 LDA #&47 ; 0311 &1aa1 91 08 STA (&08),Y ; middle_screen_address_low &1aa3 18 CLC &1aa4 a5 08 LDA &08 ; middle_screen_address_low &1aa6 69 40 ADC #&40 &1aa8 85 08 STA &08 ; middle_screen_address_low &1aaa 90 02 BCC &1aae ; skip_page &1aac e6 09 INC &09 ; middle_screen_address_high ; skip_page &1aae ca DEX &1aaf 10 e7 BPL &1a98 ; plot_middle_markers_loop ; plot_near_markers &1ab1 a2 01 LDX #&01 &1ab3 a5 70 LDA &70 ; frame_counter &1ab5 29 07 AND #&07 &1ab7 49 07 EOR #&07 &1ab9 c9 03 CMP #&03 &1abb 10 01 BPL &1abe ; skip_extra_near_marker &1abd e8 INX ; skip_extra_near_marker &1abe 0a ASL A &1abf 0a ASL A &1ac0 0a ASL A &1ac1 0a ASL A &1ac2 69 0b ADC #&0b &1ac4 85 00 STA &00 ; screen_address_low &1ac6 90 02 BCC &1aca ; skip_page &1ac8 e6 01 INC &01 ; screen_address_high ; skip_page ; plot_near_markers_loop &1aca a0 03 LDY #&03 &1acc a9 0f LDA #&0f ; 1111 ; plot_near_marker_loop &1ace 91 00 STA (&00),Y &1ad0 88 DEY &1ad1 10 fb BPL &1ace ; plot_near_marker_loop &1ad3 18 CLC &1ad4 a5 00 LDA &00 ; screen_address_low &1ad6 69 80 ADC #&80 &1ad8 85 00 STA &00 ; screen_address_low &1ada 90 02 BCC &1ade ; skip_page &1adc e6 01 INC &01 ; screen_address_high ; skip_page &1ade ca DEX &1adf 10 e9 BPL &1aca ; plot_near_markers_loop &1ae1 60 RTS ; irq1_handler &1ae2 a5 fc LDA &fc ; irq_accumulator &1ae4 48 PHA &1ae5 8a TXA &1ae6 48 PHA &1ae7 98 TYA &1ae8 48 PHA &1ae9 ad 4d fe LDA &fe4d ; System VIA interrupt flag register &1aec 29 82 AND #&82 &1aee c9 82 CMP #&82 # Has a interrupt occurred because of a v-sync? &1af0 d0 33 BNE &1b25 ; consider_timer_interrupt ; handle_vsync_interrupt &1af2 ad 4d fe LDA &fe4d ; System VIA interrupt flag register &1af5 29 7d AND #&7d # Clear all interrupts except CA1 (v-sync) (?) &1af7 8d 4d fe STA &fe4d ; System VIA interrupt flag register &1afa a5 c4 LDA &c4 ; palette_state &1afc f0 1d BEQ &1b1b ; leave_irq1_handler ; set_palette_for_top_of_screen &1afe a9 00 LDA #&00 &1b00 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1b03 a2 19 LDX #&19 &1b05 8e 69 fe STX &fe69 ; User VIA timer 2 counter MSB &1b08 85 77 STA &77 ; vsync_pending # Set to zero to indicate a v-sync has occurred &1b0a 85 c4 STA &c4 ; palette_state # Set to zero to set middle of screen next &1b0c a9 a1 LDA #&a1 # Set colour 3 to cyan &1b0e 20 35 22 JSR &2235 ; set_colour &1b11 a9 24 LDA #&24 # Set colour 1 to yellow &1b13 20 35 22 JSR &2235 ; set_colour &1b16 a9 80 LDA #&80 # Set colour 2 to white ; leave_irq1_handler_after_setting_colour &1b18 20 35 22 JSR &2235 ; set_colour ; leave_irq1_handler &1b1b 68 PLA &1b1c a8 TAY &1b1d 68 PLA &1b1e aa TAX &1b1f 68 PLA &1b20 85 fc STA &fc ; irq_accumulator &1b22 6c fe 0b JMP (&0bfe) ; previous_irq1_vector ; consider_timer_interrupt &1b25 ad 6d fe LDA &fe6d ; User VIA interrupt flag register &1b28 29 a0 AND #&a0 &1b2a c9 a0 CMP #&a0 # Has an interrupt occurred because of timer 2? &1b2c d0 ed BNE &1b1b ; leave_irq1_handler ; handle_timer_interrupt &1b2e 8d 6d fe STA &fe6d ; User VIA interrupt flag register &1b31 a5 c4 LDA &c4 ; palette_state &1b33 d0 1f BNE &1b54 ; set_palette_for_bottom_of_screen ; set_palette_for_middle_of_screen &1b35 a9 80 LDA #&80 &1b37 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1b3a a9 1d LDA #&1d &1b3c 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &1b3f a2 01 LDX #&01 # Set to non-zero to set bottom of screen text &1b41 86 c4 STX &c4 ; palette_state &1b43 a6 96 LDX &96 ; colour_scheme &1b45 bd 40 2a LDA &2a40,X ; level_colours # Set colour 3 to level colour &1b48 20 35 22 JSR &2235 ; set_colour &1b4b a9 26 LDA #&26 # Set colour 1 to red &1b4d 20 35 22 JSR &2235 ; set_colour &1b50 a9 83 LDA #&83 # Set colour 2 to blue &1b52 d0 c4 BNE &1b18 ; leave_irq1_handler_after_setting_colour # Always branches ; set_palette_for_bottom_of_screen &1b54 c9 01 CMP #&01 &1b56 d0 a6 BNE &1afe ; set_palette_for_top_of_screen &1b58 a9 b0 LDA #&b0 &1b5a 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1b5d a9 17 LDA #&17 &1b5f 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &1b62 a9 22 LDA #&22 # Set colour 1 to magenta &1b64 20 35 22 JSR &2235 ; set_colour &1b67 a9 07 LDA #&07 # Set colour 0 to black &1b69 20 35 22 JSR &2235 ; set_colour &1b6c a9 a5 LDA #&a5 # Set colour 3 to green &1b6e 85 c4 STA &c4 ; palette_state # Set to non-zero, non-one to set top of screen next &1b70 d0 a6 BNE &1b18 ; leave_irq1_handler_after_setting_colour # Always branches ; prepare_shifted_horizon_sprites &1b72 a5 9b LDA &9b ; level_number &1b74 29 03 AND #&03 &1b76 0a ASL A &1b77 69 46 ADC #&46 ; &4600 = horizon_0_sprite &1b79 85 74 STA &74 ; source_address_high # Use unshifted sprite &1b7b 8d 49 18 STA &1849 ; shifted_horizon_addresses_high &1b7e a9 0e LDA #&0e ; &0e00 = horizon_shifted_1_sprite &1b80 85 76 STA &76 ; target_address_high &1b82 20 94 1b JSR &1b94 ; shift_horizon # Create copy in &0e00 - &0fff shifted by one pixel &1b85 a9 0e LDA #&0e ; &0e00 = horizon_shifted_1_sprite &1b87 85 74 STA &74 ; source_address_high &1b89 20 94 1b JSR &1b94 ; shift_horizon # Create copy in &1000 - &11ff shifted by two pixels &1b8c a9 10 LDA #&10 ; &1000 = horizon_shifted_2_sprite &1b8e 85 74 STA &74 ; source_address_high &1b90 a9 0c LDA #&0c ; &0c00 = horizon_shifted_3_sprite &1b92 85 76 STA &76 ; target_address_high # Create copy in &0c00 - &0dff shifted by three pixels ; shift_horizon &1b94 a9 02 LDA #&02 &1b96 85 7a STA &7a ; pages ; shift_horizon_page_loop &1b98 a9 00 LDA #&00 &1b9a 85 73 STA &73 ; source_address_low &1b9c 85 75 STA &75 ; target_address_low &1b9e a2 07 LDX #&07 ; shift_horizon_row_loop &1ba0 a9 00 LDA #&00 ; shift_horizon_group_loop &1ba2 85 79 STA &79 ; offset &1ba4 a8 TAY &1ba5 b1 73 LDA (&73),Y ; source_address &1ba7 0a ASL A # Shift column of sprite left a pixel &1ba8 29 ee AND #&ee ; 3330 &1baa 91 75 STA (&75),Y ; target_address &1bac 98 TYA &1bad 18 CLC &1bae 69 08 ADC #&08 &1bb0 a8 TAY &1bb1 b1 73 LDA (&73),Y ; source_address &1bb3 29 88 AND #&88 ; 3000 # Get left pixel of next column of sprite &1bb5 4a LSR A &1bb6 4a LSR A &1bb7 4a LSR A # Move into right pixel &1bb8 a4 79 LDY &79 ; offset &1bba 11 75 ORA (&75),Y ; target_address &1bbc 91 75 STA (&75),Y ; target_address &1bbe a5 79 LDA &79 ; offset &1bc0 69 08 ADC #&08 &1bc2 d0 de BNE &1ba2 ; shift_horizon_group_loop &1bc4 e6 73 INC &73 ; source_address_low &1bc6 e6 75 INC &75 ; target_address_low &1bc8 ca DEX &1bc9 10 d5 BPL &1ba0 ; shift_horizon_row_loop &1bcb e6 74 INC &74 ; source_address_high &1bcd e6 76 INC &76 ; target_address_high &1bcf c6 7a DEC &7a ; pages &1bd1 d0 c5 BNE &1b98 ; shift_horizon_page_loop &1bd3 60 RTS ; plot_sprites &1bd4 a9 07 LDA #&07 &1bd6 85 75 STA &75 ; sprite_to_update ; plot_sprites_loop &1bd8 a6 75 LDX &75 ; sprite_to_update &1bda 20 c6 1f JSR &1fc6 ; plot_player_or_enemy &1bdd a4 75 LDY &75 ; sprite_to_update &1bdf f0 04 BEQ &1be5 ; is_player &1be1 c0 01 CPY #&01 &1be3 d0 03 BNE &1be8 ; not_player ; is_player &1be5 20 f1 1b JSR &1bf1 ; plot_player_weapon_and_consider_firing ; not_player &1be8 c6 75 DEC &75 ; sprite_to_update &1bea 10 ec BPL &1bd8 ; plot_sprites_loop &1bec 60 RTS ; first_laser_offsets &1bed 00 18 ; last_laser_offsets &1bef 14 2c ; plot_player_weapon_and_consider_firing # Called with Y = player &1bf1 98 TYA &1bf2 69 11 ADC #&11 # Use channels 1 and 2 for player one and two firing &1bf4 8d 0e 22 STA &220e ; explosion_and_firing_sound (channel) &1bf5 a9 68 LDA #&68 ; &2e68 = mask_player_weapon_0_odd &1bf9 85 06 STA &06 ; mask_address_low &1bfb a9 2e LDA #&2e &1bfd 85 07 STA &07 ; mask_address_high &1bff a9 2e LDA #&2e &1c01 85 09 STA &09 ; sprite_address_high &1c03 a9 48 LDA #&48 ; &2e48 = sprite_player_one_weapon_0_odd &1c05 c0 00 CPY #&00 &1c07 f0 02 BEQ &1c0b ; not_player_two &1c09 a9 58 LDA #&58 ; &2e58 = sprite_player_two_weapon_0_odd ; not_player_two &1c0b 85 08 STA &08 ; sprite_address_low ; plot_player_weapon &1c0d b9 0e 00 LDA &000e,Y ; players_selected_weapon &1c10 4a LSR A &1c11 4a LSR A &1c12 85 73 STA &73 ; weapon &1c14 18 CLC &1c15 65 09 ADC &09 ; sprite_address_high &1c17 85 09 STA &09 ; sprite_address_high &1c19 a5 73 LDA &73 ; weapon &1c1b 65 07 ADC &07 ; mask_address_high &1c1d 85 07 STA &07 ; mask_address_high &1c1f b9 02 00 LDA &0002,Y ; players_firing_cooldown &1c22 f0 0c BEQ &1c30 ; is_ready_to_fire ; not_ready_to_fire &1c24 a5 06 LDA &06 ; mask_address_low &1c26 69 30 ADC #&30 # Use inactive sprites if player is not ready to fire &1c28 85 06 STA &06 ; mask_address_low &1c2a a5 08 LDA &08 ; sprite_address_low &1c2c 69 30 ADC #&30 # Add &30 to sprite and mask addresses if so &1c2e 85 08 STA &08 ; sprite_address_low ; is_ready_to_fire &1c30 b9 10 00 LDA &0010,Y ; players_or_enemies_x &1c33 29 01 AND #&01 &1c35 d0 13 BNE &1c4a ; is_odd ; is_even &1c37 a5 07 LDA &07 ; mask_address_high &1c39 69 04 ADC #&04 # Add &400 to sprite and mask addresses for even x &1c3b 85 07 STA &07 ; mask_address_high &1c3d a5 09 LDA &09 ; sprite_address_high &1c3f 69 04 ADC #&04 &1c41 85 09 STA &09 ; sprite_address_high &1c43 a5 0c LDA &0c ; player_screen_offset_low &1c45 69 c6 ADC #&c6 &1c47 4c 4e 1c JMP &1c4e ; set_screen_address_low ; is_odd &1c4a a5 0c LDA &0c ; player_screen_offset_low &1c4c 69 ce ADC #&ce ; set_screen_address_low &1c4e 85 00 STA &00 ; screen_address_low &1c50 a5 0d LDA &0d ; player_screen_offset_high &1c52 a6 94 LDX &94 ; buffer_to_use # Zero for buffer one, non-zero for buffer two &1c54 d0 04 BNE &1c5a ; use_buffer_two ; use_buffer_one &1c56 69 4e ADC #&4e &1c58 d0 02 BNE &1c5c ; set_screen_address_high # Always branches ; use_buffer_two &1c5a 69 67 ADC #&67 ; set_screen_address_high &1c5c 85 01 STA &01 ; screen_address_high &1c5e b9 18 00 LDA &0018,Y ; players_or_enemies_y &1c61 29 01 AND #&01 &1c63 f0 13 BEQ &1c78 ; is_even ;is_odd &1c65 a9 68 LDA #&68 &1c67 d0 11 BNE &1c7a ; set_screen_address_low # Always branches ; plot_player_weapon_group_loop &1c69 18 CLC &1c6a a5 00 LDA &00 ; screen_address_low &1c6c 69 39 ADC #&39 &1c6e 85 00 STA &00 ; screen_address_low &1c70 a5 01 LDA &01 ; screen_address_high &1c72 69 01 ADC #&01 &1c74 85 01 STA &01 ; screen_address_high &1c76 d0 58 BNE &1cd0 ; dex_then_to_plot_player_weapon_byte_loop # Always branches ; is_even &1c78 a9 64 LDA #&64 ; set_screen_address_low &1c7a 18 CLC &1c7b 65 00 ADC &00 ; screen_address_low &1c7d 85 00 STA &00 ; screen_address_low &1c7f a5 01 LDA &01 ; screen_address_high &1c81 69 01 ADC #&01 &1c83 85 01 STA &01 ; screen_address_high &1c85 b9 10 00 LDA &0010,Y ; players_or_enemies_x &1c88 c9 1c CMP #&1c # If the player crosses the left of the screen, &1c8a 10 1a BPL &1ca6 ; skip_adjusting_weapon_screen_address &1c8c c9 18 CMP #&18 &1c8e 30 45 BMI &1cd5 ; skip_plotting_player_weapon &1c90 29 fe AND #&fe # adjust the position of the weapon accordingly &1c92 85 73 STA &73 ; tmp &1c94 38 SEC &1c95 a9 1c LDA #&1c &1c97 e5 73 SBC &73 ; tmp &1c99 0a ASL A &1c9a 0a ASL A &1c9b 85 73 STA &73 ; tmp &1c9d 38 SEC &1c9e a5 00 LDA &00 ; screen_address_low &1ca0 e5 73 SBC &73 ; tmp &1ca2 85 00 STA &00 ; screen_address_low &1ca4 b0 04 BCS &1caa ; set_tmp_y # Always branches ; skip_adjusting_weapon_screen_address &1ca6 c9 61 CMP #&61 &1ca8 10 2b BPL &1cd5 ; skip_plotting_player_weapon # Don't plot weapon if beyond right of screen ; set_tmp_y &1caa 84 73 STY &73 ; tmp_y &1cac a2 07 LDX #&07 ; plot_player_weapon_byte_loop &1cae a0 00 LDY #&00 &1cb0 b1 00 LDA (&00),Y ; screen_address &1cb2 31 06 AND (&06),Y ; mask_address &1cb4 11 08 ORA (&08),Y ; sprite_address &1cb6 91 00 STA (&00),Y ; screen_address &1cb8 a0 08 LDY #&08 &1cba b1 00 LDA (&00),Y ; screen_address &1cbc 31 06 AND (&06),Y ; mask_address &1cbe 11 08 ORA (&08),Y ; sprite_address &1cc0 91 00 STA (&00),Y ; screen_address &1cc2 e6 06 INC &06 ; mask_address_low &1cc4 e6 08 INC &08 ; sprite_address_low &1cc6 a5 00 LDA &00 ; screen_address_low &1cc8 29 07 AND #&07 &1cca c9 07 CMP #&07 &1ccc f0 9b BEQ &1c69 ; plot_player_weapon_group_loop &1cce e6 00 INC &00 ; screen_address_low ; dex_then_to_plot_player_weapon_byte_loop &1cd0 ca DEX &1cd1 10 db BPL &1cae ; plot_player_weapon_byte_loop &1cd3 a4 73 LDY &73 ; tmp_y ; skip_plotting_player_weapon &1cd5 b9 0e 00 LDA &000e,Y ; players_selected_weapon &1cd8 29 0c AND #&0c &1cda 85 73 STA &73 ; weapon_type &1cdc 4a LSR A &1cdd 4a LSR A &1cde aa TAX &1cdf bd f5 0b LDA &0bf5,X ; weapon_damages &1ce2 85 9a STA &9a ; laser_damage &1ce4 b9 04 00 LDA &0004,Y ; players_firing_intent &1ce7 f0 6a BEQ &1d53 ; consider_changing_laser_damage &1ce9 a5 70 LDA &70 ; frame_counter &1ceb 29 01 AND #&01 # Players fire alternately &1ced 85 74 STA &74 ; player_to_fire &1cef c4 74 CPY &74 ; player_to_fire &1cf1 d0 60 BNE &1d53 ; consider_changing_laser_damage &1cf3 a9 00 LDA #&00 &1cf5 99 04 00 STA &0004,Y ; players_firing_intent # Set to zero to indicate not wanting to fire &1cf8 b9 02 00 LDA &0002,Y ; players_firing_cooldown &1cfb d0 56 BNE &1d53 ; consider_changing_laser_damage &1cfd bd f9 0b LDA &0bf9,X ; weapon_cooldowns &1d00 99 02 00 STA &0002,Y ; players_firing_cooldown &1d03 be ed 1b LDX &1bed,Y ; first_laser_offsets &1d06 a5 73 LDA &73 ; weapon_type &1d08 f0 33 BEQ &1d3d ; add_standard_laser &1d0a c9 04 CMP #&04 ; WEAPON_MULTIDIRECTIONAL &1d0c d0 03 BNE &1d11 ; consider_adding_torpedo &1d0e 4c 11 1f JMP &1f11 ; add_multidirectional_laser ; consider_adding_torpedo &1d11 c9 08 CMP #&08 ; WEAPON_TORPEDO &1d13 d0 12 BNE &1d27 ; activate_smart_bomb ; add_torpedo &1d15 b5 42 LDA &42,X ; lasers_x &1d17 f0 08 BEQ &1d21 ; found_slot_for_torpedo # Is the first laser slot empty? &1d19 e8 INX &1d1a e8 INX &1d1b e8 INX &1d1c e8 INX &1d1d b5 42 LDA &42,X ; lasers_x &1d1f d0 03 BNE &1d24 ; to_consider_changing_laser_damage # If not, is the second laser slot empty? ; found_slot_for_torpedo &1d21 20 58 21 JSR &2158 ; add_laser ; to_consider_changing_laser_damage &1d24 4c 53 1d JMP &1d53 ; consider_changing_laser_damage ; activate_smart_bomb &1d27 98 TYA &1d28 aa TAX &1d29 d6 c6 DEC &c6,X ; players_maximum_weapon # Remove smart bomb &1d2b a9 00 LDA #&00 ; WEAPON_STANDARD &1d2d 95 0e STA &0e,X ; players_selected_weapon # Set player using standard laser &1d2f 20 40 06 JSR &0640 ; replot_weapon_selector # Leaves with A = &ff &1d32 85 c5 STA &c5 ; smart_bomb_timer # Set to &ff to start smart bomb on next frame &1d34 a9 ff LDA #&ff &1d36 85 72 STA &72 ; smart_bomb_or_boss_active # Set to negative to indicate smart bomb is active &1d38 8a TXA &1d39 a8 TAY &1d3a 4c a7 21 JMP &21a7 ; plot_weapon_slots ; add_standard_laser &1d3d 18 CLC &1d3e a9 05 LDA #&05 &1d40 85 79 STA &79 ; count ; find_slot_for_standard_laser &1d42 b5 42 LDA &42,X ; lasers_x &1d44 f0 0a BEQ &1d50 ; found_slot_for_standard_laser # Is this slot empty? &1d46 8a TXA &1d47 69 04 ADC #&04 # If not, move to next laser slot &1d49 aa TAX &1d4a c6 79 DEC &79 ; count &1d4c 10 f4 BPL &1d42 ; find_slot_for_standard_laser &1d4e 30 03 BMI &1d53 ; consider_changing_laser_damage ; found_slot_for_standard_laser &1d50 20 58 21 JSR &2158 ; add_laser ; consider_changing_laser_damage &1d53 a5 9b LDA &9b ; level_number &1d55 c9 04 CMP #&04 &1d57 30 10 BMI &1d69 ; skip_changing_laser_damage # On levels 1 - 4, lasers do regular damage &1d59 c9 07 CMP #&07 &1d5b f0 06 BEQ &1d63 ; double_laser_damage # On level 8, lasers do double damage &1d5d 10 08 BPL &1d67 ; halve_laser_damage # On level 9 onwards, lasers do half damage &1d5f 24 92 BIT &92 ; current_wave_type # On levels 5 - 7, &1d61 50 06 BVC &1d69 ; skip_changing_laser_damage # If &40 set, lasrs do double damage ; double_laser_damage &1d63 06 9a ASL &9a ; laser_damage &1d65 d0 02 BNE &1d69 ; skip_changing_laser_damage # Always branches ; halve_laser_damage &1d67 46 9a LSR &9a ; laser_damage ; skip_changing_laser_damage &1d69 b9 ed 1b LDA &1bed,Y ; first_laser_offsets &1d6c 85 73 STA &73 ; first_laser &1d6e be ef 1b LDX &1bef,Y ; last_laser_offsets &1d71 b9 0e 00 LDA &000e,Y ; players_selected_weapon &1d74 29 0c AND #&0c &1d76 f0 0e BEQ &1d86 ; plot_standard_lasers &1d78 c9 04 CMP #&04 ; WEAPON_MULTIDIRECTIONAL &1d7a d0 03 BNE &1d7f ; consider_plotting_torpedo &1d7c 4c bf 1d JMP &1dbf ; plot_multidirectional_lasers ; consider_plotting_torpedo &1d7f c9 08 CMP #&08 ; WEAPON_TORPEDO &1d81 d0 03 BNE &1d86 ; plot_standard_lasers &1d83 4c 3b 1f JMP &1f3b ; plot_antimatter_torpedoes ; plot_standard_lasers &1d86 b5 42 LDA &42,X ; lasers_x &1d88 f0 2c BEQ &1db6 ; consider_next_standard_laser &1d8a 20 fb 1e JSR &1efb ; set_laser_screen_address &1d8d a9 0f LDA #&0f ; 1111 &1d8f a0 01 LDY #&01 &1d91 91 00 STA (&00),Y ; screen_address &1d93 a0 09 LDY #&09 &1d95 91 00 STA (&00),Y ; screen_address &1d97 b5 42 LDA &42,X ; lasers_x &1d99 18 CLC &1d9a 69 04 ADC #&04 &1d9c 95 42 STA &42,X ; lasers_x &1d9e c9 68 CMP #&68 &1da0 30 06 BMI &1da8 ; standard_laser_is_on_screen &1da2 a9 00 LDA #&00 &1da4 95 42 STA &42,X ; lasers_x &1da6 f0 0e BEQ &1db6 ; consider_next_standard_laser # Always branches ; standard_laser_is_on_screen &1da8 20 83 1e JSR &1e83 ; check_for_collision_with_laser &1dab b5 40 LDA &40,X ; lasers_screen_offset_low &1dad 18 CLC &1dae 69 10 ADC #&10 &1db0 95 40 STA &40,X ; lasers_screen_offset_low &1db2 90 02 BCC &1db6 ; consider_next_standard_laser &1db4 f6 41 INC &41,X ; lasers_screen_offset_high ; consider_next_standard_laser &1db6 ca DEX # Move to previous slot &1db7 ca DEX &1db8 ca DEX &1db9 ca DEX &1dba e4 73 CPX &73 ; first_laser &1dbc 10 c8 BPL &1d86 ; plot_standard_lasers &1dbe 60 RTS ; plot_multidirectional_lasers &1dbf b5 42 LDA &42,X ; lasers_x &1dc1 f0 38 BEQ &1dfb ; consider_second_multidirectional_laser &1dc3 b5 43 LDA &43,X ; lasers_y &1dc5 38 SEC &1dc6 e9 02 SBC #&02 &1dc8 95 43 STA &43,X ; lasers_y &1dca c9 02 CMP #&02 &1dcc 30 0b BMI &1dd9 ; remove_first_multidirectional_laser &1dce b5 42 LDA &42,X ; lasers_x &1dd0 18 CLC &1dd1 69 02 ADC #&02 &1dd3 95 42 STA &42,X ; lasers_x &1dd5 c9 68 CMP #&68 &1dd7 30 06 BMI &1ddf ; first_multidirectional_laser_is_on_screen ; remove_first_multidirectional_laser &1dd9 a9 00 LDA #&00 &1ddb 95 42 STA &42,X ; lasers_x &1ddd f0 1c BEQ &1dfb ; consider_second_multidirectional_laser # Always branches ; first_multidirectional_laser_is_on_screen &1ddf 20 83 1e JSR &1e83 ; check_for_collision_with_laser &1de2 20 fb 1e JSR &1efb ; set_laser_screen_address &1de5 a9 0f LDA #&0f ; 1111 &1de7 a0 00 LDY #&00 &1de9 91 00 STA (&00),Y ; screen_address &1deb c8 INY &1dec 91 00 STA (&00),Y ; screen_address &1dee b5 40 LDA &40,X ; lasers_screen_offset_low &1df0 38 SEC &1df1 e9 38 SBC #&38 &1df3 95 40 STA &40,X ; lasers_screen_offset_low &1df5 b5 41 LDA &41,X ; lasers_screen_offset_high &1df7 e9 01 SBC #&01 &1df9 95 41 STA &41,X ; lasers_screen_offset_high ; consider_second_multidirectional_laser &1dfb ca DEX # Move to previous slot &1dfc ca DEX &1dfd ca DEX &1dfe ca DEX &1dff b5 42 LDA &42,X ; lasers_x &1e01 f0 2c BEQ &1e2f ; consider_third_multidirectional_laser &1e03 20 fb 1e JSR &1efb ; set_laser_screen_address &1e06 a9 0f LDA #&0f ; 1111 &1e08 a0 00 LDY #&00 &1e0a 91 00 STA (&00),Y ; screen_address &1e0c a0 01 LDY #&01 &1e0e 91 00 STA (&00),Y ; screen_address &1e10 b5 40 LDA &40,X ; lasers_screen_offset_low &1e12 18 CLC &1e13 69 10 ADC #&10 &1e15 95 40 STA &40,X ; lasers_screen_offset_low &1e17 90 02 BCC &1e1b ; skip_page &1e19 f6 41 INC &41,X ; lasers_screen_offset_high ; skip_page &1e1b b5 42 LDA &42,X ; lasers_x &1e1d 18 CLC &1e1e 69 04 ADC #&04 &1e20 95 42 STA &42,X ; lasers_x &1e22 c9 68 CMP #&68 &1e24 30 06 BMI &1e2c ; second_multidirectional_laser_is_on_screen &1e26 a9 00 LDA #&00 &1e28 95 42 STA &42,X ; lasers_x &1e2a f0 03 BEQ &1e2f ; consider_third_multidirectional_laser # Always branches ; second_multidirectional_laser_is_on_screen &1e2c 20 83 1e JSR &1e83 ; check_for_collision_with_laser ; consider_third_multidirectional_laser &1e2f ca DEX # Move to previous slot &1e30 ca DEX &1e31 ca DEX &1e32 ca DEX &1e33 b5 42 LDA &42,X ; lasers_x &1e35 f0 38 BEQ &1e6f ; consider_next_multidirectional_laser &1e37 b5 43 LDA &43,X ; lasers_y &1e39 18 CLC &1e3a 69 02 ADC #&02 &1e3c 95 43 STA &43,X ; lasers_y &1e3e c9 22 CMP #&22 &1e40 10 0b BPL &1e4d ; remove_third_multidirectional_laser &1e42 b5 42 LDA &42,X ; lasers_x &1e44 18 CLC &1e45 69 02 ADC #&02 &1e47 95 42 STA &42,X ; lasers_x &1e49 c9 68 CMP #&68 &1e4b 30 06 BMI &1e53 ; third_multidirectional_laser_is_on_screen ; remove_third_multidirectional_laser &1e4d a9 00 LDA #&00 &1e4f 95 42 STA &42,X ; lasers_x &1e51 f0 1c BEQ &1e6f ; consider_next_multidirectional_laser # Always branches ; third_multidirectional_laser_is_on_screen &1e53 20 83 1e JSR &1e83 ; check_for_collision_with_laser &1e56 20 fb 1e JSR &1efb ; set_laser_screen_address &1e59 a9 0f LDA #&0f ; 1111 &1e5b a0 00 LDY #&00 &1e5d 91 00 STA (&00),Y ; screen_address &1e5f c8 INY &1e60 91 00 STA (&00),Y ; screen_address &1e62 18 CLC &1e63 b5 40 LDA &40,X ; lasers_screen_offset_low &1e65 69 48 ADC #&48 &1e67 95 40 STA &40,X ; lasers_screen_offset_low &1e69 b5 41 LDA &41,X ; lasers_screen_offset_high &1e6b 69 01 ADC #&01 &1e6d 95 41 STA &41,X ; lasers_screen_offset_high ; consider_next_multidirectional_laser &1e6f ca DEX # Move to previous slot &1e70 ca DEX &1e71 ca DEX &1e72 ca DEX &1e73 e4 73 CPX &73 ; first_laser &1e75 30 0b BMI &1e82 ; leave ; to_plot_multidirectional_lasers &1e77 4c bf 1d JMP &1dbf ; plot_multidirectional_lasers ; unused # Unused code &1e7a ca DEX # Move to previous slot &1e7b ca DEX &1e7c ca DEX &1e7d ca DEX &1e7e e4 73 CPX &73 ; first_laser &1e80 10 f5 BPL &1e77 ; to_plot_multidirectional_lasers ; leave &1e82 60 RTS ; check_for_collision_with_laser &1e83 85 74 STA &74 ; laser_x &1e85 a0 05 LDY #&05 ; check_for_collision_with_laser_loop # For each enemy, &1e87 b9 12 00 LDA &0012,Y ; player_or_enemies_x + 2 &1e8a c5 74 CMP &74 ; laser_x # Has the enemy collided with the laser? &1e8c 10 6a BPL &1ef8 ; consider_next_enemy &1e8e 18 CLC &1e8f 69 08 ADC #&08 &1e91 c5 74 CMP &74 ; laser_x &1e93 30 63 BMI &1ef8 ; consider_next_enemy &1e95 b9 1a 00 LDA &001a,Y ; player_or_enemies_y + 2 &1e98 d5 43 CMP &43,X ; lasers_y &1e9a 10 5c BPL &1ef8 ; consider_next_enemy &1e9c 18 CLC &1e9d 79 3a 00 ADC &003a,Y ; enemies_height &1ea0 d5 43 CMP &43,X ; lasers_y &1ea2 30 54 BMI &1ef8 ; consider_next_enemy ; laser_collided_with_enemy &1ea4 a9 00 LDA #&00 # If so, set to zero to remove laser &1ea6 95 42 STA &42,X ; lasers_x &1ea8 b9 22 00 LDA &0022,Y ; players_or_enemies_energy + 2 &1eab 30 4a BMI &1ef7 ; leave # Leave if the enemy is already exploding &1ead c9 7f CMP #&7f ; ENERGY_INDESTRUCTIBLE &1eaf f0 46 BEQ &1ef7 ; leave # Leave if the enemy is indestructible &1eb1 38 SEC &1eb2 e5 9a SBC &9a ; laser_damage # Damage enemy &1eb4 99 22 00 STA &0022,Y ; players_or_enemies_energy + 2 &1eb7 10 3e BPL &1ef7 ; leave # Has the enemy been destroyed? &1eb9 a5 72 LDA &72 ; smart_bomb_or_boss_active &1ebb f0 0c BEQ &1ec9 ; explode_enemy # Zero if no boss or smart bomb active &1ebd 30 38 BMI &1ef7 ; leave # Negative if smart bomb active or boss exploding ; consider_exploding_boss &1ebf c0 05 CPY #&05 &1ec1 f0 06 BEQ &1ec9 ; explode_enemy # Only one part of boss counts towards boss damage &1ec3 a9 ff LDA #&ff &1ec5 85 72 STA &72 ; smart_bomb_or_boss_active # Set to negative to indicate boss is exploding &1ec7 85 c5 STA &c5 ; smart_bomb_timer # Set to &ff to start smart bomb on next frame ; explode_enemy &1ec9 a9 00 LDA #&00 # Add to player one's score &1ecb 86 74 STX &74 ; tmp_x &1ecd e0 15 CPX #&15 &1ecf 30 02 BMI &1ed3 ; not_player_two ; explode_enemy_by_player_two &1ed1 a9 07 LDA #&07 # Add to player two's score ; not_player_two &1ed3 85 73 STA &73 ; player_score_offset &1ed5 a9 ff LDA #&ff # Set to negative to indicate enemy is exploding &1ed7 99 22 00 STA &0022,Y ; players_or_enemies_energy + 2 &1eda b6 2a LDX &2a,Y ; players_or_enemies_type + 2 &1edc bd 00 25 LDA &2500,X ; sprite_sizes_and_data # Top three bits of first byte set score &1edf 4a LSR A &1ee0 4a LSR A &1ee1 4a LSR A &1ee2 4a LSR A &1ee3 4a LSR A &1ee4 a8 TAY &1ee5 b9 07 22 LDA &2207,Y ; score_for_destroying_enemy_digits &1ee8 18 CLC &1ee9 65 73 ADC &73 ; player_score_offset &1eeb aa TAX &1eec b9 00 22 LDA &2200,Y ; score_for_destroying_enemy_values &1eef 20 4b 22 JSR &224b ; increase_score &1ef2 20 c2 0b JSR &0bc2 ; play_explosion_sound # Play sound for destroying enemy &1ef5 a6 74 LDX &74 ; tmp_x ; leave &1ef7 60 RTS ; consider_next_enemy &1ef8 88 DEY &1ef9 10 8c BPL &1e87 ; check_for_collision_with_laser_loop ; set_laser_screen_address &1efb b5 40 LDA &40,X ; lasers_screen_offset_low &1efd 18 CLC &1efe 69 d8 ADC #&d8 &1f00 85 00 STA &00 ; screen_address_low &1f02 a5 94 LDA &94 ; buffer_to_use # Zero for buffer one, non-zero for buffer two &1f04 d0 07 BNE &1f0d ; use_buffer_two &1f06 a9 4e LDA #&4e ; set_screen_address_high &1f08 75 41 ADC &41,X ; lasers_screen_offset_high &1f0a 85 01 STA &01 ; screen_address_high &1f0c 60 RTS ; use_buffer_two &1f0d a9 67 LDA #&67 &1f0f d0 f7 BNE &1f08 ; set_screen_address_high # Always branches ; add_multidirectional_laser &1f11 b5 42 LDA &42,X ; lasers_x # Find two consecutive empty slots &1f13 15 46 ORA &46,X ; lasers_x + 4 &1f15 f0 16 BEQ &1f2d ; found_slots_for_multidirectional_laser &1f17 8a TXA &1f18 18 CLC &1f19 69 08 ADC #&08 &1f1b aa TAX &1f1c b5 42 LDA &42,X ; lasers_x &1f1e 15 46 ORA &46,X ; lasers_x + 4 &1f20 f0 0b BEQ &1f2d ; found_slots_for_multidirectional_laser &1f22 8a TXA &1f23 18 CLC &1f24 69 08 ADC #&08 &1f26 aa TAX &1f27 b5 42 LDA &42,X ; lasers_x &1f29 15 46 ORA &46,X ; lasers_x + 4 &1f2b d0 0b BNE &1f38 ; to_consider_changing_laser_damage ; found_slots_for_multidirectional_laser &1f2d 20 58 21 JSR &2158 ; add_laser # Add laser to first slot &1f30 8a TXA &1f31 18 CLC &1f32 69 04 ADC #&04 &1f34 aa TAX &1f35 20 58 21 JSR &2158 ; add_laser # Add laser to second slot ; to_consider_changing_laser_damage &1f38 4c 53 1d JMP &1d53 ; consider_changing_laser_damage ; plot_antimatter_torpedoes &1f3b b5 42 LDA &42,X ; lasers_x &1f3d f0 38 BEQ &1f77 ; consider_next_antimatter_torpedo &1f3f 18 CLC &1f40 b5 40 LDA &40,X ; lasers_screen_offset_low &1f42 69 08 ADC #&08 &1f44 95 40 STA &40,X ; lasers_screen_offset_low &1f46 90 02 BCC &1f4a ; skip_page &1f48 f6 41 INC &41,X ; lasers_screen_offset_high ; skip_page &1f4a b5 42 LDA &42,X ; lasers_x &1f4c 18 CLC &1f4d 69 02 ADC #&02 &1f4f 95 42 STA &42,X ; lasers_x &1f51 c9 66 CMP #&66 &1f53 30 06 BMI &1f5b ; antimatter_torpedo_is_on_screen &1f55 a9 00 LDA #&00 # Set to zero to remove torpedo &1f57 95 42 STA &42,X ; lasers_x &1f59 f0 1c BEQ &1f77 ; consider_next_antimatter_torpedo # Always branches ; antimatter_torpedo_is_on_screen &1f5b 20 83 1e JSR &1e83 ; check_for_collision_with_laser &1f5e 20 fb 1e JSR &1efb ; set_laser_screen_address &1f61 a9 0f LDA #&0f ; 1111 &1f63 a0 00 LDY #&00 &1f65 91 00 STA (&00),Y ; screen_address &1f67 c8 INY &1f68 91 00 STA (&00),Y ; screen_address &1f6a c8 INY &1f6b 91 00 STA (&00),Y ; screen_address &1f6d c8 INY &1f6e 91 00 STA (&00),Y ; screen_address &1f70 a0 09 LDY #&09 &1f72 91 00 STA (&00),Y ; screen_address &1f74 c8 INY &1f75 91 00 STA (&00),Y ; screen_address ; consider_next_antimatter_torpedo &1f77 ca DEX # Move to previous slot &1f78 ca DEX &1f79 ca DEX &1f7a ca DEX &1f7b e4 73 CPX &73 ; first_laser_offset &1f7d 10 bc BPL &1f3b ; plot_antimatter_torpedoes &1f7f 60 RTS ; remove_explosion &1f80 a9 00 LDA #&00 # Set to zero to remove explosion &1f82 95 10 STA &10,X ; players_or_enemies_x ; leave &1f84 60 RTS ; explosion_sprites &1f85 08 10 0c 10 ; plot_explosion &1f89 b5 10 LDA &10,X ; players_or_enemies_x &1f8b 29 fe AND #&fe &1f8c 95 10 STA &10,X ; players_or_enemies_x &1f8f b5 20 LDA &20,X ; players_or_enemies_energy &1f91 29 07 AND #&07 &1f93 4a LSR A &1f94 aa TAX &1f95 bc 85 1f LDY &1f85,X ; explosion_sprites &1f98 a6 75 LDX &75 ; sprite_to_update &1f9a 20 0a 20 JSR &200a ; plot_sprite_Y &1f9d a6 75 LDX &75 ; sprite_to_update &1f9f d6 20 DEC &20,X ; players_or_enemies_energy &1fa1 b5 20 LDA &20,X ; players_or_enemies_energy &1fa3 c9 f8 CMP #&f8 &1fa5 10 dd BPL &1f84 ; leave &1fa7 e0 00 CPX #&00 &1fa9 d0 0f BNE &1fba ; not_player_one ; remove_player_one &1fab a9 0f LDA #&0f &1fad a2 00 LDX #&00 &1faf 86 10 STX &10 ; players_or_enemies_x ; remove_player &1fb1 95 18 STA &18,X ; players_or_enemies_y &1fb3 95 20 STA &20,X ; players_or_enemies_energy &1fb5 a9 a0 LDA #&a0 # Set to negative to set player moving onto screen &1fb7 95 30 STA &30,X ; players_or_enemies_timer ; leave &1fb9 60 RTS ; not_player_one &1fba e0 01 CPX #&01 &1fbc d0 c2 BNE &1f80 ; remove_explosion ; remove_player_two &1fbe a9 0a LDA #&0a &1fc0 85 11 STA &11 ; players_or_enemies_x + 1 &1fc2 a2 01 LDX #&01 &1fc4 d0 eb BNE &1fb1 ; remove_player # Always branches ; plot_player_or_enemy &1fc6 b5 10 LDA &10,X ; players_or_enemies_x &1fc8 f0 ef BEQ &1fb9 ; leave &1fca b5 18 LDA &18,X ; players_or_enemies_y &1fcc 29 fe AND #&fe &1fce 85 73 STA &73 ; tmp &1fd0 0a ASL A &1fd1 0a ASL A &1fd2 65 73 ADC &73 ; tmp &1fd4 0a ASL A &1fd5 85 00 STA &00 ; screen_address_low &1fd7 a9 00 LDA #&00 &1fd9 2a ROL A &1fda 06 00 ASL &00 ; screen_address_low &1fdc 2a ROL A &1fdd 06 00 ASL &00 ; screen_address_low &1fdf 2a ROL A &1fe0 85 01 STA &01 ; screen_address_high &1fe2 b5 10 LDA &10,X ; players_or_enemies_x &1fe4 29 fe AND #&fe &1fe6 85 74 STA &74 ; x_column &1fe8 c9 1c CMP #&1c &1fea 10 02 BPL &1fee ; skip_floor &1fec a9 1c LDA #&1c ; skip_floor &1fee 18 CLC &1fef 65 00 ADC &00 ; screen_address_low &1ff1 90 02 BCC &1ff5 ; skip_page &1ff3 e6 01 INC &01 ; screen_address_high ; skip_page &1ff5 0a ASL A &1ff6 26 01 ROL &01 ; screen_address_high &1ff8 0a ASL A &1ff9 85 00 STA &00 ; screen_address_low &1ffb 85 0c STA &0c ; player_screen_offset_low &1ffd a5 01 LDA &01 ; screen_address_high &1fff 2a ROL A &2000 85 01 STA &01 ; screen_address_high &2002 85 0d STA &0d ; player_screen_offset_high &2004 b5 20 LDA &20,X ; players_or_enemies_energy # Negative if player or enemy is exploding &2006 30 81 BMI &1f89 ; plot_explosion &2008 b4 28 LDY &28,X ; players_or_enemies_type ; plot_sprite_Y &200a b9 01 24 LDA &2401,Y ; sprite_and_mask_addresses + 1 &200d 85 09 STA &09 ; sprite_address_high &200f b9 00 24 LDA &2400,Y ; sprite_and_mask_addresses &2012 85 08 STA &08 ; sprite_address_low &2014 b9 03 24 LDA &2403,Y ; sprite_and_mask_addresses + 3 &2017 85 07 STA &07 ; mask_address_high &2019 b9 02 24 LDA &2402,Y ; sprite_and_mask_addresses + 2 &201c 85 06 STA &06 ; mask_address_low &201e b9 01 25 LDA &2501,Y ; sprite_sizes_and_data + 1 &2021 8d c2 20 STA &20c2 ; sprite_width_in_bytes_aligned &2024 8d 40 21 STA &2140 ; sprite_width_in_bytes_unaligned &2027 18 CLC &2028 69 01 ADC #&01 &202a 4a LSR A &202b 4a LSR A &202c 85 c0 STA &c0 ; sprite_width &202e b9 00 25 LDA &2500,Y ; sprite_sizes_and_data # Low two bits of first byte are height &2031 29 03 AND #&03 &2033 8d ac 20 STA &20ac ; sprite_height_in_groups &2036 b5 10 LDA &10,X ; players_or_enemies_x &2038 c9 68 CMP #&68 &203a 10 26 BPL &2062 ; leave # Leave if sprite starts beyond right of screen &203c 18 CLC &203d 65 c0 ADC &c0 ; sprite_width &203f c9 6a CMP #&6a # Does the sprite cross the right of the screen? &2041 30 12 BMI &2055 ; skip_clipping_to_right &2043 38 SEC &2044 a9 68 LDA #&68 &2046 e5 74 SBC &74 ; x_column &2048 0a ASL A &2049 0a ASL A &204a 38 SEC &204b e9 01 SBC #&01 &204d 8d 40 21 STA &2140 ; sprite_width_in_bytes_unaligned &2050 8d c2 20 STA &20c2 ; sprite_width_in_bytes_aligned &2053 10 2e BPL &2083 ; plot_full_sprite # Always branches ; skip_clipping_to_right &2055 b5 10 LDA &10,X ; players_or_enemies_x &2057 c9 1c CMP #&1c &2059 10 28 BPL &2083 ; plot_full_sprite # Does the sprite cross the left of the screen? &205b 18 CLC &205c 65 c0 ADC &c0 &205e c9 1e CMP #&1e &2060 10 01 BPL &2063 ; plot_sprite_clipped_to_left ; leave &2062 60 RTS # Leave if sprite ends before left of screen ; plot_sprite_clipped_to_left &2063 38 SEC &2064 a9 1c LDA #&1c &2066 e5 74 SBC &74 ; x_column &2068 0a ASL A &2069 0a ASL A &206a 85 73 STA &73 ; columns_to_skip &206c 18 CLC &206d 65 08 ADC &08 ; sprite_address_low &206f 85 08 STA &08 ; sprite_address_low &2071 a5 73 LDA &73 ; columns_to_skip &2073 65 06 ADC &06 ; mask_address_low &2075 85 06 STA &06 ; mask_address_low &2077 38 SEC &2078 b9 01 25 LDA &2501,Y ; sprite_sizes_and_data + 1 &207b e5 73 SBC &73 ; columns_to_skip &207d 8d c2 20 STA &20c2 ; sprite_width_in_bytes_aligned &2080 8d 40 21 STA &2140 ; sprite_width_in_bytes_unaligned ; plot_full_sprite &2083 b5 10 LDA &10,X ; players_or_enemies_x &2085 29 01 AND #&01 &2087 f0 0d BEQ &2096 ; is_even ; is_odd &2089 18 CLC &208a a5 07 LDA &07 ; mask_address_high &208c 69 04 ADC #&04 # Add &400 to sprite and mask addresses for odd x &208e 85 07 STA &07 ; mask_address_high &2090 a5 09 LDA &09 ; sprite_address_high &2092 69 04 ADC #&04 &2094 85 09 STA &09 ; sprite_address_high ; is_even &2096 a5 00 LDA &00 ; screen_address_low &2098 18 CLC &2099 69 d8 ADC #&d8 &209b 85 00 STA &00 ; screen_address_low &209d a9 4e LDA #&4e &209f a4 94 LDY &94 ; buffer_to_use # Zero for buffer one, non-zero for buffer two &20a1 f0 02 BEQ &20a5 ; use_buffer_one ; use_buffer_two &20a3 a9 67 LDA #&67 ; use_buffer_one &20a5 65 01 ADC &01 ; screen_address_high &20a7 85 01 STA &01 ; screen_address_high &20a9 b5 18 LDA &18,X ; players_or_enemies_y &20ab a2 00 LDX #&00 # actually LDX sprite_height_in_groups &20ad e0 02 CPX #&02 &20af 30 0c BMI &20bd ; skip_clipping_to_bottom &20b1 c9 19 CMP #&19 &20b3 30 08 BMI &20bd ; skip_clipping_to_bottom &20b5 f0 05 BEQ &20bc ; skip_one_group &20b7 c9 1b CMP #&1b &20b9 30 01 BMI &20bc ; skip_one_group ; skip_two_groups &20bb ca DEX ; skip_one_group &20bc ca DEX ; skip_clipping_to_bottom &20bd 29 01 AND #&01 &20bf d0 21 BNE &20e2 ; plot_sprite_unaligned ; plot_sprite_aligned_group_loop &20c1 a0 00 LDY #&00 # actually LDY sprite_width_in_bytes_aligned ; plot_sprite_aligned_byte_loop &20c3 b1 00 LDA (&00),Y ; screen_address &20c5 31 06 AND (&06),Y ; mask_address &20c7 11 08 ORA (&08),Y ; sprite_address &20c9 91 00 STA (&00),Y ; screen_address &20cb 88 DEY &20cc 10 f5 BPL &20c3 ; plot_sprite_aligned_byte_loop &20ce e6 09 INC &09 ; sprite_address_high &20d0 e6 07 INC &07 ; mask_address_high &20d2 a5 00 LDA &00 ; screen_address_low &20d4 69 40 ADC #&40 # Move down a group &20d6 85 00 STA &00 ; screen_address_low &20d8 a5 01 LDA &01 ; screen_address_high &20da 69 01 ADC #&01 &20dc 85 01 STA &01 ; screen_address_high &20de ca DEX &20df 10 e0 BPL &20c1 ; plot_sprite_aligned_group_loop &20e1 60 RTS ; plot_sprite_unaligned &20e2 a5 00 LDA &00 ; screen_address_low &20e4 18 CLC &20e5 69 04 ADC #&04 &20e7 85 00 STA &00 ; screen_address_low ; plot_sprite_unaligned_group_loop &20e9 a5 00 LDA &00 ; screen_address_low &20eb 69 38 ADC #&38 &20ed 85 0a STA &0a ; lower_screen_address_low &20ef a5 01 LDA &01 ; screen_address_high &20f1 69 01 ADC #&01 &20f3 85 0b STA &0b ; lower_screen_address_high &20f5 a0 00 LDY #&00 ; plot_sprite_unaligned_byte_loop &20f7 b1 00 LDA (&00),Y ; screen_address # Plot four bytes in top group &20f9 31 06 AND (&06),Y ; mask_address &20fb 11 08 ORA (&08),Y ; sprite_address &20fd 91 00 STA (&00),Y ; screen_address &20ff c8 INY &2100 b1 00 LDA (&00),Y ; screen_address &2102 31 06 AND (&06),Y ; mask_address &2104 11 08 ORA (&08),Y ; sprite_address &2106 91 00 STA (&00),Y ; screen_address &2108 c8 INY &2109 b1 00 LDA (&00),Y ; screen_address &210b 31 06 AND (&06),Y ; mask_address &210d 11 08 ORA (&08),Y ; sprite_address &210f 91 00 STA (&00),Y ; screen_address &2111 c8 INY &2112 b1 00 LDA (&00),Y ; screen_address &2114 31 06 AND (&06),Y ; mask_address &2116 11 08 ORA (&08),Y ; sprite_address &2118 91 00 STA (&00),Y ; screen_address &211a c8 INY &211b b1 0a LDA (&0a),Y ; lower_screen_address # Plot four bytes in bottom group &211d 31 06 AND (&06),Y ; mask_address &211f 11 08 ORA (&08),Y ; sprite_address &2121 91 0a STA (&0a),Y ; lower_screen_address &2123 c8 INY &2124 b1 0a LDA (&0a),Y ; lower_screen_address &2126 31 06 AND (&06),Y ; mask_address &2128 11 08 ORA (&08),Y ; sprite_address &212a 91 0a STA (&0a),Y ; lower_screen_address &212c c8 INY &212d b1 0a LDA (&0a),Y ; lower_screen_address &212f 31 06 AND (&06),Y ; mask_address &2131 11 08 ORA (&08),Y ; sprite_address &2133 91 0a STA (&0a),Y ; lower_screen_address &2135 c8 INY &2136 b1 0a LDA (&0a),Y ; lower_screen_address &2138 31 06 AND (&06),Y ; mask_address &213a 11 08 ORA (&08),Y ; sprite_address &213c 91 0a STA (&0a),Y ; lower_screen_address &213e c8 INY &213f c0 00 CPY #&00 # actually CPY sprite_width_in_bytes_unaligned &2141 30 b4 BMI &20f7 ; plot_sprite_unaligned_byte_loop &2143 e6 09 INC &09 ; sprite_address_high &2145 e6 07 INC &07 ; mask_adress_high &2147 18 CLC &2148 a5 00 LDA &00 ; screen_address_low &214a 69 40 ADC #&40 # Move down a group &214c 85 00 STA &00 ; screen_address_low &214e a5 01 LDA &01 ; screen_address_high &2150 69 01 ADC #&01 &2152 85 01 STA &01 ; screen_address_high &2154 ca DEX &2155 10 92 BPL &20e9 ; plot_sprite_unaligned_group_loop &2157 60 RTS ; add_laser &2158 18 CLC &2159 b9 18 00 LDA &0018,Y ; players_or_enemies_y &215c 29 01 AND #&01 &215e f0 0a BEQ &216a ; is_aligned ; is_unaligned &2160 a9 a0 LDA #&a0 &2162 65 0c ADC &0c ; player_screen_offset_low &2164 95 40 STA &40,X ; lasers_screen_offset_low &2166 a9 02 LDA #&02 &2168 d0 08 BNE &2172 ; set_laser_screen_offset_high # Always branches ; is_aligned &216a a5 0c LDA &0c ; player_screen_offset_low &216c 69 64 ADC #&64 &216e 95 40 STA &40,X ; lasers_screen_offset_low &2170 a9 01 LDA #&01 ; set_laser_screen_offset_high &2172 65 0d ADC &0d ; player_screen_offset_high &2174 95 41 STA &41,X ; lasers_screen_offset_high &2176 b9 18 00 LDA &0018,Y ; players_or_enemies_y &2179 69 04 ADC #&04 &217b 95 43 STA &43,X ; lasers_y &217d b9 10 00 LDA &0010,Y ; players_or_enemies_x &2180 69 0a ADC #&0a &2182 95 42 STA &42,X ; lasers_x &2184 b9 0e 00 LDA &000e,Y ; players_selected_weapon &2187 4a LSR A &2188 4a LSR A &2189 18 CLC &218a 69 01 ADC #&01 # Use envelope 1 for standard, 2 for multidirectional &218c 84 73 STY &73 ; tmp_y &218e 86 74 STX &74 ; tmp_x &2190 c9 03 CMP #&03 &2192 10 07 BPL &219b ; play_sound_for_torpedo ; play_sound_for_laser &2194 a0 00 LDY #&00 # Pitch &2196 a2 02 LDX #&02 # Duration &2198 4c cd 0b JMP &0bcd ; play_sound_with_envelope_pitch_and_duration ; play_sound_for_torpedo &219b 18 CLC &219c 69 01 ADC #&01 # Use envelope 4 for torpedo &219e 4c c4 0b JMP &0bc4 ; play_sound_with_envelope ; weapon_slot_buffer_addresses_low &21a1 b8 68 ; weapon_slot_buffer_two_addresses_high &21a3 7d 7e ; weapon_slot_buffer_one_addresses_high &21a5 64 65 ; plot_weapon_slots &21a7 b9 a1 21 LDA &21a1,Y ; weapon_slot_buffer_addresses_low &21aa 85 00 STA &00 ; buffer_two_address_low &21ac 85 73 STA &73 ; buffer_one_address_low &21ae b9 a3 21 LDA &21a3,Y ; weapon_slot_buffer_two_addresses_high &21b1 85 01 STA &01 ; buffer_two_address_high &21b3 b9 a5 21 LDA &21a5,Y ; weapon_slot_buffer_one_addresses_high &21b6 85 74 STA &74 ; buffer_one_address_high &21b8 b9 c6 00 LDA &00c6,Y ; players_maximum_weapon &21bb 85 77 STA &77 ; maximum_weapon &21bd a2 00 LDX #&00 ; plot_weapon_slots_loop &21bf a9 00 LDA #&00 ; &0700 = weapon_slot_sprites &21c1 85 75 STA &75 ; sprite_address_low &21c3 a9 07 LDA #&07 &21c5 85 76 STA &76 ; sprite_address_high &21c7 e4 77 CPX &77 ; maximum_weapon &21c9 10 0c BPL &21d7 ; plot_weapon_slot # Use empty slot if weapon not collected &21cb 8a TXA # Otherwise use sprite for weapon &21cc 18 CLC &21cd 69 01 ADC #&01 &21cf 0a ASL A &21d0 0a ASL A &21d1 0a ASL A &21d2 0a ASL A &21d3 65 75 ADC &75 ; sprite_address_low &21d5 85 75 STA &75 ; sprite_address_low ; plot_weapon_slot &21d7 a0 0f LDY #&0f ; plot_weapon_slot_loop &21d9 b1 75 LDA (&75),Y ; sprite_address &21db 91 00 STA (&00),Y ; buffer_two_address &21dd 91 73 STA (&73),Y ; buffer_one_address &21df 88 DEY &21e0 10 f7 BPL &21d9 ; plot_weapon_slot_loop &21e2 a5 00 LDA &00 ; buffer_two_address_low &21e4 18 CLC &21e5 69 10 ADC #&10 &21e7 85 00 STA &00 ; buffer_two_address_low &21e9 85 73 STA &73 ; buffer_one_address_low &21eb e8 INX &21ec e0 03 CPX #&03 &21ee d0 cf BNE &21bf ; plot_weapon_slots_loop &21f0 60 RTS ; unused &21f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; score_for_destroying_enemy_values # 0: 1 ; 0 1 2 3 4 5 6 # 1: 5 &2200 10 28 08 28 08 28 08 # 2: 10 ; score_for_destroying_enemy_digits # 3: 50 ; 0 1 2 3 4 5 6 # 4: 100 &2207 06 06 05 05 04 04 03 # 5: 500 # 6: 1000 (unused) ; explosion_and_firing_sound ; chan vol pitch dur &220e 12 00 00 00 00 00 00 00 ; bonus_sound ; chan vol pitch dur &2216 13 00 04 00 64 00 05 00 # Use channel 3 for bonus ; load_cu_string &221e 4c 4f 41 44 20 43 55 0d ; "LOAD CU" ; unused &2226 00 00 00 00 00 00 00 00 ; check_for_keypress &222e a0 ff LDY #&ff &2230 a9 81 LDA #&81 ; Scan for a particular key &2232 4c f4 ff JMP &fff4 ; OSBYTE ; set_colour &2235 8d 21 fe STA &fe21 ; video ULA palette register &2238 09 10 ORA #&10 &223a 8d 21 fe STA &fe21 ; video ULA palette register &223d 09 40 ORA #&40 &223f 8d 21 fe STA &fe21 ; video ULA palette register &2242 29 ef AND #&ef &2244 8d 21 fe STA &fe21 ; video ULA palette register ; leave &2247 60 RTS ; to_consider_spawning_enemies &2248 4c 89 23 JMP &2389 ; consider_spawning_enemies ; increase_score &224b a4 9b LDY &9b ; level_number &224d c0 04 CPY #&04 &224f 30 01 BMI &2252 ; skip_multiplication &2251 ca DEX # Score ten times as much on level 5 onwards ; skip_multiplication &2252 a0 06 LDY #&06 ; increase_score_loop &2254 18 CLC &2255 75 82 ADC &82,X ; players_score &2257 95 82 STA &82,X ; players_score &2259 c9 50 CMP #&50 ; 8 * 10 &225b 30 ea BMI &2247 ; leave &225d 38 SEC &225e e9 50 SBC #&50 ; 8 * 10 &2260 95 82 STA &82,X ; players_score &2262 a9 08 LDA #&08 ; 8 * 1 &2264 ca DEX &2265 88 DEY &2266 10 ec BPL &2254 ; increase_score_loop &2268 60 RTS ; to_title_screen_after_checking_for_high_score &2269 4c a9 22 JMP &22a9 ; title_screen_after_checking_for_high_score ; to_plot_string &226c 4c 96 27 JMP &2796 ; plot_string ; to_reset_screen_for_new_level &226f 4c 53 2a JMP &2a53 ; reset_screen_for_new_level ; plot_character &2272 85 a8 STA &a8 ; character_data &2274 a2 a8 LDX #&a8 ; &a8 = character_data &2276 a0 00 LDY #&00 &2278 a9 0a LDA #&0a ; Read character definition &227a 20 f1 ff JSR &fff1 ; OSWORD &227d a2 07 LDX #&07 ; plot_character_loop &227f 8a TXA &2280 a8 TAY &2281 b5 a9 LDA &a9,X ; character_data + 1 &2283 4a LSR A &2284 4a LSR A &2285 4a LSR A &2286 4a LSR A &2287 45 74 EOR &74 ; text_eor &2289 91 00 STA (&00),Y ; screen_address &228b 8a TXA &228c 18 CLC &228d 69 08 ADC #&08 &228f a8 TAY &2290 b5 a9 LDA &a9,X ; character_data + 1 &2292 29 0f AND #&0f &2294 45 74 EOR &74 ; text_eor &2296 91 00 STA (&00), screen_address &2298 ca DEX &2299 10 e4 BPL &227f ; plot_character_loop &229b a5 00 LDA &00 ; screen_address_low &229d 69 10 ADC #&10 &229f 85 00 STA &00 ; screen_address_low &22a1 90 02 BCC &22a5 ; leave &22a3 e6 01 INC &01 ; screen_address_high &22a5 60 RTS ; to_plot_high_score_screen &22a6 4c 55 23 JMP &2355 ; plot_high_score_screen ; title_screen_after_checking_for_high_score &22a9 a9 00 LDA #&00 &22ab 85 7a STA &7a ; title_screen_cooldown &22ad 20 38 0b JSR &0b38 ; check_for_high_score ; title_screen &22b0 20 6c 27 JSR &276c ; reset_screen ; title_screen_loop &22b3 a2 9d LDX #&9d ; SPACE &22b5 20 2e 22 JSR &222e ; check_for_keypress &22b8 b0 f9 BCS &22b3 ; title_screen_loop # Wait until SPACE is not pressed &22ba c6 7a DEC &7a ; title_screen_cooldown &22bc d0 03 BNE &22c1 ; not_high_score_screen &22be 4c 3c 23 JMP &233c ; high_score_screen ; not_high_score_screen &22c1 a2 08 LDX #&08 ; "L TO SKIP LEVEL" &22c3 20 bc 27 JSR &27bc ; delay &22c6 ad 02 2a LDA &2a02 ; maximum_level_reached &22c9 d0 01 BNE &22cc ; write_title_screen_strings_loop # If the first level hasn't been completed, &22cb ca DEX ; &07 ; "SPACE TO PLAY" # Skip writing "L TO SKIP LEVEL" ; write_title_screen_strings_loop &22cc 86 79 STX &79 ; string_id &22ce a0 00 LDY #&00 # Start on level 1 by default &22d0 84 9b STY &9b ; level_number &22d2 ad 01 2a LDA &2a01 ; game_type &22d5 4a LSR A &22d6 69 04 ADC #&04 ; "1> KEYBOARD" &22d8 c5 79 CMP &79 ; string_id &22da d0 02 BNE &22de ; skip_highlighting &22dc a0 ff LDY #&ff # Highlight selected game type ; skip_highlighting &22de a6 79 LDX &79 ; string_id &22e0 20 96 27 JSR &2796 ; plot_string &22e3 a6 79 LDX &79 ; string_id &22e5 ca DEX &22e6 30 09 BMI &22f1 ; finishing_writing_strings &22e8 e0 01 CPX #&01 ; "CYBORG WARRIORS" - 1 &22ea 10 e0 BPL &22cc ; write_title_screen_strings_loop &22ec ad 00 2a LDA &2a00 ; sound_suppressed # If sound suppressed, &22ef d0 db BNE &22cc ; write_title_screen_strings_loop # Bug: endless rewriting of "SOUND ON" and "OFF" ; finishing_writing_strings &22f1 a0 04 LDY #&04 ; check_for_game_type_keys_loop &22f3 84 79 STY &79 ; key_offset &22f5 be 20 27 LDX &2720,Y ; number_keys &22f8 20 2e 22 JSR &222e ; check_for_keypress # Returns carry set if key pressed &22fb a4 79 LDY &79 ; key_offset &22fd 90 03 BCC &2302 ; key_not_pressed &22ff 8c 01 2a STY &2a01 ; game_type ; key_not_pressed &2302 88 DEY &2303 88 DEY &2304 10 ed BPL &22f3 ; check_for_game_type_keys_loop &2306 a2 ae LDX #&ae ; S &2308 20 2e 22 JSR &222e ; check_for_keypress &230b 90 08 BCC &2315 ; check_if_l_pressed # If S pressed, &230d ad 00 2a LDA &2a00 ; sound_suppressed &2310 49 ff EOR #&ff # toggle sound suppression &2312 20 74 03 JSR &0374 ; toggle_sound_suppressed ; check_if_l_pressed &2315 a2 a9 LDX #&a9 ; L &2317 20 2e 22 JSR &222e ; check_for_keypress &231a 90 05 BCC &2321 ; check_if_space_pressed # If L pressed, &231c ad 02 2a LDA &2a02 ; maximum_level_reached &231f d0 46 BNE &2367 ; start_from_maximum_level_reached # start from maximum level reached, if set ; check_if_space_pressed &2321 a2 9d LDX #&9d ; SPACE &2323 20 2e 22 JSR &222e ; check_for_keypress &2326 90 8b BCC &22b3 ; title_screen_loop # If SPACE pressed, &2328 a9 00 LDA #&00 # Players start with only standard laser &232a 85 c6 STA &c6 ; players_maximum_weapon &232c 85 c7 STA &c7 ; players_maximum_weapon + 1 &232e ae 01 2a LDX &2a01 ; game_type &2331 bd f8 29 LDA &29f8,X ; lives_by_game_type # Set player lives depending on game type &2334 85 9c STA &9c ; players_lives &2336 bd f9 29 LDA &29f9,X ; lives_by_game_type + 1 &2339 85 9d STA &9d ; players_lives + 1 &233b 60 RTS ; high_score_screen &233c 20 55 23 JSR &2355 ; plot_high_score_screen ; high_score_screen_loop &233f c6 7a DEC &7a ; title_screen_cooldown &2341 d0 03 BNE &2346 ; not_title_screen ; to_title_screen &2343 4c b0 22 JMP &22b0 ; title_screen ; not_title_screen &2346 a2 9d LDX #&9d ; SPACE &2348 20 bc 27 JSR &27bc ; delay &234b 20 bc 27 JSR &27bc ; delay &234e 20 2e 22 JSR &222e ; check_for_keypress # If SPACE pressed, return to title screen &2351 b0 f0 BCS &2343 ; to_title_screen &2353 90 ea BCC &233f ; high_score_screen_loop # Always branches ; plot_high_score_screen &2355 20 6c 27 JSR &276c ; reset_screen &2358 a2 0a LDX #&0a ; "HIGH SCORE" @ &4f90 &235a a0 00 LDY #&00 &235c 20 96 27 JSR &2796 ; plot_string &235f 4c 40 07 JMP &0740 ; to_write_high_scores ; leave_after_decreasing_spawn_cooldown &2362 ce 66 23 DEC &2366 ; spawn_cooldown ; leave &2365 60 RTS ; spawn_cooldown &2366 00 ; start_from_maximum_level_reached &2367 ad 02 2a LDA &2a02 ; maximum_level_reached &236a 85 9b STA &9b ; level_number &236c ad b4 2a LDA &2ab4 ; initial_players_lives &236f f0 07 BEQ &2378 ; skip_player_one # If player one completed level, &2371 ad b2 2a LDA &2ab2 ; initial_players_maximum_weapon &2374 85 c6 STA &c6 ; players_maximum_weapon &2376 a9 04 LDA #&04 # Player one starts with four lives ; skip_player_one &2378 85 9c STA &9c ; players_lives &237a ad b5 2a LDA &2ab5 ; initial_players_lives + 1 &237d f0 07 BEQ &2386 ; skip_player_two # If player two completed level, &237f ad b3 2a LDA &2ab3 ; initial_players_maximum_weapon + 1 &2382 85 c7 STA &c7 ; players_maximum_weapon + 1 &2384 a9 04 LDA #&04 # Player two starts with four lives &2386 85 9d STA &9d ; players_lives + 1 ; skip_player_two &2388 60 RTS ; consider_spawning_enemies # Called with X = enemy for each active enemy &2389 b5 12 LDA &12,X ; player_or_enemies_x + 2 &238b c9 1c CMP #&1c &238d 30 d6 BMI &2365 ; leave # Leave if enemy if beyond left of screen &238f c9 5e CMP #&5e &2391 10 d2 BPL &2365 ; leave # Leave if enemy if beyond right of screen &2393 b5 7c LDA &7c,X ; enemies_spawn_type &2395 f0 ce BEQ &2365 ; leave # Leave if enemy doesn't spawn &2397 a5 70 LDA &70 ; frame_counter &2399 29 03 AND #&03 &239b 18 CLC &239c 75 7c ADC &7c,X ; enemies_spawn_type &239e a8 TAY &239f b9 3c 27 LDA &273c,Y ; type_of_enemy_to_spawn_table - 4 &23a2 85 73 STA &73 ; spawn_type &23a4 ad 66 23 LDA &2366 ; spawn_cooldown &23a7 d0 b9 BNE &2362 ; leave_after_decreasing_spawn_cooldown &23a9 a9 10 LDA #&10 &23ab 8d 66 23 STA &2366 ; spawn_cooldown &23ae a0 05 LDY #&05 ; find_slot_for_spawn &23b0 b9 12 00 LDA &0012,Y ; player_or_enemies_x + 2 # Zero if slot is empty &23b3 f0 04 BEQ &23b9 ; found_slot_for_spawn &23b5 88 DEY &23b6 10 f8 BPL &23b0 ; find_slot_for_spawn &23b8 60 RTS ; found_slot_for_spawn &23b9 b5 1a LDA &1a,X ; players_or_enemies_y + 2 &23bb 18 CLC &23bc 69 02 ADC #&02 &23be 99 1a 00 STA &001a,Y ; player_or_enemies_y + 2 &23c1 b5 12 LDA &12,X ; player_or_enemies_x + 2 &23c3 e9 01 SBC #&01 &23c5 29 fe AND #&fe &23c7 99 12 00 STA &0012,Y ; player_or_enemies_x + 2 &23ca a5 73 LDA &73 ; spawn_type &23cc 99 2a 00 STA &002a,Y ; players_or_enemies_type + 2 &23cf c9 2c CMP #&2c ; SPRITE_ROCKET &23d1 f0 08 BEQ &23db ; not_rocket &23d3 b9 12 00 LDA &0012,Y ; player_or_enemies_x + 2 &23d6 69 04 ADC #&04 &23d8 99 12 00 STA &0012,Y ; player_or_enemies_x + 2 ; not_rocket &23db a9 01 LDA #&01 &23dd 99 22 00 STA &0022,Y ; players_or_enemies_energy + 2 &23e0 a9 04 LDA #&04 &23e2 99 3a 00 STA &003a,Y ; enemies_height &23e5 a9 00 LDA #&00 &23e7 99 7c 00 STA &007c,Y ; enemies_spawn_type &23ea 60 RTS ; unused # &23eb - &23ff is a copy of some part of &248c - &24b4 &23eb 50 3e 68 3e 50 3e 68 3e 50 3e 68 3e 50 3e 68 3e &23fb 50 3e 68 3e 50 ; sprite_and_mask_addresses ; sl sh ml mh spr en sprite address mask address &2400 00 2e 30 2e ; &00 : &2e00 = sprite_player_one_even_group_0 &2e30 = mask_player_even_group_0 &2404 18 2e 30 2e ; &04 : &2e18 = sprite_player_two_even_group_0 &2e30 = mask_player_even_group_0 &2408 70 04 88 04 ; &08 : &0470 = sprite_explosion_one_group_0 &0488 = mask_explosion_one_group_0 &240c a0 04 b8 04 ; &0c : &04a0 = sprite_explosion_two_group_0 &04b8 = mask_explosion_two_group_0 &2410 d0 04 e8 04 ; &10 : &04d0 = sprite_explosion_three_group_0 &04e8 = mask_explosion_three_group_0 &2414 a8 2e c0 2e ; &14 &00 : &2ea8 = sprite_alien_even_group_0 &2ec0 = mask_alien_even_group_0 &2418 a8 2e c0 2e ; &18 &01 : &2ea8 = sprite_alien_even_group_0 &2ec0 = mask_alien_even_group_0 &241c d8 2e e8 2e ; &1c &02 : &2ed8 = sprite_ball_one_even_group_0 &2ee8 = mask_ball_even_group_0 &2420 00 36 e8 30 ; &20 &03 : &3600 = sprite_player_one_bonus_even_group_0 &30e8 = mask_player_bonus_even_group_0 &2424 00 38 e8 30 ; &24 &04 : &3800 = sprite_player_two_bonus_even_group_0 &30e8 = mask_player_bonus_even_group_0 &2428 d8 30 e8 2e ; &28 &05 : &30d8 = sprite_ball_two_even_group_0 &2ee8 = mask_ball_even_group_0 &242c 00 05 20 05 ; &2c &06 : &0500 = sprite_rocket_group_0 &0520 = mask_rocket_group_0 &2430 10 36 e8 36 ; &30 &07 : &3610 = sprite_diamond_even_group_0 &36e8 = mask_diamond_even_group_0 &2434 10 36 e8 36 ; &34 &08 : &3610 = sprite_diamond_even_group_0 &36e8 = mask_diamond_even_group_0 &2438 10 36 e8 36 ; &38 &09 : &3610 = sprite_diamond_even_group_0 &36e8 = mask_diamond_even_group_0 &243c d8 30 e8 2e ; &3c &0a : &30d8 = sprite_ball_two_even_group_0 &2ee8 = mask_ball_even_group_0 &2440 80 40 e8 30 ; &40 &0b : &4080 = sprite_drone_even_group_0 &30e8 = mask_player_bonus_even_group_0 &2444 28 36 48 36 ; &44 &0c : &3628 = sprite_claw_even_group_0 &3648 = mask_claw_even_group_0 &2448 68 36 80 36 ; &48 &0d : &3668 = sprite_segment_one_even_group_0 &3680 = mask_segment_one_even_group_0 &244c 98 36 b0 36 ; &4c &0e : &3698 = sprite_segment_two_even_group_0 &36b0 = mask_segment_two_even_group_0 &2450 c8 36 00 3e ; &50 &0f : &36c8 = sprite_legs_even_group_0 &3e00 = mask_legs_even_group_0 &2454 28 36 48 36 ; &54 &10 : &3628 = sprite_claw_even_group_0 &3648 = mask_claw_even_group_0 &2458 10 36 e8 36 ; &58 &11 : &3610 = sprite_diamond_even_group_0 &36e8 = mask_diamond_even_group_0 &245c 10 36 e8 36 ; &5c &12 : &3610 = sprite_diamond_even_group_0 &36e8 = mask_diamond_even_group_0 &2460 28 36 48 36 ; &60 &13 : &3628 = sprite_claw_even_group_0 &3648 = mask_claw_even_group_0 &2464 c8 36 00 3e ; &64 &14 : &36c8 = sprite_legs_even_group_0 &3e00 = mask_legs_even_group_0 &2468 d0 3e d0 42 ; &68 &15 : &3ed0 = sprite_mound_group_0 &42d0 = mask_mound_group_0 &246c d8 2e e8 2e ; &6c &16 : &2ed8 = sprite_ball_one_even_group_0 &2ee8 = mask_ball_even_group_0 &2470 10 38 e8 38 ; &70 &17 : &3810 = sprite_diamond_even_group_2 &38e8 = mask_diamond_even_group_2 &2474 10 38 e8 38 ; &74 &18 : &3810 = sprite_diamond_even_group_2 &38e8 = mask_diamond_even_group_2 &2478 10 38 e8 38 ; &78 &19 : &3810 = sprite_diamond_even_group_2 &38e8 = mask_diamond_even_group_2 &247c f0 40 e8 2e ; &7c &1a : &40f0 = sprite_ball_six_even_group_0 &2ee8 = mask_ball_even_group_0 &2480 e0 40 e8 2e ; &80 &1b : &40e0 = sprite_ball_five_even_group_0 &2ee8 = mask_ball_even_group_0 &2484 d0 3c e8 2e ; &84 &1c : &3cd0 = sprite_ball_four_even_group_0 - &400 &2ee8 = mask_ball_even_group_0 &2488 d0 40 e8 2e ; &88 &1d : &40d0 = sprite_ball_four_even_group_0 &2ee8 = mask_ball_even_group_0 &248c 20 3e 38 3e ; &8c &1e : &3e20 = sprite_balls_even_group_0 &3e38 = mask_balls_even_group_0 &2490 50 3e 68 3e ; &90 &1f : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &2494 50 3e 68 3e ; &94 &20 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &2498 50 3e 68 3e ; &98 &21 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &249c 50 3e 68 3e ; &9c &22 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24a0 50 3e 68 3e ; &a0 &23 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24a4 50 3e 68 3e ; &a4 &24 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24a8 50 3e 68 3e ; &a8 &25 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24ac 50 3e 68 3e ; &ac &26 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24b0 50 3e 68 3e ; &b0 &27 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24b4 50 3e 68 3e ; &b4 &28 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24b8 a8 2e c0 2e ; &b8 &29 : &2ea8 = sprite_alien_even_group_0 &2ec0 = mask_alien_even_group_0 &24bc 50 04 68 3d ; &bc &2a : &0450 = sprite_fireball_group_0 &3d68 = mask_platform_group_0 &24c0 50 04 68 3d ; &c0 &2b : &0450 = sprite_fireball_group_0 &3d68 = mask_platform_group_0 &24c4 80 3e e8 2e ; &c4 &2c : &3e80 = sprite_ball_three_even_group_0 &2ee8 = mask_ball_even_group_0 &24c8 80 3e e8 2e ; &c8 &2d : &3e80 = sprite_ball_three_even_group_0 &2ee8 = mask_ball_even_group_0 &24cc c8 36 00 3e ; &cc &2e : &36c8 = sprite_legs_even_group_0 &3e00 = mask_legs_even_group_0 &24d0 c8 36 00 3e ; &d0 &2f : &36c8 = sprite_legs_even_group_0 &3e00 = mask_legs_even_group_0 &24d4 68 39 68 3d ; &d4 &30 : &3968 = sprite_platform_group_0 &3d68 = mask_platform_group_0 &24d8 f8 2a f8 2e ; &d8 &31 : &2af8 = sprite_sparks_group_0 - &400 &2ef8 = mask_sparks_group_0 - &400 &24dc 10 39 e8 39 ; &dc &32 : &3910 = sprite_diamond_even_group_3 &39e8 = mask_diamond_even_group_3 &24e0 50 3e 68 3e ; &e0 &33 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24e4 50 3e 68 3e ; &e4 &34 : &3e50 = sprite_pillar_even_group_0 &3e68 = mask_pillar_even_group_0 &24e8 68 39 68 3d ; &e8 &35 : &3968 = sprite_platform_group_0 &3d68 = mask_platform_group_0 &24ec d0 3e d0 42 ; &ec &36 : &3ed0 = sprite_mound_group_0 &42d0 = mask_mound_group_0 &24f0 d0 3f d0 43 ; &f0 &37 : &3fd0 = sprite_cigar_group_0 &43d0 = mask_cigar_group_0 &24f4 d0 3f d0 43 ; &f4 &38 : &3fd0 = sprite_cigar_group_0 &43d0 = mask_cigar_group_0 &24f8 90 3e b0 3e ; &f8 &39 : &3e90 = sprite_head_even_group_0 &3eb0 = mask_head_even_group_0 &24fc 80 40 e8 30 ; &fc &3a : &4080 = sprite_drone_even_group_0 &30e8 = mask_player_bonus_even_group_0 ; &00 &3b ; (empty enemy) ; Sprite data ; =========== ; ; First byte: ; ; 842..... score (offset into lookup table) ; ...184.. type of enemy spawned (zero for no spawning) ; ......21 height in groups (+1) ; ; Second byte is the width of the sprite in bytes. ; ; Third byte sets initial vertical position: ; ; &01 - use value to set position ; &00 use low bits of frame counter to set position ; &80 use low and high bits of frame counter to set position ; ; Fourth byte sets energy ; sprite sizes and data ; sh w y st spr en &2500 03 17 00 00 ; &00 : player one &2504 03 17 00 00 ; &04 : player two &2508 02 17 00 00 ; &08 : explosion one &250c 02 17 00 00 ; &0c : explosion two &2510 03 17 00 00 ; &10 : explosion three &2514 23 17 16 02 ; &14 &00 : alien 2 energy score 5 &2518 23 17 06 02 ; &18 &01 : alien 2 energy score 5 &251c 41 0f 07 06 ; &1c &02 : ball one 6 energy score 10 &2520 01 0f 0e 04 ; &20 &03 : player one bonus 4 energy score 1 &2524 01 0f 14 04 ; &24 &04 : player two bonus 4 energy score 1 &2528 41 0f 02 02 ; &28 &05 : ball two 2 energy score 10 &252c 41 1f 80 02 ; &2c &06 : rocket 2 energy score 10 &2530 41 17 1c 04 ; &30 &07 : diamond top 4 energy score 10 &2534 41 17 1c 04 ; &34 &08 : diamond top 4 energy score 10 &2538 41 17 1c 04 ; &38 &09 : diamond top 4 energy score 10 &253c 41 0f 19 02 ; &3c &0a : ball two 2 energy score 10 &2540 41 0f 07 04 ; &40 &0b : drone 4 energy score 10 &2544 a7 1f 03 7f ; &44 &0c : claw indestructible score 500 spawn type &04 (rockets) &2548 a2 17 07 7f ; &48 &0d : segment one indestructible score 500 &254c a2 17 0f 7f ; &4c &0e : segment two indestructible score 500 &2550 a3 1f 0a 08 ; &50 &0f : legs 8 energy score 500 &2554 a7 1f 11 7f ; &54 &10 : claw indestructible score 500 spawn type &04 (rockets) &2558 63 17 0e 06 ; &58 &11 : diamond 6 energy score 50 &255c 63 17 0e 06 ; &5c &12 : diamond 6 energy score 50 &2560 83 1f 08 10 ; &60 &13 : claw 16 energy score 100 &2564 83 1f 08 7f ; &64 &14 : legs indestructible score 100 &2568 20 2f 00 00 ; &68 &15 : mound 0 energy score 5 &256c 41 0f 16 06 ; &6c &16 : ball one 6 energy score 10 &2570 41 17 02 04 ; &70 &17 : diamond bottom 4 energy score 10 &2574 41 17 02 04 ; &74 &18 : diamond bottom 4 energy score 10 &2578 41 17 02 04 ; &78 &19 : diamond bottom 4 energy score 10 &257c 41 0f 80 04 ; &7c &1a : ball six 4 energy score 10 spawned enemy &2580 41 0f 80 04 ; &80 &1b : ball five 4 energy score 10 spawned enemy &2584 41 0f 80 04 ; &84 &1c : ball four 4 energy score 10 spawned enemy &2588 41 0f 80 04 ; &88 &1d : ball four 4 energy score 10 spawned enemy &258c 8b 17 80 10 ; &8c &1e : balls 16 energy score 100 spawn type &08 (balls) &2590 a3 17 02 7f ; &90 &1f : pillar indestructible score 500 &2594 a3 17 11 7f ; &94 &20 : pillar indestructible score 500 &2598 a3 17 18 7f ; &98 &21 : pillar indestructible score 500 &259c a3 17 09 7f ; &9c &22 : pillar indestructible score 500 &25a0 a3 17 0d 7f ; &a0 &23 : pillar indestructible score 500 &25a4 a3 17 0d 7f ; &a4 &24 : pillar indestructible score 500 &25a8 a3 17 02 7f ; &a8 &25 : pillar indestructible score 500 &25ac a3 17 18 7f ; &ac &26 : pillar indestructible score 500 &25b0 a3 17 09 7f ; &b0 &27 : pillar indestructible score 500 &25b4 a3 17 11 7f ; &b4 &28 : pillar indestructible score 500 &25b8 a7 17 14 04 ; &b8 &29 : alien 4 energy score 500 &25bc 40 1f 00 01 ; &bc &2a : fireball 1 energy score 10 &25c0 40 1f 00 01 ; &c0 &2b : fireball 1 energy score 10 &25c4 41 0f 07 02 ; &c4 &2c : ball three 2 energy score 10 &25c8 41 0f 16 02 ; &c8 &2d : ball three 2 energy score 10 &25cc 87 1f 07 08 ; &cc &2e : legs 8 energy score 100 &25d0 87 1f 13 08 ; &d0 &2f : legs 8 energy score 100 &25d4 a0 5f 0a 7f ; &d4 &30 : platform indestructible score 500 &25d8 63 07 00 04 ; &d8 &31 : sparks 4 energy score 50 spawned enemy &25dc 8c 17 02 08 ; &dc &32 : diamond bottom tip 8 energy score 100 spawn type &0c (sparks) &25e0 a3 17 0a 7f ; &e0 &33 : pillar indestructible score 500 &25e4 a3 17 10 7f ; &e4 &34 : pillar indestructible score 500 &25e8 a0 5f 16 7f ; &e8 &35 : platform indestructible score 500 &25ec 20 2f 00 00 ; &ec &36 : mound 0 energy score 5 &25f0 60 2f 04 00 ; &f0 &37 : cigar 0 energy score 50 &25f4 60 2f 1c 00 ; &f4 &38 : cigar 0 energy score 50 &25f8 a2 1f 80 06 ; &f8 &39 : head 6 energy score 500 &25fc 41 0f 16 04 ; &fc &3a : drone 4 energy score 10 ; Level data ; ========== ; One byte per wave: ; ; 8....... invert vertical movement ; .4...... apply horizontal movement to enemies ; lasers do double damage on levels 5 - 7 ; ..218421 wave type ; level_waves_data ; 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 &2600 01 00 11 02 03 11 11 04 00 11 0b 11 05 05 11 0c 0c 11 04 09 10 11 11 0c 11 11 0d 0d 11 06 06 06 11 0e 0e 08 ; level 1 &2624 0a 04 07 14 14 15 11 8a 04 0f 0f 11 16 11 12 11 51 07 14 17 11 04 0f 0f 04 12 04 04 11 0a 04 17 14 04 11 13 ; level 2 &2648 04 11 5c 5d 62 63 47 54 04 10 10 11 04 11 64 5f 66 51 64 62 5d 47 51 5a 5a 44 59 51 64 67 66 67 5c 63 47 48 ; level 3 &266c 00 04 17 04 0c 06 04 0e 14 10 17 14 04 2a 06 29 04 11 58 51 11 04 06 1a 2b 2c 2b 2c 2b 2c 0f 2c 04 44 47 53 ; level 4 &2690 43 51 2e 04 2d 46 51 4b 51 2f 1a 1a 14 11 28 04 86 86 91 30 11 2d 31 46 59 51 71 40 41 4c 51 42 46 6a 46 48 ; level 5 &26b4 71 44 51 5c 62 5b 5f 5d 51 60 61 5e 5f 66 67 5b 5e 52 64 66 66 62 5b 5c 51 61 66 65 67 62 62 5c 51 52 47 53 ; level 6 &26d8 6e 51 71 72 6f 70 51 73 51 74 51 6a 51 75 44 51 47 4f 4f 51 4a 73 57 51 76 51 51 ca c4 73 70 11 73 51 76 48 ; level 7 &26fc 29 2a 2b 2c 37 38 3e 3a 3c 39 3d 3c 3b 3e 2b 3e 33 11 47 69 6a 6b 77 78 79 7a 7b 7c 7d 7e 6b 6a 78 7b 7e 53 ; level 8 ; number_keys &2720 cf 00 ; 1 &2722 ce 00 ; 2 &2724 ee 00 ; 3 ; unused &2726 87 6e 00 00 00 32 74 6c 61 67 00 88 14 00 00 00 &2736 ee 74 77 65 70 00 88 46 00 00 ; type_of_enemy_to_spawn_table &2740 2c 2c 2c 2c ; &04 # Rockets &2744 88 80 84 7c ; &08 # Balls &2748 d8 d8 d8 d8 ; &0c # Sparks ; unused &274c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &275c 00 00 00 00 ; grouped_enemies_x_positions &2760 68 68 6e 6e 72 68 ; &06 # End of odd levels boss &2766 68 68 68 68 6e 6e ; &0c # End of even levels boss ; reset_screen &276c a9 4f LDA #&4f &276e 85 74 STA &74 ; wipe_address_high &2770 a9 00 LDA #&00 &2772 85 73 STA &73 ; wipe_address_low &2774 a8 TAY &2775 a2 19 LDX #&19 ; wipe_screen_loop # Wipe &4f00 - &67ff &2777 91 73 STA (&73),Y ; wipe_address &2779 88 DEY &277a d0 fb BNE &2777 ; wipe_screen_loop &277c e6 74 INC &74 ; wipe_address_high &277e ca DEX &277f d0 f6 BNE &2777 ; wipe_screen_loop &2781 a9 0d LDA #&0d # R13: Displayed screen start address register (low) &2783 8d 00 fe STA &fe00 ; video register number &2786 a9 e8 LDA #&e8 &2788 8d 01 fe STA &fe01 ; video register value &278b a9 0c LDA #&0c # R12: Displayed screen start address register (high) &278d 8d 00 fe STA &fe00 ; video register number &2790 a9 09 LDA #&09 # Set screen start address to &4f40 (buffer_one) &2792 8d 01 fe STA &fe01 ; video register value &2795 60 RTS ; plot_string &2796 84 74 STY &74 ; text_eor &2798 bd 01 01 LDA &0101,X ; strings + 1 &279b 85 75 STA &75 ; string_end &279d bc 00 01 LDY &0100,X ; strings &27a0 b9 00 01 LDA &0100,Y ; strings &27a3 85 00 STA &00 ; screen_address_low &27a5 b9 01 01 LDA &0101,Y ; strings + 1 &27a8 85 01 STA &01 ; screen_address_high &27aa c8 INY &27ab c8 INY ; plot_string_loop &27ac b9 00 01 LDA &0100,Y ; strings &27af 84 73 STY &73 ; offset &27b1 20 72 22 JSR &2272 ; plot_character &27b4 a4 73 LDY &73 ; offset &27b6 c8 INY &27b7 c4 75 CPY &75 ; string_end &27b9 30 f1 BMI &27ac ; plot_string_loop &27bb 60 RTS ; delay &27bc 86 77 STX &77 ; vsync_pending ; wait_for_vsyncs &27be a5 77 LDA &77 ; vsync_pending &27c0 d0 fc BNE &27be ; wait_for_vsyncs &27c2 60 RTS ; unused &27c3 47 98 00 00 de fb de fb de fb 00 00 11 92 11 92 &27d3 11 52 00 00 7b 7b 7b 7b 7b 7b 00 00 1f 21 23 24 &27e3 3b 3b 83 00 25 26 27 a8 29 3b 83 0c 2a ab 2a ab &27f3 2a bb 00 00 6c 6c 6c 6c 6c 7b 80 00 6d ; Wave data ; ========= ; First six bytes are enemies: ; ; 84...... delay before next enemy ; ..218421 type of enemy ; ; Seventh byte sets flags for wave: ; ; &00 add new enemies when old enemies are destroyed ; &01 don't add new enemies when old enemies are destroyed ; &80 add fixed number of enemies at start of wave ; &83 add fixed number of enemies at start of wave, consider as a group ; ; Eighth byte is zero if enemies are added individually ; non-zero to set group used for positions for boss ; wave_data ; e0 e1 e2 e3 e4 e5 fl gr &2800 40 80 40 40 80 40 00 00 ; wave type &00 # Bouncing aliens &2808 41 81 c1 41 81 81 00 00 ; wave type &01 # Bouncing aliens &2810 01 40 01 40 01 40 80 00 ; wave type &02 # Clustered aliens &2818 42 42 42 42 42 42 80 00 ; wave type &03 # Circling balls &2820 46 86 46 c6 46 86 00 00 ; wave type &04 # Rockets &2828 47 89 c8 89 48 87 00 00 ; wave type &05 # Rising diamond bottoms &2830 45 8a 85 4a ca 85 00 00 ; wave type &06 # Bouncing balls &2838 08 59 1f 22 20 61 80 00 ; wave type &07 # Vertical pillar gate, opening middle &2840 10 4c 0d 4e 4f 3b 83 06 ; wave type &08 # End of odd levels boss &2848 11 d2 11 d2 11 52 80 00 ; wave type &09 # Paired diamonds &2850 46 53 54 54 54 54 83 00 ; wave type &0a # Rocket and claw with many legs &2858 56 56 56 56 56 56 80 00 ; wave type &0b # Circling balls &2860 02 d6 02 d6 02 d6 00 00 ; wave type &0c # Paired circling balls &2868 97 58 d7 99 59 18 00 00 ; wave type &0d # Falling diamond tops &2870 57 c9 08 59 47 98 00 00 ; wave type &0e # Falling diamond tops and rising diamond bottoms &2878 de fb de fb de fb 00 00 ; wave type &0f # Ball spawners &2880 11 92 11 92 11 52 00 00 ; wave type &10 # Paired diamonds &2888 7b 7b 7b 7b 7b 7b 00 00 ; wave type &11 # Paired diamonds &2890 1f 21 23 24 3b 3b 83 00 ; wave type &12 # Horizontal pillar gate &2898 25 26 27 a8 29 3b 83 0c ; wave type &13 # End of even levels boss &28a0 2a ab 2a ab 2a bb 00 00 ; wave type &14 # Paired fireballs &28a8 6c 6c 6c 6c 6c 7b 80 00 ; wave type &15 # Wavy drones &28b0 6d 6d 6d 6d 6d 7b 80 00 ; wave type &16 # Wavy drones &28b8 2d 6c 2d 6c 2d 2c 01 00 ; wave type &17 # Erratic wavy drones &28c0 2f ae 2f ae fb fb 80 00 ; wave type &18 # Paired legs and rocket &28c8 08 d8 08 d8 08 d8 00 00 ; wave type &19 # Paired falling diamond tops and rising diamond bottoms &28d0 f2 fb f2 f2 7b 72 00 00 ; wave type &1a # Spark spawners &28d8 1f 73 ad 34 61 2c 80 00 ; wave type &1b # Pillar chicane and drones &28e0 1f 33 f4 33 34 21 83 00 ; wave type &1c # Pillar chicane &28e8 b0 b0 9f bb bb bb 01 00 ; wave type &1d # Top platform and pillar &28f0 34 a1 4a 1f 73 05 01 00 ; wave type &1e # Pillars and bouncing ball &28f8 b5 b5 a1 bb bb bb 01 00 ; wave type &1f # Bottom platform and pillar &2900 35 b0 35 b0 33 b4 01 00 ; wave type &20 # Double platforms and middle pillar &2908 35 b0 35 b0 1f a1 01 00 ; wave type &21 # Double platforms and top and bottom pillars &2910 b0 b0 33 34 a1 bb 01 00 ; wave type &22 # Platform and double bottom pillars &2918 b5 b5 1f 33 b4 bb 01 00 ; wave type &23 # Platform and double top pillars &2920 33 34 e1 1f 33 34 83 00 ; wave type &24 # Pillar chicane &2928 1f 33 34 e1 3b 3b 83 00 ; wave type &25 # Pillars &2930 1f a1 30 b5 33 34 01 00 ; wave type &26 # Pillars and platforms &2938 1f a1 30 b5 1f 21 01 00 ; wave type &27 # Pillars and platforms &2940 08 58 33 22 20 74 80 00 ; wave type &28 # Vertical pillar gate, opening top and bottom &2948 46 86 46 42 42 c2 00 00 ; wave type &29 # Rockets and circling balls &2950 45 8a 45 56 56 d6 00 00 ; wave type &2a # Circling balls and bouncing balls &2958 40 81 85 c6 48 d6 00 00 ; wave type &2b # Aliens and bouncing balls &2960 57 8a 80 c2 46 d2 00 00 ; wave type &2c # Alien, balls and diamond top &2968 f9 b9 f9 f9 b9 f9 00 00 ; wave type &2d # Heads &2970 4b 4b 4b 4b 4b 4b 80 00 ; wave type &2e # Formation drones &2978 7a 7a 7a 7a 7a 7a 80 00 ; wave type &2f # Formation drones &2980 3a 4b 3a 4b 3a 4b 00 00 ; wave type &30 # Double formation drones &2988 55 95 55 d5 55 55 00 00 ; wave type &31 # Mounds &2990 76 b6 76 f6 76 76 00 00 ; wave type &32 # Mounds &2998 36 55 36 55 36 55 00 00 ; wave type &33 # Mounds &29a0 b7 b7 b7 b7 b7 b7 01 00 ; wave type &34 # Cigars &29a8 b8 b8 b8 b8 b8 b8 01 00 ; wave type &35 # Cigars &29b0 38 b7 38 b7 3b bb 01 00 ; wave type &36 # Cigars &29b8 4b aa 15 6c f1 bb 00 00 ; wave type &37 # Assorted enemies &29c0 16 71 b6 6a d2 86 00 00 ; wave type &38 # Assorted enemies &29c8 79 88 2e 78 cb bb 00 00 ; wave type &39 # Assorted enemies &29d0 77 97 32 55 ed ab 00 00 ; wave type &3a # Assorted enemies &29d8 79 ba 2c 45 c0 92 00 00 ; wave type &3b # Assorted enemies &29e0 79 b7 78 6f c7 ad 00 00 ; wave type &3c # Assorted enemies &29e8 72 81 46 55 eb 98 00 00 ; wave type &3d # Assorted enemies &29f0 45 95 6b 79 6c 9e 00 00 ; wave type &3e # Assorted enemies ; lives_by_game_type ; p1 p2 &29f8 04 00 ; 1 &29fa 00 04 ; 2 &29fc 04 04 ; 3 ; unused &29fe d0 f9 ; sound_suppressed &2a00 00 ; game_type &2a01 00 ; maximum_level_reached &2a02 00 ; unused &2a03 03 04 ; enemy_pattern_types # Uses enemy type to determine which row of ; 0 1 2 3 4 5 6 7 8 9 a b c d e f # patterns_for_horizontal_movement &2a05 00 80 02 03 03 05 43 07 08 09 0a 0b 0c 0d 0e 0f ; &00 # and patterns_for_vertical_movement to use &2a15 10 92 12 14 14 5e 82 87 88 89 15 95 46 c6 03 03 ; &10 # 8....... invert vertical movement &2a25 96 03 16 17 18 19 19 11 1a 01 54 d4 1b 9b 4f cf ; &20 # .4...... apply horizontal movement &2a35 03 1c 03 03 03 03 de 5f df 5d 8b ; &30 # ...18421 movement pattern ; level_colours &2a40 a5 ; &00 (level 1) : set colour 3 to green &2a41 a4 ; &01 (level 2) : set colour 3 to yellow &2a42 a2 ; &02 (level 3) : set colour 3 to magenta &2a43 a1 ; &03 (level 4) : set colour 3 to cyan &2a44 a0 ; &04 (level 5) : set colour 3 to white &2a45 a2 ; &05 (level 6) : set colour 3 to magenta &2a46 a4 ; &06 (level 7) : set colour 3 to yellow &2a47 a5 ; &07 (level 8) : set colour 3 to green ; smart_bomb_colours &2a48 06 ; set colour 0 to red &2a49 05 ; set colour 0 to green &2a4a 04 ; set colour 0 to yellow &2a4b 03 ; set colour 0 to blue &2a4c 02 ; set colour 0 to magenta &2a4d 01 ; set colour 0 to cyan &2a4e 06 ; set colour 0 to red &2a4f 05 ; set colour 0 to green &2a50 02 ; set colour 0 to magenta &2a51 01 ; set colour 0 to cyan &2a52 07 ; set colour 0 to black ; reset_screen_for_new_level &2a53 20 6c 27 JSR &276c ; reset_screen &2a56 a2 0c LDX #&0c ; "LEVEL " @ &5c18 &2a58 a0 f0 LDY #&f0 &2a5a 20 96 27 JSR &2796 ; plot_string &2a5d a5 9b LDA &9b ; level_number &2a5f 8d 02 2a STA &2a02 ; maximum_level_reached &2a62 18 CLC &2a63 69 31 ADC #&31 ; "1" &2a65 20 72 22 JSR &2272 ; plot_character &2a68 a2 32 LDX #&32 ; delay_loop &2a6a 20 bc 27 JSR &27bc ; delay &2a6d ca DEX &2a6e d0 fa BNE &2a6a ; delay_loop &2a70 a5 c6 LDA &c6 ; players_maximum_weapon &2a72 8d b2 2a STA &2ab2 ; initial_players_maximum_weapon &2a75 a5 c7 LDA &c7 ; players_maximum_weapon + 1 &2a77 8d b3 2a STA &2ab3 ; initial_players_maximum_weapon + 1 &2a7a a5 9c LDA &9c ; players_lives &2a7c 8d b4 2a STA &2ab4 ; initial_players_lives &2a7f a5 9d LDA &9d ; players_lives + 1 &2a81 8d b5 2a STA &2ab5 ; initial_players_lives + 1 &2a84 a0 00 LDY #&00 ; copy_score_section_loop # Copy &6840 - &697f to &4f40 - &507f &2a86 b9 40 68 LDA &6840,Y ; buffer_two_scores ; buffer_two &2a89 99 40 4f STA &4f40,Y ; buffer_one_scores ; buffer_one &2a8c b9 80 68 LDA &6880,Y ; buffer_two_scores + &40 ; buffer_two + 8 * 8 &2a8f 99 80 4f STA &4f80,Y ; buffer_one_scores + &40 ; buffer_one + 8 * 8 &2a92 88 DEY &2a93 d0 f1 BNE &2a86 ; copy_score_section_loop &2a95 a9 7c LDA #&7c &2a97 85 74 STA &74 ; buffer_two_address_high &2a99 a9 63 LDA #&63 &2a9b 85 76 STA &76 ; buffer_one_address_high &2a9d 84 73 STY &73 ; buffer_two_address_low &2a9f 84 75 STY &75 ; buffer_one_address_low &2aa1 a2 05 LDX #&05 ; copy_status_section_loop # Copy &7c00 - &7fff to &6300 - &67ff &2aa3 b1 73 LDA (&73),Y ; buffer_two_address &2aa5 91 75 STA (&75),Y ; buffer_one_address &2aa7 88 DEY &2aa8 d0 f9 BNE &2aa3 ; copy_status_section_loop &2aaa e6 74 INC &74 ; buffer_two_address_high &2aac e6 76 INC &76 ; buffer_one_address_high &2aae ca DEX &2aaf d0 f2 BNE &2aa3 ; copy_status_section_loop &2ab1 60 RTS ; initial_players_maximum_weapon &2ab2 00 00 ; initial_players_lives &2ab4 00 00 ; unused &2ab6 28 63 29 20 54 6f 6e 79 20 4f 61 6b 64 65 6e 20 ; "(c) Tony Oakden " &2ac6 66 6f 72 20 57 69 6c 64 43 61 74 20 31 39 38 39 ; "for WildCat 1989" &2ad6 2e 20 54 68 61 6e 6b 73 20 74 6f 20 57 61 79 6e ; ". Thanks to Wayn" &2ae6 65 20 44 6f 64 73 77 6f 72 74 68 20 66 6f 72 20 ; "e Dodsworth for " &2af6 68 69 73 20 61 64 76 69 63 65 ; "his advice" ; patterns_for_vertical_movement # Uses value from enemy_pattern_types to determine ; 0 1 2 3 4 5 6 7 ; movement frame # which row of movement_patterns to use horizontally &2b00 02 01 02 01 0a 01 0a 00 ; &00 &2b08 02 00 01 00 02 00 01 00 ; &01 &2b10 00 04 03 00 04 03 00 00 ; &02 &2b18 00 00 00 00 00 00 00 00 ; &03 &2b20 00 00 00 00 00 00 00 00 ; &04 &2b28 07 08 07 08 07 08 07 08 ; &05 &2b30 02 02 02 02 02 02 02 02 ; &06 &2b38 00 00 00 00 00 0a 0a 0a ; &07 &2b40 00 00 0a 0a 0a 0a 0a 0a ; &08 &2b48 00 00 00 00 0a 0a 0a 0a ; &09 &2b50 08 07 08 07 08 07 08 07 ; &0a &2b58 00 00 01 00 00 00 02 00 ; &0b &2b60 00 0e 0b 0e 0e 0c 0e 0e ; &0c &2b68 00 10 0b 10 10 0c 10 10 ; &0d &2b70 00 0f 0b 0f 0f 0c 0f 0f ; &0e &2b78 00 00 0b 00 00 0c 00 00 ; &0f &2b80 00 0d 0b 0d 0d 0c 0d 0d ; &10 &2b88 00 12 00 00 00 13 00 00 ; &11 &2b90 00 00 0b 0c 00 00 00 0c ; &12 &2b98 00 00 00 00 00 00 00 00 ; &13 &2ba0 0f 0f 01 02 0f 01 0f 0f ; &14 &2ba8 01 01 01 01 01 01 01 01 ; &15 &2bb0 0c 00 0b 00 0c 0b 00 0c ; &16 &2bb8 00 00 00 00 00 00 00 00 ; &17 &2bc0 00 00 00 00 00 00 00 00 ; &18 &2bc8 00 00 00 00 00 00 00 00 ; &19 &2bd0 00 00 00 13 00 00 00 00 ; &1a &2bd8 04 03 04 03 04 09 04 03 ; &1b &2be0 09 09 09 09 09 09 09 09 ; &1c &2be8 00 00 00 00 00 00 00 00 ; &1d &2bf0 14 0b 0b 0b 09 09 09 09 ; &1e &2bf8 00 15 00 15 00 15 00 15 ; &1f ; unused # &2c00 - &2c7f is a copy of &2cb1 to &2d30 &2c00 02 02 02 02 02 02 02 02 02 02 02 02 00 00 02 02 &2c10 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 &2c20 02 02 02 02 02 02 02 0a 00 00 00 0a 00 00 0a 02 &2c30 00 0c 01 02 00 0b 0c 02 00 0c 01 02 00 0b 0c 02 &2c40 00 0c 01 02 00 0b 0c 02 00 0c 01 02 00 0b 0c 02 &2c50 00 0c 01 02 00 0b 0c 11 11 11 11 11 11 11 11 0a &2c60 02 02 02 01 01 01 01 02 02 02 02 02 02 02 02 02 &2c70 02 02 02 02 02 02 02 01 01 01 01 01 01 01 01 02 ; patterns_for_horizontal_movement # Uses value from enemy_pattern_types to determine ; 0 1 2 3 4 5 6 7 ; movement frame # which row of movement_patterns to use horizontally &2c80 02 02 02 02 0a 0a 0a 0a ; &00 &2c88 11 11 11 11 11 11 11 11 ; &01 &2c90 02 06 05 02 06 05 02 02 ; &02 &2c98 02 02 02 02 02 02 02 02 ; &03 &2ca0 00 00 00 00 00 00 00 00 ; &04 &2ca8 02 02 02 02 02 02 02 02 ; &05 &2cb0 02 02 02 02 02 02 02 02 ; &06 &2cb8 02 02 02 02 02 00 00 02 ; &07 &2cc0 02 02 02 02 02 02 02 02 ; &08 &2cc8 02 02 02 02 02 02 02 02 ; &09 &2cd0 02 02 02 02 02 02 02 02 ; &0a &2cd8 0a 00 00 00 0a 00 00 0a ; &0b &2ce0 02 00 0c 01 02 00 0b 0c ; &0c &2ce8 02 00 0c 01 02 00 0b 0c ; &0d &2cf0 02 00 0c 01 02 00 0b 0c ; &0e &2cf8 02 00 0c 01 02 00 0b 0c ; &0f &2d00 02 00 0c 01 02 00 0b 0c ; &10 &2d08 11 11 11 11 11 11 11 11 ; &11 &2d10 0a 02 02 02 01 01 01 01 ; &12 &2d18 02 02 02 02 02 02 02 02 ; &13 &2d20 02 02 02 02 02 02 02 02 ; &14 &2d28 01 01 01 01 01 01 01 01 ; &15 &2d30 02 02 02 02 02 02 02 02 ; &16 &2d38 02 0a 02 02 00 02 0a 02 ; &17 &2d40 02 00 02 02 0a 02 00 0a ; &18 &2d48 11 11 11 11 11 11 11 11 ; &19 &2d50 11 11 11 11 11 11 11 11 ; &1a &2d58 02 02 02 02 02 02 02 02 ; &1b &2d60 00 00 00 00 00 00 00 00 ; &1c &2d68 03 03 03 02 03 03 03 03 ; &1d &2d70 02 02 02 02 02 02 02 02 ; &1e &2d78 0a 16 09 17 0a 16 09 17 ; &1f ; unused &2d80 8d 51 98 00 00 00 00 61 72 35 00 8d 52 68 00 00 &2d90 6a 7a 6f 74 75 72 62 73 63 00 8d 52 88 00 00 84 &2da0 7a 6f 74 75 72 62 73 63 32 00 8d 55 e0 00 00 8d &2db0 7a 6e 74 00 8d 59 38 00 00 da 7a 69 00 8d 5a 48 &2dc0 00 00 3c 7d 73 6b 00 8d 5a 78 00 00 c9 7d 78 69 &2dd0 74 00 8d 5a b8 00 00 e3 7a 74 63 00 8d 5b 08 00 &2de0 00 b9 7a 63 72 6f 6c 6c 00 8d 5b d8 00 00 c7 7a &2df0 63 72 6f 6c 6c 31 00 8d 5c e8 00 00 58 7b 68 73 ; sprite_player_one_even_group_0 &2e00 00 00 00 11 01 23 23 03 00 00 8f 68 f0 f0 78 0f &2e10 00 00 00 00 00 00 00 00 ; sprite_player_two_even_group_0 &2e18 00 00 00 11 10 32 30 30 00 00 f8 80 06 0f 87 f0 &2e28 00 00 00 00 00 00 00 00 ; mask_player_even_group_0 &2e30 ff ff ee cc cc 88 88 88 ff 00 00 00 00 00 00 00 &2e40 ff ff 77 ff 77 77 77 77 ; sprite_player_one_weapon_0_odd &2e48 00 00 ff f0 c0 80 08 00 00 00 88 80 00 00 00 00 ; sprite_player_two_weapon_0_odd &2e58 00 00 ff 0f 0c 08 80 00 00 00 88 08 00 00 00 00 ; mask_player_weapon_0_odd &2e68 ff 00 00 00 00 33 77 77 ff 77 77 77 77 ff ff ff ; sprite_player_one_weapon_0_inactive_odd &2e78 00 00 fb b0 c0 80 08 00 00 00 00 00 00 00 00 00 ; sprite_player_two_weapon_0_inactive_odd &2e88 00 00 bf 0b 0c 08 80 00 00 00 00 00 00 00 00 00 ; mask_player_weapon_0_inactive_odd &2e98 ff 00 00 00 00 33 77 77 ff ff ff ff ff ff ff ff ; sprite_alien_even_group_0 &2ea8 00 11 32 20 56 07 8f 0f ce 0f 0f 87 0f 0e 0e 0c &2eb8 00 00 00 00 00 00 00 00 ; mask_alien_even_group_0 &2ec0 ee cc 88 88 88 00 00 00 00 00 00 00 00 00 00 11 &2ed0 ff 77 77 77 77 ff ff ff ; sprite_ball_one_even_group_0 &2ed8 00 00 30 70 72 f4 f4 f0 00 00 00 80 80 c0 c0 c0 ; mask_ball_even_group_0 &2ee8 ff cc 88 88 00 00 00 00 ff ff 77 77 33 33 33 33 ; sprite_sparks_group_0 &2ef8 99 aa aa 44 44 55 22 22 ; sprite_player_one_even_group_1 &2f00 03 33 47 07 8f 0d 1b 07 0e 07 08 1d 3a 60 d0 f8 &2f10 00 00 00 44 c8 80 40 c0 ; sprite_player_two_even_group_1 &2f18 30 33 74 70 f8 d0 b1 70 e0 70 80 d1 a3 06 0d 8f &2f28 00 00 00 44 8c 08 04 0c ; mask_player_even_group_1 &2f30 88 88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &2f40 77 77 ff 33 33 33 33 33 ; sprite_player_one_weapon_1_odd &2f48 20 20 ec d1 d0 a0 28 00 00 00 00 00 00 00 00 00 ; sprite_player_two_weapon_1_odd &2f58 02 02 ce 1d 0d 0a 82 00 00 00 00 00 00 00 00 00 ; mask_player_weapon_1_odd &2f68 dd 11 00 00 00 11 55 77 ff ff ff ff ff ff ff ff ; sprite_player_one_weapon_1_inactive_odd &2f78 00 00 cc a2 a0 c0 08 00 00 00 00 00 00 00 00 00 ; sprite_player_two_weapon_1_inactive_odd &2f88 00 00 cc 2a 0a 0c 80 00 00 00 00 00 00 00 00 00 ; mask_player_weapon_1_inactive_odd &2f98 ff 33 11 11 11 33 33 77 ff ff ff ff ff ff ff ff ; sprite_alien_even_group_1 &2fa8 08 00 04 83 c0 e0 a6 1f 0a 15 0d 2b 03 47 07 07 &2fb8 00 00 08 08 08 08 08 04 ; mask_alien_even_group_1 &2fc0 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &2fd0 ff 77 77 77 77 77 33 33 ; sprite_ball_one_even_group_1 &2fd8 f0 f0 f0 60 60 30 00 00 c0 40 40 80 80 00 00 00 ; mask_ball_even_group_1 &2fe8 00 00 00 00 88 88 cc ff 33 33 33 33 77 77 ff ff ; sprite_sparks_group_1 &2ff8 aa 44 44 44 55 22 22 22 ; sprite_player_one_even_group_2 &3000 0f 0f 07 00 03 01 00 00 4e 0f 12 2c 2e 1f 0f 07 &3010 80 84 00 00 00 00 88 08 ; sprite_player_two_even_group_2 &3018 f0 f0 70 00 30 10 00 00 f4 f0 21 c0 e2 f1 f0 70 &3028 48 48 00 00 00 00 88 80 ; mask_player_even_group_2 &3030 00 00 00 88 cc ee ff ff 00 00 00 00 00 00 00 00 &3040 33 33 33 ff ff 77 33 33 ; sprite_player_one_weapon_2_odd &3048 00 00 ff f0 a0 f0 08 00 00 88 80 80 80 80 00 00 ; sprite_player_two_weapon_2_odd &3058 00 00 ff 0f 0a 0f 80 00 00 88 08 08 08 08 00 00 ; mask_player_weapon_2_odd &3068 ff 00 00 00 00 00 00 77 77 77 77 77 77 77 77 ff ; sprite_player_one_weapon_2_inactive_odd &3078 00 22 ec 60 a0 60 08 00 00 00 00 00 00 00 00 00 ; sprite_player_two_weapon_2_inactive_odd &3088 00 22 ce 06 0a 06 80 00 00 00 00 00 00 00 00 00 ; mask_player_weapon_2_inactive_odd &3098 dd 11 11 11 11 11 11 77 ff ff ff ff ff ff ff ff ; sprite_alien_even_group_2 &30a8 8b c9 64 12 07 45 64 32 8b 0c 0e 06 91 2b 0d 06 &30b8 04 04 0c 0c 0c 08 08 00 ; mask_alien_even_group_2 &30c0 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 00 &30d0 33 33 33 33 33 33 33 33 ; sprite_ball_two_even_group_0 &30d8 00 03 07 27 4f 4f 0f 0f 00 00 08 08 0c 0c 0c 0c ; mask_player_bonus_even_group_0 &30e8 88 00 00 00 00 00 00 00 77 33 33 33 33 33 33 33 ; sprite_sparks_group_2 &30f8 22 aa 44 44 44 55 22 22 ; sprite_player_one_even_group_3 &3100 00 00 00 00 11 00 00 00 02 23 47 8f 0a 0c 06 00 &3110 08 00 08 00 00 00 00 00 ; sprite_player_two_even_group_3 &3118 00 00 00 00 11 00 00 00 20 32 74 f8 a0 c0 60 00 &3128 80 00 80 00 00 00 00 00 ; mask_player_even_group_3 &3130 ff ff ff ee ee ee ff ff 88 88 00 00 00 11 00 88 &3140 33 33 33 77 ff ff ff ff ; sprite_player_one_weapon_3_odd &3148 00 00 9b a7 97 a7 1b 00 00 00 00 88 4c 88 00 00 ; sprite_player_two_weapon_3_odd &3158 00 00 9b 2f 1f 2f 93 00 00 00 00 88 4c 88 00 00 ; mask_player_weapon_3_odd &3168 ff 44 00 00 00 00 00 44 ff ff 77 33 33 33 77 ff ; sprite_player_one_weapon_3_inactive_odd &3178 00 00 a9 96 a5 96 29 00 00 00 00 08 84 08 00 00 ; sprite_player_two_weapon_3_inactive_odd &3188 00 00 a9 1e 2d 1e a1 00 00 00 00 08 84 08 00 00 ; mask_player_weapon_3_inactive_odd &3198 ff 44 00 00 00 00 00 44 ff ff 77 33 33 33 77 ff ; sprite_alien_even_group_3 &31a8 01 03 22 32 11 00 00 00 80 59 0d 06 83 e0 c0 80 &31b8 8c 0c 0c 08 00 00 00 00 ; mask_alien_even_group_3 &31c0 88 88 88 88 cc ee ff ff 00 00 00 00 00 00 11 33 &31d0 33 33 33 33 77 ff ff ff ; sprite_ball_two_even_group_1 &31d8 0f 0f 06 06 03 00 00 00 04 04 08 08 00 00 00 00 ; mask_player_bonus_even_group_1 &31e8 00 00 00 00 00 00 00 88 33 33 33 33 33 33 33 77 ; sprite_sparks_group_3 &31f8 22 aa 44 44 44 44 44 00 ; sprite_player_one_odd_group_0 &3200 00 00 00 00 00 00 00 00 00 00 23 56 34 bc 9e 0f &3210 00 00 0c 80 c0 c0 c0 0c ; sprite_player_two_odd_group_0 &3218 00 00 00 00 00 00 00 00 00 00 32 64 41 cb e1 f0 &3228 00 00 c0 00 08 0c 0c c0 ; mask_player_odd_group_0 &3230 ff ff ff ff ff ee ee ee ff cc 88 00 00 00 00 00 &3240 ff 33 11 33 11 11 11 11 ; sprite_player_one_weapon_0_even &3248 00 00 33 30 30 20 02 00 00 00 ee e0 00 00 00 00 ; sprite_player_two_weapon_0_even &3258 00 00 33 03 03 02 20 00 00 00 ee 0e 00 00 00 00 ; mask_player_weapon_0_even &3268 ff cc cc cc cc cc dd dd ff 11 11 11 11 ff ff ff ; sprite_player_one_weapon_0_inactive_even &3278 00 00 32 20 30 20 02 00 00 00 cc c0 00 00 00 00 ; sprite_player_two_weapon_0_inactive_even &3288 00 00 23 02 03 02 20 00 00 00 cc 0c 00 00 00 00 ; mask_player_weapon_0_inactive_even &3298 ff cc cc cc cc cc dd dd ff 33 33 33 33 ff ff ff ; sprite_alien_odd_group_0 &32a8 00 00 00 00 11 01 23 03 33 47 cb a1 4b 0f 0f 0f &32b8 08 0c 0c 0c 0c 08 08 00 ; mask_alien_odd_group_0 &32c0 ff ff ee ee ee cc cc cc 88 00 00 00 00 00 00 00 &32d0 33 11 11 11 11 33 33 77 ; sprite_ball_one_odd_group_0 &32d8 00 00 00 10 10 31 31 30 00 00 c0 e0 e8 f0 f0 f0 ; mask_ball_odd_group_0 &32e8 ff ff ee ee cc cc cc cc ff 33 11 11 00 00 00 00 ; mask_sparks_group_0 &32f8 44 44 11 11 88 88 88 11 ; sprite_player_one_odd_group_1 &3300 00 00 11 01 23 03 02 01 0f cd 0e 0f 0e 14 7c 3e &3310 08 0c 00 55 fa a0 50 f0 ; sprite_player_two_odd_group_1 &3318 00 00 11 10 32 30 20 10 f0 dc e0 f0 e0 41 c7 e3 &3328 80 c0 00 55 af 0a 05 0f ; mask_player_odd_group_1 &3330 ee ee cc cc cc cc cc cc 00 00 00 00 00 00 00 00 &3340 11 11 33 00 00 00 00 00 ; sprite_player_one_weapon_1_even &3348 00 00 33 30 30 20 02 00 80 80 80 44 40 80 80 00 ; sprite_player_two_weapon_1_even &3358 00 00 33 03 03 02 20 00 08 08 08 44 04 08 08 00 ; mask_player_weapon_1_even &3368 ff cc cc cc cc cc dd dd 77 77 33 33 33 77 77 ff ; sprite_player_one_weapon_1_inactive_even &3378 00 00 33 20 20 30 02 00 00 00 00 88 80 00 00 00 ; sprite_player_two_weapon_1_inactive_even &3388 00 00 33 02 02 03 20 00 00 00 00 88 08 00 00 00 ; mask_player_weapon_1_inactive_even &3398 ff cc cc cc cc cc cc dd ff ff 77 77 77 77 ff ff ; sprite_alien_odd_group_1 &33a8 02 00 01 20 30 30 21 03 02 01 03 0e 00 91 89 4d &33b8 08 44 06 8e 0e 0e 0e 0d ; mask_alien_odd_group_1 &33c0 cc ff cc cc cc cc cc cc 00 cc 00 00 00 00 00 00 &33d0 33 11 11 11 11 11 00 00 ; sprite_ball_one_odd_group_1 &33d8 30 30 30 10 10 00 00 00 f0 d0 d0 a0 a0 c0 00 00 ; mask_ball_odd_group_1 &33e8 cc cc cc cc ee ee ff ff 00 00 00 00 11 11 33 ff ; mask_sparks_group_1 &33f8 11 11 99 88 88 88 99 99 ; sprite_player_one_odd_group_2 &3400 03 03 01 00 00 00 00 00 1f 0f 0c 03 0f 07 03 01 &3410 28 2d 48 80 88 4c 2e 0e ; sprite_player_two_odd_group_2 &3418 30 30 10 00 00 00 00 00 f1 f0 c0 30 f0 70 30 10 &3428 d2 d2 84 00 88 c4 e2 e0 ; mask_player_odd_group_2 &3430 cc cc cc ee ff ff ff ff 00 00 00 00 00 88 cc cc &3440 00 00 00 33 33 11 00 00 ; sprite_player_one_weapon_2_even &3448 00 00 33 30 20 30 02 00 00 22 ec e0 a0 e0 00 00 ; sprite_player_two_weapon_2_even &3458 00 00 33 03 02 03 20 00 00 22 ce 0e 0a 0e 00 00 ; mask_player_weapon_2_even &3468 ff cc cc cc cc cc cc dd dd 11 11 11 11 11 11 ff ; sprite_player_one_weapon_2_inactive_even &3478 00 00 33 10 20 10 02 00 00 88 80 80 80 80 00 00 ; sprite_player_two_weapon_2_inactive_even &3488 00 00 33 01 03 01 20 00 00 88 08 08 08 08 00 00 ; mask_player_weapon_2_inactive_even &3498 ff cc cc cc cc cc cc dd 77 77 77 77 77 77 77 ff ; sprite_alien_odd_group_2 &34a8 22 32 11 00 01 11 11 00 2e 07 83 49 2c 06 83 c9 &34b8 0d 01 0b 0b 47 8e 06 08 ; mask_alien_odd_group_2 &34c0 cc cc cc cc cc cc cc ee 00 00 00 00 00 00 00 00 &34d0 00 00 00 00 00 00 00 00 ; sprite_ball_two_odd_group_0 &34d8 00 00 01 01 13 13 03 03 00 0c 0e 8e 0f 0f 0f 0f ; mask_player_bonus_odd_group_0 &34e8 ee cc cc cc cc cc cc cc 11 00 00 00 00 00 00 00 ; mask_sparks_group_2 &34f8 11 11 11 99 88 88 88 99 ; sprite_player_one_odd_group_3 &3500 00 00 00 00 00 00 00 00 00 00 11 23 46 03 01 00 &3510 0a 8c 0e 0c 08 00 08 00 ; sprite_player_two_odd_group_3 &3518 00 00 00 00 00 00 00 00 00 00 11 32 64 30 10 00 &3528 a0 c8 e0 c0 80 00 80 00 ; mask_player_odd_group_3 &3530 ff ff ff ff ff ff ff ff ee ee cc 88 88 88 cc ee &3540 00 00 00 11 33 77 33 33 ; sprite_player_one_weapon_3_even &3548 00 00 22 21 21 21 02 00 00 00 4c ae 5f ae 4c 00 ; sprite_player_two_weapon_3_even &3558 00 00 22 03 03 03 20 00 00 00 4c ae 5f ae 4c 00 ; mask_player_weapon_3_even &3568 ff dd cc cc cc cc cc dd ff 33 11 00 00 00 11 33 ; sprite_player_one_weapon_3_inactive_even &3578 00 00 22 21 21 21 02 00 00 00 84 4a a5 4a 84 00 ; sprite_player_two_weapon_3_inactive_even &3588 00 00 22 03 03 03 20 00 00 00 84 4a a5 4a 84 00 ; mask_player_weapon_3_inactive_even &3598 ff dd cc cc cc cc cc dd ff 33 11 00 00 00 11 33 ; sprite_alien_odd_group_3 &35a8 00 00 00 00 00 00 00 00 24 1e 8b c9 64 30 30 20 &35b8 23 47 07 0a 0c 80 00 00 ; mask_alien_odd_group_3 &35c0 ee ee ee ee ff ff ff ff 00 00 00 00 00 88 cc cc &35d0 00 00 00 00 11 33 77 ff ; sprite_ball_two_odd_group_1 &35d8 03 03 01 01 00 00 00 00 0d 0d 0a 0a 0c 00 00 00 ; mask_player_bonus_odd_group_1 &35e8 cc cc cc cc cc cc cc ee 00 00 00 00 00 00 00 11 ; mask_sparks_group_3 &35f8 11 11 11 99 99 99 99 99 ; sprite_player_one_bonus_even_group_0 &3600 00 07 0f f0 ff ff 33 33 00 08 0c c0 cc cc 00 00 ; sprite_diamond_even_group_0 &3610 00 00 00 00 11 11 01 23 00 88 88 88 48 48 84 a4 &3620 00 00 00 00 00 00 00 00 ; sprite_claw_even_group_0 &3628 00 00 11 32 21 47 42 05 00 00 0e 2d 0f 03 0d 02 &3638 00 00 00 08 84 4a 2d 0f 00 00 00 00 00 00 00 00 ; mask_claw_even_group_0 &3648 ff ee cc cc 88 88 88 00 ff 11 00 00 00 00 00 00 &3658 ff ff 77 33 11 00 00 00 ff ff ff ff ff ff ff 77 ; sprite_segment_one_even_group_0 &3668 00 23 56 27 5e 9f 2f 8f 00 00 08 84 4a 86 2d 4b &3678 00 00 00 00 00 00 00 00 ; mask_segment_one_even_group_0 &3680 cc 88 88 88 00 00 00 00 ff 77 33 11 11 00 00 00 &3690 ff ff ff ff ff ff ff ff ; sprite_segment_two_even_group_0 &3698 00 00 00 00 00 11 01 23 00 32 47 9e 4f 1e ad 0f &36a8 00 00 80 08 84 48 84 0c ; mask_segment_two_even_group_0 &36b0 ff ff ff ee ee cc cc cc cc 88 00 00 00 00 00 00 &36c0 ff 77 77 33 33 33 33 33 ; sprite_legs_even_group_0 &36c8 00 46 cf 8f 8a 89 00 00 00 11 33 2b 2a 04 0c 0e &36d8 00 08 0c 04 0a 06 01 03 00 00 00 00 00 00 00 00 ; mask_diamond_even_group_0 &36e8 ff ff ff ee ee ee cc cc 77 77 77 33 33 33 11 11 &36f8 ff ff ff ff ff ff ff ff ; sprite_player_one_bonus_even_group_1 &3700 3f 3f 3f 3f 3f 0c 07 00 04 04 04 04 04 04 08 00 ; sprite_diamond_even_group_1 &3710 23 13 57 57 27 af af 5f a4 4a 5a 5a a5 a5 a5 5f &3720 00 00 00 00 00 80 80 08 ; sprite_claw_even_group_1 &3728 8a 84 00 08 00 00 00 00 01 00 00 00 00 00 00 00 &3738 16 0f 0b 07 05 12 00 02 08 08 08 0c 84 40 80 80 ; mask_claw_even_group_1 &3748 00 11 33 77 77 ff ff ff cc ee ff ff ff ff ff ff &3758 00 00 00 00 88 88 cc cc 77 77 33 33 33 33 33 33 ; sprite_segment_one_even_group_1 &3768 1e 0f 8f 0f 0b 07 07 05 2d 5a 2d 1e 0f 0f 0f 0f &3778 00 08 08 08 08 84 0c 0c ; mask_segment_one_even_group_1 &3780 00 00 00 00 00 00 88 88 00 00 00 00 00 00 00 00 &3790 77 77 77 77 33 33 33 33 ; sprite_segment_two_even_group_1 &3798 13 03 03 47 27 17 07 8f 1e 8f 1e 0f 0f 1e 2d 0e &37a8 48 84 0c 48 84 08 04 08 ; mask_segment_two_even_group_1 &37b0 cc 88 88 88 88 00 00 00 00 00 00 00 00 00 00 00 &37c0 33 33 33 33 33 33 33 33 ; sprite_legs_even_group_1 &37c8 00 22 46 07 07 8f 0f 0f 06 0e 0f 05 0b 0d 0f 0f &37d8 03 47 07 8e 05 0b 05 0f 00 00 00 00 00 88 4c 0c ; mask_diamond_even_group_1 &37e8 cc 88 88 88 00 00 00 00 11 00 00 00 00 00 00 00 &37f8 ff ff ff ff 77 77 77 77 ; sprite_player_two_bonus_even_group_0 &3800 00 70 f0 0f ff ff 33 f3 00 80 c0 0c cc cc 00 40 ; sprite_diamond_even_group_2 &3810 5f a5 a5 25 52 52 12 21 5f a7 a7 a7 5f 5f 4e a6 &3820 08 88 88 00 00 00 00 00 ; sprite_claw_even_group_2 &3828 00 00 88 00 0c 4a 25 07 00 00 00 00 00 11 32 cf &3838 12 65 07 cb 0f 86 0f 0d 40 84 0c 08 00 08 00 00 ; mask_claw_even_group_2 &3848 ff 77 77 33 11 00 00 88 ff ff ff ff ee cc 00 00 &3858 88 88 00 00 00 00 00 00 33 33 33 33 77 77 77 ff ; sprite_segment_one_even_group_2 &3868 03 02 01 01 00 00 00 00 0f 0e 0f 07 0b 05 02 01 &3878 08 0c 08 04 08 04 08 00 ; mask_segment_one_even_group_2 &3880 88 cc cc ee ee ff ff ff 00 00 00 00 00 00 88 cc &3890 33 33 33 33 33 33 33 77 ; sprite_segment_two_even_group_2 &3898 4f 2f 0f 1e 0f 0e 05 0a 0d 4a 0d 0a 05 0a 04 08 &38a8 00 08 00 00 00 00 00 00 ; mask_segment_two_even_group_2 &38b0 00 00 00 00 00 00 00 88 00 00 00 00 00 00 11 33 &38c0 33 77 77 77 ff ff ff ff ; sprite_legs_even_group_2 &38c8 4b 2d 4b 25 07 24 02 00 0f 0f 8d 0a 05 0d 0e 04 &38d8 0e 0d 02 0d 06 0f 07 03 08 04 08 00 00 00 00 00 ; mask_diamond_even_group_2 &38e8 00 00 00 00 88 88 88 cc 00 00 00 00 00 00 00 11 &38f8 77 77 77 77 ff ff ff ff ; sprite_player_two_bonus_even_group_1 &3900 f3 f3 f3 f3 f3 c0 70 00 40 40 40 40 40 40 80 00 ; sprite_diamond_even_group_3 &3910 21 01 10 10 00 00 00 00 a6 84 4c 4c 88 88 88 00 &3920 00 00 00 00 00 00 00 00 ; sprite_claw_even_group_3 &3928 03 02 01 00 00 00 00 00 0f 0f 01 0f 00 00 00 00 &3938 0a 04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 ; mask_claw_even_group_3 &3948 88 cc cc ee ff ff ff ff 00 00 00 00 00 ff ff ff &3958 00 11 33 77 ff ff ff ff ff ff ff ff ff ff ff ff ; sprite_platform_group_0 &3968 00 77 ff f8 f0 f0 60 30 00 ff ff f0 f0 70 e0 30 &3978 00 ff ff f0 f0 70 e0 30 00 ff ff f0 f0 70 e0 30 &3988 00 ff ff f0 f0 70 e0 30 00 ff ff f0 f0 70 e0 30 &3998 00 ff ff f0 f0 70 e0 30 00 ff ff f0 f0 70 e0 30 &39a8 00 ff ff f0 f0 70 e0 30 00 ff ff f0 f0 70 e0 30 &39b8 00 ff ff f0 f0 70 e0 30 00 ee ff f1 f0 50 e0 80 ; sprite_legs_even_group_3 &39c8 00 00 99 ab 8e cf ce 00 0e 0c 26 2a 2b 33 11 00 &39d8 03 45 06 8a 0c 4c 08 00 00 00 00 00 00 00 00 00 ; mask_diamond_even_group_3 &39e8 cc cc ee ee ee ff ff ff 11 11 33 33 33 77 77 77 &39f8 ff ff ff ff ff ff ff ff ; sprite_player_one_bonus_odd_group_0 &3a00 00 01 03 30 33 33 00 00 00 0e 0f f0 ff ff cc cc ; sprite_diamond_odd_group_0 &3a10 00 00 00 00 00 00 00 00 00 22 22 22 53 53 25 a5 &3a20 00 00 00 00 00 00 00 88 ; sprite_claw_odd_group_0 &3a28 00 00 00 00 00 11 10 01 00 00 47 cb 87 0c 0b 04 &3a38 00 00 08 86 2d 1e 07 0b 00 00 00 00 00 08 84 0c ; mask_claw_odd_group_0 &3a48 ff ff ff ff ee ee ee cc ff 88 00 00 00 00 00 00 &3a58 ff 77 11 00 00 00 00 00 ff ff ff ff 77 33 33 11 ; sprite_segment_one_odd_group_0 &3a68 00 00 11 01 13 23 03 23 00 8c 4a ad 5a 6d 8f 1e &3a78 00 00 00 00 08 08 84 0c ; mask_segment_one_odd_group_0 &3a80 ff ee ee ee cc cc cc cc 33 11 00 00 00 00 00 00 &3a90 ff ff ff 77 77 33 33 33 ; sprite_segment_two_odd_group_0 &3a98 00 00 00 00 00 00 00 00 00 00 11 23 13 47 27 8f &3aa8 00 c8 2c 4a 2d 5a a5 0f ; mask_segment_two_odd_group_0 &3ab0 ff ff ff ff ff ff ff ff ff ee cc 88 88 00 00 00 &3ac0 33 11 11 00 00 00 00 00 ; sprite_legs_odd_group_0 &3ac8 00 00 00 00 00 00 00 00 46 cf 8d 8a 89 00 00 11 &3ad8 00 11 19 19 15 0c 0c 0c 8c 8e 8a 05 03 01 03 47 ; mask_diamond_odd_group_0 &3ae8 ff ff ff ff ff ff ff ff dd dd dd 88 88 88 00 00 &3af8 ff ff ff ff ff ff 77 77 ; sprite_player_one_bonus_odd_group_1 &3b00 03 03 03 03 03 03 01 00 cd cd cd cd cd 01 0e 00 ; sprite_diamond_odd_group_1 &3b10 00 00 10 10 01 21 21 13 a5 5b 5b 5b a5 a5 a5 5f &3b20 88 08 4c 4c 8c ae ae 4e ; sprite_claw_odd_group_1 &3b28 22 21 00 02 00 00 00 00 08 00 00 00 00 00 00 00 &3b38 05 03 02 01 01 00 00 00 4a 0e 0e 0f 25 58 20 28 ; mask_claw_odd_group_1 &3b48 cc cc cc dd dd ff ff ff 33 77 ff ff ff ff ff ff &3b58 00 88 cc cc ee ee ff ff 11 11 00 00 00 00 00 00 ; sprite_segment_one_odd_group_1 &3b68 03 03 23 03 02 01 01 01 4b 1e 0f 0f 0f 0f 0f 07 &3b78 84 4a 86 4a 0e 2d 0f 0f ; mask_segment_one_odd_group_1 &3b80 cc cc cc cc cc cc ee ee 00 00 00 00 00 00 00 00 &3b90 11 11 11 11 00 00 00 00 ; sprite_segment_two_odd_group_1 &3b98 00 00 00 11 01 01 01 23 4f 2f 0f 0f 8f 4f 0f 0f &3ba8 5a 2d 4b 1e 2d 4a 85 0a ; mask_segment_two_odd_group_1 &3bb0 ff ee ee ee ee cc cc cc 00 00 00 00 00 00 00 00 &3bc0 00 00 00 00 00 00 00 00 ; sprite_legs_odd_group_1 &3bc8 00 00 11 01 01 23 03 03 23 cf 0f 0d 0e 0f 0f 0f &3bd8 08 0c 2e 07 0d 06 0d 0f 8e 0e 0e 0c 04 2e 17 0f ; mask_diamond_odd_group_1 &3be8 ff ee ee ee cc cc cc cc 00 00 00 00 00 00 00 00 &3bf8 77 33 33 33 11 11 11 11 ; sprite_player_two_bonus_odd_group_0 &3c00 00 10 30 03 33 33 00 30 00 e0 f0 0f ff ff cc dc ; sprite_diamond_odd_group_2 &3c10 13 23 23 01 11 11 00 00 5f ad ad ad 5e 5e 5e ad &3c20 4e a4 a4 84 48 48 08 80 ; sprite_claw_odd_group_2 &3c28 00 00 22 00 03 12 01 01 00 00 00 00 00 08 84 3f &3c38 00 11 01 32 03 65 cb 0f 58 a5 0f 0e 0c 0a 0c 04 ; mask_claw_odd_group_2 &3c48 ff dd dd cc cc cc cc ee ff ff ff ff 77 33 00 00 &3c58 ee ee cc cc 88 00 00 00 00 00 00 00 11 11 11 33 ; sprite_segment_one_odd_group_2 &3c68 00 00 00 00 00 00 00 00 0f 0b 07 05 02 01 00 00 &3c78 0e 0b 0e 0d 0e 05 0a 04 ; mask_segment_one_odd_group_2 &3c80 ee ff ff ff ff ff ff ff 00 00 00 88 88 cc ee ff &3c90 00 00 00 00 00 00 00 11 ; sprite_segment_two_odd_group_2 &3c98 13 03 03 03 03 03 01 00 0f 9e 0f 4a 0d 0a 07 0c &3ca8 04 0a 04 08 04 08 00 00 ; mask_segment_two_odd_group_2 &3cb0 cc cc cc cc cc cc cc ee 00 00 00 00 00 00 00 00 &3cc0 00 11 11 11 33 33 77 ff ; sprite_legs_odd_group_2 &3cc8 12 03 12 01 01 01 00 00 0f 87 2f 86 0d 87 0f 02 &3cd8 0f 0f 04 0b 05 07 0b 08 0a 05 0a 04 08 0c 06 0a ; mask_diamond_odd_group_2 &3ce8 cc cc cc cc ee ee ee ff 00 00 00 00 00 00 00 00 &3cf8 11 11 11 11 33 33 33 77 ; sprite_player_two_bonus_odd_group_1 &3d00 30 30 30 30 30 30 10 00 dc dc dc dc dc 10 e0 00 ; sprite_diamond_odd_group_3 &3d10 00 00 00 00 00 00 00 00 ad 25 56 56 22 22 22 00 &3d20 80 00 00 00 00 00 00 00 ; sprite_claw_odd_group_3 &3d28 00 00 00 00 00 00 00 00 0f 0b 04 03 00 00 00 00 &3d38 0e 0d 06 0c 00 00 00 00 08 00 00 00 00 00 00 00 ; mask_claw_odd_group_3 &3d48 ee ff ff ff ff ff ff ff 00 00 00 88 cc ff ff ff &3d58 00 00 00 11 33 ff ff ff 33 77 ff ff ff ff ff ff ; mask_platform_group_0 &3d68 cc 88 00 00 00 00 88 cc 00 00 00 00 00 00 00 00 &3d78 44 00 00 00 00 00 00 44 cc 00 00 00 00 00 00 cc &3d88 cc 00 00 00 00 00 00 cc cc 00 00 00 00 00 00 cc &3d98 ff 00 00 00 00 00 00 cc cc 00 00 00 00 00 00 cc &3da8 cc 00 00 00 00 00 00 cc cc 00 00 00 00 00 00 cc &3db8 cc 00 00 00 00 00 00 cc ff 11 00 00 00 00 11 77 ; sprite_legs_odd_group_3 &3dc8 00 00 00 00 00 00 00 00 01 00 00 11 ab 8e cd 46 &3dd8 04 0c 0c 15 19 19 00 00 05 03 01 22 03 8d 8e 00 ; mask_diamond_odd_group_3 &3de8 ff ff ff ff ff ff ff ff 00 00 88 88 88 dd dd dd &3df8 77 77 ff ff ff ff ff ff ; mask_legs_even_group_0 &3e00 99 00 00 00 44 66 77 ff ee cc 44 00 00 11 11 11 &3e10 77 33 33 11 11 00 88 88 ff ff ff ff ff ff ff ff ; sprite_balls_even_group_0 &3e20 00 30 70 72 f4 f4 f0 f0 00 00 90 91 e2 c3 87 a7 &3e30 00 00 80 80 c0 40 48 08 ; mask_balls_even_group_0 &3e38 cc 88 88 00 00 00 00 00 ff 66 44 00 00 00 00 00 &3e48 ff 77 77 33 33 33 33 33 ; sprite_pillar_even_group_0 &3e50 00 76 76 76 76 76 76 00 00 e0 f0 e0 f0 e0 f0 00 &3e60 00 80 00 80 00 80 00 00 ; mask_pillar_even_group_0 &3e68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3e78 33 33 33 33 33 33 33 33 ; sprite_ball_three_even_group_0 &3e80 00 00 30 07 34 b4 f0 80 00 00 00 80 08 c0 c0 c0 ; sprite_head_even_group_0 &3e90 00 00 00 11 23 03 46 06 00 00 8f 0f 0c 0f 03 00 &3ea0 00 00 00 08 0c 06 0e 0f 00 00 00 00 00 00 00 00 ; mask_head_even_group_0 &3eb0 ff ff ee cc cc 88 88 88 ff 00 00 00 00 00 00 00 &3ec0 ff ff 77 33 11 11 00 00 ff ff ff ff ff ff ff ff ; sprite_mound_group_0 &3ed0 00 00 00 00 00 30 00 70 00 00 00 70 00 f0 00 f0 &3ee0 00 f0 00 f0 00 f0 00 f0 00 f0 00 f0 00 f0 00 f0 &3ef0 00 00 00 e0 00 f0 00 f0 00 00 00 00 00 c0 00 e0 ; mask_legs_even_group_1 &3f00 cc 88 88 00 00 00 00 00 11 00 00 00 00 00 00 00 &3f10 88 00 00 00 00 00 00 00 ff ff ff ff 77 33 33 33 ; sprite_balls_even_group_1 &3f20 f0 f0 60 60 30 00 13 23 4f 4f 0f 0f 0f 0f 06 06 &3f30 0c 0c 0c 0c 04 04 08 08 ; mask_balls_even_group_1 &3f38 00 00 00 00 88 88 cc 88 00 00 00 00 00 00 00 00 &3f48 33 33 33 33 33 33 33 77 ; sprite_pillar_even_group_1 &3f50 33 33 33 33 00 11 11 11 f0 e0 d0 e0 00 e8 c8 a8 &3f60 00 00 00 00 00 00 00 00 ; mask_pillar_even_group_1 &3f68 88 88 88 88 88 cc cc cc 00 00 00 00 00 00 00 00 &3f78 77 77 77 77 77 ff ff ff ; sprite_ball_three_even_group_1 &3f80 00 10 b0 70 60 30 00 00 80 c0 40 80 80 00 00 00 ; sprite_head_even_group_1 &3f90 8f 0d 27 af ae aa aa aa 0f 05 af af ab ab 88 00 &3fa0 0f 0f 08 03 16 24 14 3c 00 08 00 08 0c 84 04 84 ; mask_head_even_group_1 &3fb0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 &3fc0 00 00 00 00 00 00 00 00 77 77 33 33 33 33 33 33 ; sprite_cigar_group_0 &3fd0 00 00 01 05 05 01 00 00 01 05 05 05 05 05 05 01 &3fe0 07 37 37 37 04 04 04 07 0e 02 02 02 ce ce ce 0e &3ff0 08 0a 0a 0a 0a 0a 0a 08 00 00 08 0a 0a 08 00 00 ; mask_legs_even_group_2 &4000 00 00 00 00 88 88 cc ff 00 00 00 00 00 00 11 11 &4010 00 00 00 00 00 00 00 88 33 33 33 77 ff ff ff ff ; sprite_balls_even_group_2 &4020 27 07 07 07 07 03 03 05 0b c4 f4 f0 f0 f0 f0 60 &4030 00 80 c0 c0 c0 40 40 80 ; mask_balls_even_group_2 &4038 88 88 88 88 88 88 88 88 00 00 00 00 00 00 00 00 &4048 33 33 33 33 33 33 33 33 ; sprite_pillar_even_group_2 &4050 11 11 11 00 33 33 33 33 c8 a8 c8 00 f0 e0 d0 e0 &4060 00 00 00 00 00 00 00 00 ; mask_pillar_even_group_2 &4068 cc cc cc 88 88 88 88 88 00 00 00 00 00 00 00 00 &4078 ff ff ff 77 77 77 77 77 ; sprite_drone_even_group_0 &4080 00 03 06 87 e0 e5 e4 e1 00 00 08 04 08 04 08 04 ; sprite_head_even_group_2 &4090 88 00 00 aa aa 2f 05 06 00 00 00 aa aa af 04 0f &40a0 1c 2c 1c 06 0b 05 0a 05 04 84 04 0c 0c 04 08 00 ; mask_head_even_group_2 &40b0 11 77 11 00 00 00 00 88 ff ff ff 00 00 00 00 00 &40c0 00 00 00 00 00 00 00 00 33 33 33 33 33 33 33 77 ; sprite_ball_four_even_group_0 &40d0 00 03 27 27 4f 4f 0e 0e 00 00 08 08 40 40 c0 c0 ; sprite_ball_five_even_group_0 &40e0 00 03 17 17 83 83 c1 c1 00 00 08 08 8c 8c 0c 0c ; sprite_ball_six_even_group_0 &40f0 00 30 50 50 a0 a0 c1 c1 00 00 80 00 0c 0c 0c 0c ; mask_legs_even_group_3 &4100 77 66 44 00 00 00 00 99 11 11 11 00 44 44 cc ee &4110 88 88 00 11 11 33 33 77 ff ff ff ff ff ff ff ff ; sprite_balls_even_group_3 &4120 06 07 07 03 03 01 00 00 60 38 0a 04 04 08 00 00 &4130 80 00 00 00 00 00 00 00 ; mask_balls_even_group_3 &4138 88 88 88 88 cc cc ee ff 00 00 00 11 33 33 77 ff &4148 77 77 ff ff ff ff ff ff ; sprite_pillar_even_group_3 &4150 00 76 76 76 76 76 76 00 00 f0 f0 e0 f0 e0 f0 00 &4160 00 80 00 80 00 80 00 00 ; mask_pillar_even_group_3 &4168 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4178 33 33 33 33 33 33 33 33 ; sprite_drone_even_group_1 &4180 70 e0 10 10 f0 70 30 00 08 04 c0 40 c0 c0 80 00 ; sprite_head_even_group_3 &4190 01 02 01 00 00 00 00 00 00 0f 00 0f 00 00 00 00 &41a0 0a 04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 ; mask_head_even_group_3 &41b0 88 88 cc ee ff ff ff ff 00 00 00 00 00 ff ff ff &41c0 00 11 33 77 ff ff ff ff ff ff ff ff ff ff ff ff ; sprite_ball_four_even_group_1 &41d0 1c 1c 20 60 30 00 00 00 40 40 80 80 00 00 00 00 ; sprite_ball_five_even_group_1 &41e0 a0 a0 50 50 30 00 00 00 0c 0c 00 80 00 00 00 00 ; sprite_ball_six_even_group_1 &41f0 83 83 17 17 03 00 00 00 8c 8c 08 08 00 00 00 00 ; mask_legs_odd_group_0 &4200 ff ff ff ff ff ff ff ff 99 00 00 00 44 66 ee ee &4210 ff ee 66 66 22 22 33 33 33 11 11 00 88 cc 88 88 ; sprite_balls_odd_group_0 &4220 00 00 00 00 00 00 00 10 00 00 01 13 13 27 e3 e8 &4230 00 00 08 0c 0c 0e 0e 06 ; mask_balls_odd_group_0 &4238 ff ff ff ff ff ff ee ee ff ee cc cc 88 00 00 00 &4248 ff 77 33 33 11 11 11 11 ; sprite_pillar_odd_group_0 &4250 00 11 11 11 11 11 11 00 00 f8 f8 f8 f8 f8 f8 00 &4260 00 a0 c0 a0 c0 a0 c0 00 ; mask_pillar_odd_group_0 &4268 cc cc cc cc cc cc cc cc 00 00 00 00 00 00 00 00 &4278 00 00 00 00 00 00 00 00 ; sprite_ball_three_odd_group_0 &4280 00 00 00 01 01 21 30 20 00 00 c0 2c c2 f0 f0 30 ; sprite_head_odd_group_0 &4290 00 00 00 00 00 00 11 01 00 00 23 47 8f 0f 08 08 &42a0 00 00 0c 0e 03 0d 0f 03 00 00 00 00 00 08 08 0c ; mask_head_odd_group_0 &42b0 ff ff ff ff ff ee ee ee ff cc 88 00 00 00 00 00 &42c0 ff 33 11 00 00 00 00 00 ff ff ff ff 77 77 33 33 ; mask_mound_group_0 &42d0 ff ff ff ff ee cc 88 00 ff ee 88 00 00 00 00 00 &42e0 88 00 00 00 00 00 00 00 11 00 00 00 00 00 00 00 &42f0 ff 77 11 00 00 00 00 00 ff ff ff ff 77 33 11 00 ; mask_legs_odd_group_1 &4300 ff ff ff ee ee cc cc cc cc cc 00 00 00 00 00 00 &4310 77 22 00 00 00 00 00 00 00 11 11 11 33 11 00 00 ; sprite_balls_odd_group_1 &4320 10 31 31 30 30 30 30 00 e9 e0 f0 f0 f0 d0 30 0c &4330 0a 0c 0c 0e 0e 0e 0e 0a ; mask_balls_odd_group_1 &4338 cc cc cc cc cc cc cc cc 00 00 00 00 00 00 00 00 &4348 11 11 33 11 11 11 11 11 ; sprite_pillar_odd_group_1 &4350 00 00 00 00 00 00 00 00 fc fc fc fc 00 76 76 66 &4360 c0 80 40 80 00 80 00 80 ; mask_pillar_odd_group_1 &4368 ee ee ee ee ee ff ff ff 00 00 00 00 00 00 00 00 &4378 11 11 11 11 11 33 33 33 ; sprite_ball_three_odd_group_1 &4380 00 00 20 10 10 00 00 00 20 70 d0 e0 a0 c0 00 00 ; sprite_head_odd_group_1 &4390 23 03 01 23 23 22 22 22 0f 05 af af aa aa aa 88 &43a0 0f 07 8e 8c 8d 8d 01 03 0c 0e 00 0e 4b a1 41 e1 ; mask_head_odd_group_1 &43b0 cc cc cc cc cc cc cc cc 00 00 00 00 00 00 00 11 &43c0 00 00 00 00 00 00 00 cc 00 00 00 00 00 00 00 00 ; mask_cigar_group_0 &43d0 ff ee 88 00 00 88 ee ff 88 00 00 00 00 00 00 88 &43e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &43f0 11 00 00 00 00 00 00 11 ff 77 11 00 00 11 77 ff ; mask_legs_odd_group_2 &4400 cc cc cc cc ee ee ff ff 00 00 00 00 00 00 00 88 &4410 00 00 00 00 00 00 00 44 00 00 11 33 77 33 11 00 ; sprite_balls_odd_group_2 &4420 01 01 13 13 03 03 03 03 8f 8e 0f 0f 0f 0f 0d 0d &4430 0a 0c 00 c0 e8 e8 f0 f0 ; mask_balls_odd_group_2 &4438 ee cc cc cc cc cc cc cc 00 00 00 00 00 00 00 00 &4448 11 33 77 33 11 11 00 00 ; sprite_pillar_odd_group_2 &4450 00 00 00 00 00 00 00 00 76 66 76 00 fc fc fc fc &4460 00 80 00 00 c0 80 40 80 ; mask_pillar_odd_group_2 &4468 ff ff ff ee ee ee ee ee 00 00 00 00 00 00 00 00 &4478 33 33 33 11 11 11 11 11 ; sprite_droid_odd_group_0 &4480 00 00 01 21 30 31 31 30 00 0c 0a 0d 82 85 82 85 ; sprite_head_odd_group_2 &4490 22 00 00 22 22 03 01 01 00 00 00 aa aa af 05 0b &44a0 03 03 03 89 8a 8d 02 0d 41 a1 41 0b 0f 05 0a 04 ; mask_head_odd_group_2 &44b0 cc dd cc cc cc cc cc ee 77 ff 77 00 00 00 00 00 &44c0 cc cc cc 00 00 00 00 00 00 00 00 00 00 00 00 11 ; sprite_ball_four_odd_group_0 &44d0 00 10 10 00 03 03 03 03 00 c0 a0 a0 50 50 38 38 ; sprite_ball_five_odd_group_0 &44e0 00 00 01 01 20 20 30 30 00 0c 4e 4e 2f 2f 07 07 ; sprite_ball_six_odd_group_0 &44f0 00 00 10 10 20 20 30 30 00 e0 60 40 83 83 07 07 ; mask_legs_odd_group_3 &4500 ff ff ff ff ff ff ff ff cc 66 66 22 00 00 00 88 &4510 22 33 33 22 22 66 66 ff 00 00 88 cc 88 00 11 11 ; sprite_balls_odd_group_3 &4520 01 21 20 30 10 10 00 00 0a 1e 1c 30 90 90 00 00 &4530 f0 f0 d0 d0 a0 a0 c0 00 ; mask_balls_odd_group_3 &4538 cc cc cc cc cc ee ee ff 00 00 00 00 00 66 66 ff &4548 00 00 00 00 00 11 11 33 ; sprite_pillar_odd_group_3 &4550 00 11 11 11 11 11 11 00 00 f8 f8 f8 f8 f8 f8 00 &4560 00 e0 c0 a0 c0 a0 c0 00 ; mask_pillar_odd_group_3 &4568 cc cc cc cc cc cc cc cc 00 00 00 00 00 00 00 00 &4578 00 00 00 00 00 00 00 00 ; sprite_droid_odd_group_1 &4580 10 30 00 00 30 10 00 00 c2 81 70 50 f0 f0 e0 00 ; sprite_head_odd_group_3 &4590 00 00 00 00 00 00 00 00 04 0b 04 03 00 00 00 00 &45a0 02 0d 02 0c 00 00 00 00 08 00 00 00 00 00 00 00 ; mask_head_odd_group_3 &45b0 ee ee ff ff ff ff ff ff 00 00 00 88 cc ff ff ff &45c0 00 00 00 11 33 ff ff ff 33 77 ff ff ff ff ff ff ; sprite_ball_four_odd_group_1 &45d0 13 13 01 01 00 00 00 00 1c 1c 8e 8e 0c 00 00 00 ; sprite_ball_five_odd_group_1 &45e0 20 20 10 10 00 00 00 00 83 83 40 60 c0 00 00 00 ; sprite_ball_six_odd_group_1 &45f0 20 20 01 01 00 00 00 00 2f 2f 4e 4e 0c 00 00 00 ; horizon_0_sprite # Woodland &4600 00 00 00 00 00 00 00 99 11 00 22 22 bb 66 55 55 &4610 00 88 cc 66 cc aa 66 88 00 00 00 00 88 00 22 66 &4620 00 00 00 00 00 00 88 44 00 00 00 00 00 11 22 22 &4630 00 00 00 00 88 44 22 11 22 99 11 46 02 13 22 55 &4640 00 00 33 44 88 00 aa 22 66 99 00 00 44 11 00 44 &4650 00 00 88 77 00 00 44 11 00 00 00 00 88 44 aa 99 &4660 00 00 00 00 00 11 ee 00 00 00 00 00 ff 00 00 00 &4670 00 00 00 00 00 cc 22 11 00 00 00 00 00 00 00 00 &4680 00 00 00 00 22 22 00 22 00 00 00 00 00 00 00 00 &4690 00 00 44 44 44 44 44 aa 00 00 00 00 00 00 44 00 &46a0 00 22 22 22 00 22 77 55 00 00 00 00 00 00 00 00 &46b0 00 00 00 00 00 00 00 99 00 00 00 00 00 66 cc 00 &46c0 00 00 00 00 11 88 22 44 00 33 44 88 00 00 00 00 &46d0 00 ee 11 00 00 00 88 00 00 00 ee 11 00 88 44 00 &46e0 00 00 00 99 66 00 00 00 00 00 00 cc 22 11 00 88 &46f0 00 00 00 00 00 00 cc 33 00 00 00 00 00 00 00 88 &4700 22 00 00 44 11 80 00 aa 55 88 22 00 00 40 33 ff &4710 bb 88 2a 08 08 6e 7f 7f 77 00 88 77 c4 00 b8 ee &4720 55 cc 88 22 6e 4c 08 19 44 88 00 11 00 22 77 ff &4730 00 22 44 00 00 00 88 ee aa 77 44 11 33 33 67 01 &4740 00 88 00 00 88 88 cc 00 00 88 99 99 bb bb 09 09 &4750 11 33 33 77 ff 89 01 01 00 88 88 cc cc 00 00 11 &4760 00 11 88 55 ee ee 04 04 00 11 22 44 66 33 00 00 &4770 88 44 44 aa 44 ee 08 08 cc 22 33 00 aa 02 02 ff &4780 55 22 55 22 77 55 02 8a 00 00 55 11 55 44 04 bf &4790 ee aa 55 bb 55 04 04 ff 44 aa 44 44 44 04 ff ff &47a0 22 55 aa 77 8a 02 22 ff 77 00 99 00 88 04 15 ff &47b0 22 00 88 11 00 04 ff ff 33 77 ff aa df 02 02 df &47c0 00 88 00 99 33 67 01 01 00 00 00 00 88 bb 33 01 &47d0 00 00 00 44 00 11 00 11 22 00 22 66 66 02 00 cc &47e0 00 22 00 44 dd 19 00 88 33 00 00 00 88 00 08 23 &47f0 88 20 00 ea 33 20 06 69 44 00 99 22 44 44 00 6e ; horizon_1_sprite # Desert &4800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4830 00 00 00 00 00 00 00 44 00 00 00 00 00 00 00 00 &4840 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 00 &4850 00 00 00 00 11 11 33 33 44 44 ee cc ff ee ff ff &4860 00 00 00 00 00 00 88 00 00 00 00 00 11 00 00 00 &4870 00 00 00 00 99 55 22 57 00 00 00 88 44 22 00 00 &4880 00 44 aa 99 11 00 66 89 00 00 00 33 44 08 4c 22 &4890 00 00 00 00 88 44 44 00 11 00 33 33 33 33 33 33 &48a0 00 00 88 00 88 00 88 00 00 00 00 00 00 00 00 00 &48b0 00 00 00 00 00 00 00 00 00 00 00 00 00 11 00 00 &48c0 00 00 00 00 cc 22 00 23 00 00 00 00 00 00 cc 22 &48d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &48e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &48f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4900 00 f0 00 00 f0 00 f0 fc 00 f0 00 00 f1 33 f7 ff &4910 00 e2 77 ee ff ff ff ff 00 f0 00 88 74 aa dd ee &4920 00 f0 00 00 f0 00 f0 f8 00 f0 00 00 f0 00 f1 f1 &4930 33 c4 77 77 f7 00 bb 88 ff cc ff 33 ff 00 ff 00 &4940 00 f8 88 88 f8 00 76 76 00 f0 00 00 f1 11 f3 f3 &4950 77 f7 ff ff ff ff ff ff ff ff ff ff ff ff dd dd &4960 cc 98 66 cc bb ee dd ff 00 f1 00 00 f0 00 f8 71 &4970 8a b4 04 04 78 08 79 ff 99 f8 44 44 f0 00 ff ff &4980 01 e1 02 02 d2 ff ff ff 11 f0 00 00 f0 88 fe ff &4990 00 f8 00 00 f0 00 f0 fe 33 f3 33 33 f3 33 f7 f7 &49a0 88 70 88 00 f8 00 fc fc 00 f0 44 0e f0 00 f0 ff &49b0 00 f0 00 11 e1 00 f0 ff 00 f0 00 00 78 00 f0 fc &49c0 45 e9 02 02 d2 02 d3 ff 88 f4 22 22 f0 cc ff ff &49d0 00 f0 00 00 f0 00 f0 fc 00 f0 00 00 ff bb ee ee &49e0 00 f0 00 00 fe aa fe fe 00 f0 00 00 f0 00 f0 f7 &49f0 00 f0 00 00 f2 55 ee ff 00 f0 00 00 f0 00 f8 74 ; horizon_2_sprite # Volcanoes &4a00 00 00 00 00 00 00 00 00 00 01 02 05 00 26 26 66 &4a10 10 80 1a 40 00 00 00 00 20 0c 00 00 00 00 00 00 &4a20 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4a30 00 00 00 00 00 00 00 00 00 00 00 00 02 05 02 04 &4a40 00 00 10 80 00 00 00 00 00 00 80 00 00 00 00 44 &4a50 00 00 00 00 00 00 00 01 00 00 00 00 00 00 20 00 &4a60 00 00 00 00 00 20 00 00 00 00 00 00 00 00 00 11 &4a70 00 11 22 00 44 aa 00 00 00 00 88 00 44 00 22 11 &4a80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4a90 00 01 06 01 26 46 66 46 08 02 48 00 00 00 00 00 &4aa0 00 00 80 00 00 00 00 00 00 00 00 00 00 00 66 88 &4ab0 00 00 00 00 00 00 00 00 00 00 00 00 00 11 02 22 &4ac0 00 00 00 00 00 00 88 00 00 00 00 00 00 11 22 01 &4ad0 00 00 00 00 88 44 2a 11 00 00 00 00 00 00 00 00 &4ae0 00 00 00 00 00 00 00 00 20 00 80 00 80 00 08 88 &4af0 00 00 20 00 00 00 00 44 00 40 00 00 00 00 00 00 &4b00 00 00 00 01 13 33 37 ee 19 7f bb 55 44 bb 44 ff &4b10 00 00 88 88 dd 66 aa dd 00 33 55 aa 44 88 22 88 &4b20 00 00 88 44 22 11 00 11 02 22 33 22 37 77 6e ff &4b30 00 00 00 88 00 cc 89 ff 66 66 26 55 7f ee ff cc &4b40 00 11 66 00 00 88 89 77 bb 00 88 44 00 00 ee 11 &4b50 02 88 02 22 33 37 66 ff 00 00 00 88 66 11 88 66 &4b60 00 00 00 11 22 88 02 aa 22 44 aa 00 01 4c dd dd &4b70 88 00 22 00 cc 00 44 55 00 00 00 00 00 11 8a ff &4b80 88 44 22 00 00 00 88 55 00 00 00 00 89 11 13 77 &4b90 66 5f df df ef ef dd ee 00 00 00 00 11 2a 08 8f &4ba0 11 22 55 88 44 00 00 0e 55 00 00 00 00 00 11 27 &4bb0 00 00 88 44 22 11 00 ff 11 44 aa 00 00 44 11 99 &4bc0 44 22 11 00 00 00 00 55 44 00 00 00 6e 04 44 55 &4bd0 00 00 00 02 22 37 55 55 cc 33 00 00 00 00 00 77 &4be0 00 00 88 44 01 11 13 ee 88 19 aa 88 55 cc aa dd &4bf0 aa 00 99 00 00 00 00 00 00 00 00 00 88 44 11 33 ; horizon_3_sprite # Industrial &4c00 00 00 00 00 00 00 00 00 00 00 11 33 32 32 32 32 &4c10 00 00 88 c0 c0 f7 38 c0 00 00 00 00 00 ff f1 00 &4c20 00 00 00 00 00 ff f0 99 00 00 00 00 00 ff ba f5 &4c30 00 00 00 00 00 ff f1 32 00 00 00 00 00 ff 00 00 &4c40 00 00 00 00 00 ff 30 77 00 88 22 22 22 ff ff ff &4c50 00 88 00 00 00 88 ee bb 00 11 00 00 00 00 00 00 &4c60 00 20 00 00 00 00 00 00 00 08 02 10 11 10 11 10 &4c70 00 00 00 00 00 00 00 00 77 74 62 11 40 00 40 00 &4c80 ff f1 32 64 c8 44 22 11 ff 77 f8 cc ea b9 ba 64 &4c90 88 88 88 88 88 88 88 88 00 00 00 11 11 32 22 75 &4ca0 00 ff fc 62 b9 ba 64 ea 00 ff f8 88 88 88 88 88 &4cb0 04 c8 40 40 e0 40 40 40 00 00 00 00 10 00 00 00 &4cc0 08 80 80 80 c0 80 80 80 00 00 00 00 00 00 00 00 &4cd0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4ce0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &4cf0 00 00 00 00 00 22 00 02 00 00 00 00 00 00 00 00 &4d00 00 00 00 00 00 20 33 0f 32 32 32 30 76 76 f8 0f &4d10 48 80 c0 08 e1 e0 e0 0f 00 00 03 0c 00 00 11 03 &4d20 54 22 99 06 88 88 44 0f 64 64 75 ba 65 6c 64 0f &4d30 64 c8 80 00 01 0a 04 00 00 13 15 3b 33 33 33 07 &4d40 ff bf ff ff ff dd dd 0f ff 3f ff dd dd 88 88 0f &4d50 dd 6e ff ff ff ff ff 0f 88 cf 44 ee aa ee ee 0f &4d60 00 08 04 02 01 00 00 00 11 10 33 44 4a 47 88 0f &4d70 00 00 88 44 40 4c 22 0e 40 00 04 0a 0a 00 00 00 &4d80 00 00 00 00 00 00 00 01 c8 cc ea b9 ba ec c8 0f &4d90 88 88 88 99 99 bb bb 0f 54 ea b9 d4 62 31 ff 0f &4da0 b9 ba 64 ea b9 ba ff 0f 88 88 88 88 88 88 98 1c &4db0 e8 c0 e8 c0 e0 c0 f0 f0 11 10 11 10 10 10 30 30 &4dc0 c0 80 c0 80 c0 80 e0 e0 00 00 00 10 30 03 10 07 &4dd0 00 00 11 95 97 0e 40 0f 00 ff aa ff cf 12 10 0f &4de0 00 ee bb ff 1f 4a 40 0f 00 00 00 00 11 02 55 0f &4df0 55 0a 55 0a 55 0a 55 0f 00 08 00 08 44 0a 55 0f ; TOPSTR ; 006480 006840 000140 &6480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # Score section &6490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &64a0 00 00 00 00 00 00 00 00 08 08 08 08 08 08 0f 00 &64b0 04 04 04 04 04 04 0c 00 03 03 03 03 03 03 03 00 &64c0 00 00 00 00 00 00 00 00 08 08 08 08 08 08 0f 00 &64d0 04 04 04 04 04 04 0c 00 08 08 08 08 08 08 0f 00 &64e0 04 04 04 04 04 04 0c 00 08 08 08 08 08 08 08 00 &64f0 04 04 04 04 04 04 04 00 08 08 08 08 08 08 0f 00 &6500 04 04 04 04 04 04 0c 00 00 00 00 00 00 00 00 00 &6510 00 00 00 00 00 00 00 00 09 09 09 09 09 09 0f 00 &6520 02 02 02 02 02 02 0e 00 08 08 08 08 08 08 08 00 &6530 04 04 04 04 04 04 04 00 08 08 08 08 08 08 08 00 &6540 04 04 04 04 04 04 04 00 08 08 08 08 08 08 08 00 &6550 04 04 04 04 04 04 04 00 03 03 03 03 03 03 0f 00 &6560 00 00 00 00 00 00 0c 00 08 08 08 08 08 08 0f 00 &6570 04 04 04 04 04 04 0c 00 08 08 08 08 08 08 08 00 &6580 04 04 04 04 04 04 04 00 00 00 00 00 00 00 0f 00 &6590 04 04 04 04 04 04 0c 00 00 00 00 00 00 00 00 00 &65a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &65b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; BOTSTR ; 007880 007880 0003c0 &7880 00 00 00 00 00 00 00 00 80 80 80 80 80 80 80 80 # Status section &7890 33 66 66 66 66 66 33 00 cc 66 00 00 00 66 cc 00 &78a0 66 66 66 66 66 66 33 00 66 66 66 66 66 66 cc 00 &78b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &78c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &78d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &78e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &78f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7920 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7930 10 10 10 00 00 00 00 00 20 40 40 c0 c0 50 10 00 &7940 00 00 00 00 00 00 00 00 70 40 30 20 10 10 00 00 &7950 80 00 c0 00 e0 00 f0 80 00 00 00 00 00 00 b0 b0 &7960 00 00 00 00 00 00 e0 e0 10 00 30 00 70 00 f0 80 &7970 f0 10 e0 20 c0 40 80 80 00 00 00 00 00 00 00 00 &7980 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7990 40 d0 90 80 a0 a0 80 80 00 00 00 00 00 00 00 00 &79a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &79b0 30 10 10 10 10 10 10 10 00 00 00 00 00 00 00 00 &79c0 00 00 00 00 00 00 00 00 80 80 80 80 80 80 80 80 &79d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &79e0 33 66 66 77 77 66 33 00 cc 66 ee ee 66 66 cc 00 &79f0 33 66 00 11 00 66 33 00 cc 66 66 cc 66 66 cc 00 &7a00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7a10 33 66 66 77 77 66 33 00 cc 66 ee ee 66 66 cc 00 &7a20 00 11 33 66 77 00 00 00 cc cc cc cc ee cc cc 00 &7a30 33 66 66 77 77 66 33 00 cc 66 ee ee 66 66 cc 00 &7a40 33 66 66 77 77 66 33 00 cc 66 ee ee 66 66 cc 00 &7a50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7a70 10 10 10 10 10 10 10 10 00 00 00 00 00 00 00 00 &7a80 80 00 40 00 20 00 10 00 00 00 00 00 00 00 00 00 &7a90 70 40 30 30 00 00 00 00 b0 b0 b0 b0 00 70 70 70 &7aa0 e0 e0 e0 e0 00 f0 f0 e0 f0 90 e0 e0 00 00 00 00 &7ab0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7ac0 00 00 00 00 00 00 00 30 00 00 00 30 30 c0 c0 00 &7ad0 e0 f0 10 00 c0 00 c0 00 00 00 80 c0 40 20 20 10 &7ae0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7af0 10 20 20 20 20 20 20 40 00 00 00 00 00 00 00 00 &7b00 00 00 00 00 00 00 00 00 80 80 80 80 80 80 80 80 &7b10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7b90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7ba0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &7bb0 10 10 10 10 10 10 10 10 00 00 00 00 00 00 00 00 &7bc0 00 00 00 00 00 00 00 00 80 00 40 00 20 00 10 00 &7bd0 00 00 00 10 10 10 10 10 70 00 f0 f0 f0 f0 f0 f0 &7be0 f0 00 f0 f0 f0 f0 f0 f0 00 00 80 70 a0 f0 f0 f0 &7bf0 00 00 10 e0 b0 50 f0 f0 10 60 b0 d0 70 f0 f0 f0 &7c00 b0 c0 40 a0 e0 e0 e0 e0 30 00 c0 00 00 00 00 00 &7c10 00 00 00 00 00 00 00 00 10 10 00 00 00 00 00 00 &7c20 00 00 80 80 80 80 40 40 00 00 00 00 00 00 00 10 &7c30 40 40 40 80 80 80 00 00 00 00 00 00 00 00 00 00