Kix disassembly =============== Published by Superior Software for the BBC Micro in 1986, Kix is a conversion of Taito's 1981 arcade game Qix. The player must draw lines to enclose areas of the screen, avoiding the sparklers, which move around the unenclosed space, the tracers, which travel along the boundaries, and the fuse, which chases the player after hesitation. A level may be won by filling more than three quarters of its area, or by splitting it into two regions, each containing one sparkler. The following disassembly was created by reverse engineering a binary image 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's italic font is generated on the fly by intercepting OSWRCH. GCOL 1, 128 at the start of the game stops CLG from clearing the graphics area. The sound in the demo mode is limited by intercepting OSWORD. Game-play notes =============== The game has twenty levels, which cycle through four colours. After level twenty, the game repeats from level eleven, continuing the same colour order. The final position of the player determines the type of sparklers on the high score screen. If the player was in the left half of the screen, one large sparkler is plotted. If the player was in the right half of the screen, two sparklers are plotted. The player's vertical position determines the stability of these sparklers. If the player was in the bottom quarter of the screen, both sparklers are stable. If the player was in the top quarter of the screen, both are chaotic. Otherwise, one sparkler is stable and one is chaotic. If the level has only one sparkler, splitting it kills the player. The demo level can only be won by splitting. Pressing TAB starts a new level. Interesting pokes ================= &1cab = &a6, &23c6 = &a5, &24f0 = &a5 infinite lives &1568 = &ea infinite time &1317 = &02 player is invulnerable to tracers Disassembly =========== ; KIX1 ; 0035800 006300 003680 # &3580 - &61ff is moved to &0380 - &2fff at &6253 ; unused &0380 0d ; row_multiplication_table &0381 00 00 &0383 02 80 &0385 05 00 &0387 07 80 &0389 0a 00 &038b 0c 80 &038d 0f 00 &038f 11 80 &0391 14 00 &0393 16 80 &0395 19 00 &0397 1b 80 &0399 1e 00 &039b 20 80 &039d 23 00 &039f 25 80 &03a1 28 00 &03a3 2a 80 &03a5 2d 00 &03a7 2f 80 &03a9 32 00 &03ab 34 80 &03ad 37 00 &03af 39 80 &03b1 3c 00 &03b3 3e 80 &03b5 41 00 &03b7 43 80 &03b9 46 00 &03bb 48 80 &03bd 4b 00 &03bf 4d 80 ; unused &03c1 3a 4f 58 54 45 ; ":OXTE" ; define_character_e1_string # Used prior to relocation &35c6 17 e1 08 14 22 41 22 14 08 00 ; Define character &e1 ; call_previous_osbyte_vector &03d0 6c f0 02 JMP (&02f0) ; previous_osbyte_vector &03d3 ea NOP ; call_previous_osword_vector &03d4 6c f2 02 JMP (&02f2) ; previous_osword_vector &03d7 ea NOP ; call_previous_oswrch_vector &03d8 6c f4 02 JMP (&02f4) ; previous_oswrch_vector &03db ea NOP ; call_previous_insv_vector &03dc 6c f6 02 JMP (&02f6) ; previous_insv_vector &03df ea NOP ; define_character_e1 # Used prior to relocation &35e0 a2 00 LDX #&00 ; write_define_character_e1_loop &35e2 bd c6 35 LDA &35c6,X ; define_character_e1_string &35e5 20 ee ff JSR &ffee ; OSWRCH &35e8 e8 INX &35e9 e0 0a CPX #&0a &35eb 90 f5 BCC &35e2 ; write_define_character_e1_loop &35ed a2 00 LDX #&00 &35ef 60 RTS ; unused &03f0 48 45 4c 4c 4f 20 47 55 59 53 20 21 21 21 0d ; "HELLO GUYS !!!" &03ff 20 ; " " ; demo_scrolltext &0400 20 20 20 20 50 4f 49 4e 54 53 20 66 6f 72 20 46 ; " POINTS for F" &0410 49 4c 4c 49 4e 47 20 28 70 65 72 20 70 65 72 63 ; "ILLING (per perc" &0420 65 6e 74 29 3a 20 51 55 49 43 4b 2d 44 52 41 57 ; "ent): QUICK-DRAW" &0430 20 3d 20 33 20 20 6f 72 20 20 53 4c 4f 57 2d 44 ; " = 3 or SLOW-D" &0440 52 41 57 20 3d 20 33 30 20 3b 20 61 62 6f 76 65 ; "RAW = 30 ; above" &0450 20 37 35 25 3a 20 51 55 49 43 4b 20 3d 20 39 30 ; " 75%: QUICK = 90" &0460 20 20 6f 72 20 20 53 4c 4f 57 20 3d 20 39 39 2e ; " or SLOW = 99." &0470 20 20 20 53 70 6c 69 74 74 69 6e 67 20 67 69 76 ; " Splitting giv" &0480 65 73 20 42 4f 4e 55 53 3a 20 51 55 49 43 4b 20 ; "es BONUS: QUICK " &0490 3d 20 31 30 30 20 20 6f 72 20 20 53 4c 4f 57 20 ; "= 100 or SLOW " &04a0 3d 20 31 30 30 30 2e 20 20 20 54 49 4d 45 2d 42 ; "= 1000. TIME-B" &04b0 4f 4e 55 53 20 61 66 74 65 72 20 63 6f 6d 70 6c ; "ONUS after compl" &04c0 65 74 69 6e 67 20 61 20 6c 65 76 65 6c 2e 20 20 ; "eting a level. " &04d0 20 20 59 6f 75 20 67 65 74 20 61 6e 20 45 58 54 ; " You get an EXT" &04e0 52 41 20 4c 49 46 45 20 65 76 65 72 79 20 31 30 ; "RA LIFE every 10" &04f0 30 30 30 20 70 6f 69 6e 74 73 2e 20 20 20 20 20 ; "000 points. " ; demo_screen_setup_string &0500 1a ; restore default windows &0501 0c ; clear screen &0502 1f 23 09 ; TAB(&23, &09) &0505 44 45 4d 4f ; "DEMO" &0509 13 01 05 00 00 00 ; set colour 1 to magenta &050f 13 02 03 00 00 00 ; set colour 2 to yellow &0515 13 03 07 00 00 00 ; set colour 3 to white ; high_score_text_window_string &051b 1c 00 1f 20 00 ; define text window x:(&00, &20), y:(&00, &1f) ; high_score_input_block &0520 00 05 ; &0500 # First byte is set to offset in high_scores &0522 06 ; 6 characters maximum &0523 20 ; " " &0524 7f ; BACKSPACE ; high_score_table_string &0525 16 01 ; MODE 1 &0527 11 02 ; COLOUR 2 &0529 1c 0c 1f 1a 05 ; define text window x:(&0c, &1a), y:(&05, &1f) &052e 0a ; high_scores &052f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &053f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &054f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &055f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &056f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &057f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &058f 20 20 20 20 20 20 20 20 20 20 20 20 20 0d 0a 0a &059f 20 20 20 20 20 20 20 20 20 20 20 20 20 &05ac 00 00 &05ae 1a ; restore default windows &05af 00 ; press_space_fire_tab_or_k_string &05b0 1f 00 1f ; TAB(&00, &1f) &05b3 20 20 20 20 20 20 20 20 50 52 45 53 53 20 53 50 ; " PRESS SPACE,FIRE,TAB or K " &05c3 41 43 45 2c 46 49 52 45 2c 54 41 42 20 6f 72 20 &05d3 4b 20 20 20 20 20 0d ; get_random_velocity &05da a0 08 LDY #&08 ; shuffle_prnd_loop &05dc 18 CLC &05dd a5 be LDA &be ; rnd_state + 6 &05df 10 0c BPL &05ed ; skip_eor &05e1 a2 02 LDX #&02 ; eor_pnd_state_loop &05e3 b5 bb LDA &bb,X ; rnd_state + 3 &05e5 55 b8 EOR &b8,X ; rnd_state &05e7 95 bb STA &bb,X ; rnd_state + 3 &05e9 ca DEX &05ea 10 f7 BPL &05e3 ; eor_pnd_state_loop &05ec 38 SEC ; skip_eor &05ed 26 bb ROL &bb ; rnd_state + 3 &05ef 26 bc ROL &bc ; rnd_state + 4 &05f1 26 bd ROL &bd ; rnd_state + 5 &05f3 26 be ROL &be ; rnd_state + 6 &05f5 88 DEY &05f6 d0 e4 BNE &05dc ; shuffle_prnd_loop &05f8 a5 be LDA &be ; rnd_state + 6 &05fa 29 87 AND #&87 &05fc 60 RTS ; unused &05fd 09 ; colour_0_or_3_pixel_values &05fe 00 11 ; pause_string # Written backwards &0600 00 00 00 08 02 13 ; set colour 2 to flashing black/white &0606 45 53 55 41 50 ; "PAUSE" &060c 0f 0d 1f ; TAB(&0d, &0f) &060f 02 11 ; COLOUR 2 ; unpause_string # Written backwards &0610 03 11 ; COLOUR 3 &0612 00 00 00 07 02 13 ; set colour 2 to white (bug: should be yellow) ; unused &0618 55 00 87 56 00 00 00 2a ; game_over_string &0620 1c 22 1e 27 01 ; define text window x:(&22, &27), y:(&01, &1e) &0625 1f 01 1d ; TAB(&01, &1d) &0628 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a &0633 47 0a ; "G" &0635 41 0a ; "A" &0637 4d 0a ; "M" &0639 45 0a ; "E" &063b 0d 20 ; " " &006e 4f 0a ; "O" &063f 56 0a ; "V" &0641 45 0a ; "E" &0643 52 0a ; "R" &0645 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a ; check_for_fire_pressed &0650 a9 80 LDA #&80 ; Read I/O device or buffer status &0652 a2 00 LDX #&00 ; joystick buttons &0654 20 f4 ff JSR &fff4 ; OSBYTE &0657 8a TXA &0658 4a LSR A &0659 a2 04 LDX #&04 # Unnecessary code &065b 60 RTS # Leaves with carry set if fire pressed ; insv_handler &065c 85 66 STA &66 ; last_key_pressed &065e 4c dc 03 JMP &03dc ; call_previous_insv_vector ; update_high_score_screen_sparkler &0661 a9 20 LDA #&20 &0663 8d 6f 0b STA &0b6f ; timer_ready # Set to positive to wait for next timer event &0666 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &0669 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &066c c6 cf DEC &cf ; high_score_screen_sparkler_line_to_use &066e d0 23 BNE &0693 ; apply_velocities &0670 a9 27 LDA #&27 &0672 85 cf STA &cf ; high_score_screen_sparkler_line_to_use &0674 c6 ce DEC &ce ; high_score_screen_sparkler_velocity_change_timer &0676 10 1b BPL &0693 ; apply_velocities &0678 20 da 05 JSR &05da ; get_random_velocity &067b 29 07 AND #&07 &067d 85 ce STA &ce ; high_score_screen_sparkler_velocity_change_timer &067f 20 da 05 JSR &05da ; get_random_velocity &0682 85 c4 STA &c4 ; sparkler_velocities &0684 20 da 05 JSR &05da ; get_random_velocity &0687 85 c5 STA &c5 ; sparkler_velocities + 1 &0689 20 da 05 JSR &05da ; get_random_velocity &068c 85 c6 STA &c6 ; sparkler_velocities + 2 &068e 20 da 05 JSR &05da ; get_random_velocity &0691 85 c7 STA &c7 ; sparkler_velocities + 3 ; apply_velocities &0693 a2 03 LDX #&03 ; apply_velocities_loop &0695 b5 c4 LDA &c4,X ; sparkler_velocities &0697 10 0b BPL &06a4 ; velocity_is_positive ; velocity_is_negative &0699 29 0f AND #&0f &069b 18 CLC &069c 75 c0 ADC &c0,X ; sparkler_coordinates &069e b0 0f BCS &06af ; flip_velocity &06a0 95 c0 STA &c0,X ; sparkler_coordinates &06a2 90 11 BCC &06b5 ; consider_next_velocity # Always branches ; velocity_is_positive &06a4 b5 c0 LDA &c0,X ; sparkler_coordinates &06a6 38 SEC &06a7 f5 c4 SBC &c4,X ; sparkler_velocities &06a9 90 04 BCC &06af ; flip_velocity &06ab 95 c0 STA &c0,X ; sparkler_coordinates &06ad b0 06 BCS &06b5 ; consider_next_velocity # Always branches ; flip_velocity &06af b5 c4 LDA &c4,X ; sparkler_velocities &06b1 49 80 EOR #&80 &06b3 95 c4 STA &c4,X ; sparkler_velocities ; consider_next_velocity &06b5 ca DEX &06b6 10 dd BPL &0695 ; apply_velocities_loop &06b8 a6 cf LDX &cf ; high_score_screen_sparkler_line_to_use &06ba bd 28 01 LDA &0128,X ; high_score_screen_sparkler_lines_start_y &06bd 85 51 STA &51 ; line_start_y &06bf bd 00 01 LDA &0100,X ; high_score_screen_sparkler_lines_start_x &06c2 85 50 STA &50 ; line_start_x &06c4 bc 78 01 LDY &0178,X ; high_score_screen_sparkler_lines_end_y &06c7 bd 50 01 LDA &0150,X ; high_score_screen_sparkler_lines_end_x &06ca aa TAX &06cb 20 ca 1c JSR &1cca ; draw_line &06ce a6 cf LDX &cf ; high_score_screen_sparkler_line_to_use &06d0 a5 c1 LDA &c1 ; sparklers_first_line_start_y &06d2 85 51 STA &51 ; line_start_y &06d4 9d 28 01 STA &0128,X ; high_score_screen_sparkler_lines_start_y &06d7 a5 c0 LDA &c0 ; sparklers_first_line_start_x &06d9 85 50 STA &50 ; line_start_x &06db 9d 00 01 STA &0100,X ; high_score_screen_sparkler_lines_start_x &06de a4 c3 LDY &c3 ; sparklers_first_line_end_y &06e0 98 TYA &06e1 9d 78 01 STA &0178,X ; high_score_screen_sparkler_lines_end_y &06e4 a5 c2 LDA &c2 ; sparklers_first_line_end_x &06e6 9d 50 01 STA &0150,X ; high_score_screen_sparkler_lines_end_x &06e9 aa TAX &06ea 20 ca 1c JSR &1cca ; draw_line ; wait_for_timer &06ed 2c 6f 0b BIT &0b6f ; timer_ready # Negative after timer event &06f0 10 fb BPL &06ed ; wait_for_timer &06f2 60 RTS ; unused &06f3 32 00 88 36 00 ; sound_0 # Sparkler hitting boundary ; chan vol pitch dur &06f8 10 00 09 00 02 00 01 00 # (pitch is modified) ; game_scrolltext &0700 54 68 69 73 20 69 73 20 4b 49 58 2e 20 54 68 65 ; "This is KIX. The" &0710 20 67 61 6d 65 20 28 32 30 20 73 63 65 6e 65 73 ; " game (20 scenes" &0720 29 20 69 73 20 70 6c 61 79 65 64 20 62 79 20 54 ; ") is played by T" &0730 48 45 20 4b 49 58 20 61 6e 64 20 54 48 45 20 46 ; "HE KIX and THE F" &0740 49 4c 4c 45 52 2e 20 41 6c 73 6f 20 73 74 61 72 ; "ILLER. Also star" &0750 72 69 6e 67 3a 54 48 45 20 46 55 53 45 20 61 6e ; "ring:THE FUSE an" &0760 64 20 54 52 41 43 45 52 53 20 31 2c 32 2c 33 2c ; "d TRACERS 1,2,3," &0770 34 2e 20 53 63 65 6e 61 72 69 6f 3a 41 47 41 2e ; "4. Scenario:AGA." &0780 20 4d 75 73 69 63 3a 4e 45 55 45 54 52 4f 55 53 ; " Music:NEUETROUS" &0790 45 52 53 2e 20 44 65 63 6f 72 61 74 69 6f 6e 3a ; "ERS. Decoration:" &07a0 41 47 41 2e 20 54 65 73 74 69 6e 67 3a 53 50 41 ; "AGA. Testing:SPA" &07b0 43 45 20 4d 4f 4e 4b 45 59 2e 20 50 72 6f 64 75 ; "CE MONKEY. Produ" &07c0 63 65 64 20 61 6e 64 20 64 69 72 65 63 74 65 64 ; "ced and directed" &07d0 20 62 79 20 53 49 52 20 48 41 4c 45 57 49 4a 4e ; " by SIR HALEWIJN" &07e0 20 28 41 47 41 29 2e 20 28 43 29 31 39 38 36 20 ; " (AGA). (C)1986 " &07f0 53 75 70 65 72 69 6f 72 20 20 20 20 20 20 20 20 ; "Superior " ## &3a00 - &3a7f is used in place, wiped for &0800 - &087f ; press_space_or_fire_string &3a00 1f 0a 18 ; TAB(&0a, &18) &3a03 88 ; FLASH &3a04 50 72 65 73 73 20 53 50 41 43 45 20 6f 72 20 46 ; "Press SPACE or FIRE" &3a14 49 52 45 0d ; unused &3a18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &3a78 00 00 00 00 00 00 00 00 ; wipe_screen &0880 f0 1e BEQ &08a0 ; wipe_screen_with_black &0882 30 06 BMI &088a ; invert_screen ; wipe_screen_with_pattern &0884 a2 8a LDX #&8a ; TXA &0886 a0 ea LDY #&ea ; NOP &0888 d0 1a BNE &08a4 ; set_wipe_screen_ops ; invert_screen &088a a2 49 LDX #&49 ; EOR &088c a0 ff LDY #&ff ; #&ff &088e 20 a4 08 JSR &08a4 ; set_wipe_screen_ops &0891 a2 00 LDX #&00 ; write_split_bonus_loop &0893 bd 03 0b LDA &0b03,X ; split_bonus_string &0896 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &0899 e8 INX &089a e0 16 CPX #&16 &089c d0 f5 BNE &0893 ; write_split_bonus_loop &089e f0 0a BEQ &08aa ; start_wiping_screen # Always branches ; wipe_screen_with_black &08a0 a2 a9 LDX #&a9 ; LDA &08a2 a0 00 LDY #&00 ; #&00 ; set_wipe_screen_ops &08a4 8e 14 0c STX &0c14 ; wipe_part_of_screen_op &08a7 8c 15 0c STY &0c15 ; wipe_part_of_screen_op + 1 ; start_wiping_screen &08aa a9 f0 LDA #&f0 ; &58f0 = screen_memory + &28f0 &08ac 85 20 STA &20 ; wipe_address_low &08ae a9 58 LDA #&58 &08b0 85 21 STA &21 ; wipe_address_high &08b2 a2 00 LDX #&00 &08b4 86 22 STX &22 ; wipe_length &08b6 20 10 0c JSR &0c10 ; wipe_part_of_screen &08b9 4c 1c 29 JMP &291c ; continue_wiping_screen ; unused &08bc 8c 72 b0 00 ; os_envelope_storage ; envelope_1 # Fuse appearing &08c0 07 06 fa 00 01 01 00 7f 00 00 00 01 01 00 00 00 ; envelope_2 # Fuse moving &08d0 03 2d d3 0f 02 02 02 7f 00 00 00 01 01 00 00 00 ; envelope_3 # Background drone (sound_6) &08e0 7f 01 00 01 01 01 01 7f 00 00 00 14 24 00 00 00 ; envelope_4 # Background drone (sound_7) &08f0 7f 00 ff 00 01 01 01 7f 00 00 00 14 24 00 00 00 ; envelope_5 # Tracer appearing &0900 01 f8 00 00 21 00 00 7f 00 00 fb 7e 7e 00 00 00 ; envelope_6 # Extra life &0910 01 78 88 78 01 01 01 7f 00 00 ff 7e 7e 00 00 00 ; envelope_7 # Death shudder &0920 01 0c b9 fe 0f 01 80 7f 00 00 83 01 01 00 00 00 ; enter_a_name_string &0930 1f 0e 1f ; TAB(&0e, &1f) &0933 45 4e 54 45 52 20 41 20 4e 41 4d 45 0d ; "ENTER A NAME" ; envelope_9 # Sparkler hitting boundary &0940 01 00 00 00 00 00 00 7f 00 00 fd 50 50 00 00 00 ; envelope_10 # Split bonus &0950 01 00 00 00 00 00 00 7f 00 00 ff 7e 7e 00 00 00 ; envelope_11 # Music &0960 01 01 ff 01 01 02 01 0a f6 ff fd 6a 50 00 00 00 ; envelope_12 # Music &0970 01 00 00 00 00 00 00 7f d6 00 ff 6a 3c 00 00 00 ; envelope_13 # Music &0980 01 00 00 00 00 00 00 7f d6 00 81 6a 14 00 00 00 ; envelope_14 # Music &0990 01 00 00 00 00 00 00 0a f6 00 ff 50 3c 00 00 00 ; envelope_15 # Music &09a0 01 00 00 00 00 00 00 32 f6 00 ff 6a 50 00 00 00 ; sound_1 # Split bonus ; chan vol pitch dur &09b0 13 00 0a 00 ff 00 01 00 ; sound_2 # Time bonus ; chan vol pitch dur &09b8 12 00 f8 ff 00 00 01 00 # (pitch is modified) ; sound_3 # Fuse appearing ; chan vol pitch dur &09c0 10 00 f2 ff 07 00 ff 00 ; sound_4 # Fuse appearing ; chan vol pitch dur &09c8 11 00 01 00 90 00 ff 00 ; sound_5 # Fuse moving ; chan vol pitch dur &09d0 11 00 02 00 c8 00 ff 00 ; sound_6 # Background drone ; chan vol pitch dur &09d8 12 01 03 00 00 00 ff 00 ; sound_7 # Background drone ; chan vol pitch dur &09e0 13 01 04 00 01 00 ff 00 ; sound_8 # Tracer appearing ; chan vol pitch dur &09e8 11 00 05 00 ff 00 01 00 ; sound_9 # Extra life ; chan vol pitch dur &09f0 11 00 06 00 78 00 01 00 ; sound_10 # Highlight lines, filling ; chan vol pitch dur &09f8 11 00 f9 ff f0 00 01 00 # (pitch is modified) ; check_for_high_score_screen_keys &0a00 20 50 06 JSR &0650 ; check_for_fire_pressed # Returns carry set if fire pressed &0a03 a6 66 LDX &66 ; last_key_pressed &0a05 a9 00 LDA #&00 # Set to positive to not use joystick &0a07 85 85 STA &85 ; use_joystick &0a09 85 66 STA &66 ; last_key_pressed &0a0b 90 06 BCC &0a13 ; fire_not_pressed &0a0d c6 85 DEC &85 ; use_joystick # Set to negative to use joystick &0a0f a2 02 LDX #&02 # Sample joystick &0a11 d0 06 BNE &0a19 ; set_maximum_channel ; fire_not_pressed &0a13 e0 20 CPX #&20 ; " " &0a15 d0 09 BNE &0a20 ; space_or_fire_not_pressed &0a17 a2 00 LDX #&00 ; no ADC sampling takes place ; set_maximum_channel &0a19 a9 10 LDA #&10 ; Set maximum number of ADC channel &0a1b 20 f4 ff JSR &fff4 ; OSBYTE &0a1e 38 SEC # Leave with carry set to indicate space or fire pressed &0a1f 60 RTS ; space_or_fire_not_pressed &0a20 e0 51 CPX #&51 ; "Q" &0a22 d0 05 BNE &0a29 ; q_not_pressed &0a24 a9 01 LDA #&01 # Set to non-zero to disable sound &0a26 8d 62 02 STA &0262 ; os_sound_suppression ; q_not_pressed &0a29 e0 53 CPX #&53 ; "S" &0a2b d0 05 BNE &0a32 ; s_not_pressed &0a2d a9 00 LDA #&00 # Set to zero to enable sound &0a2f 8d 62 02 STA &0262 ; os_sound_suppression ; s_not_pressed &0a32 e0 4b CPX #&4b ; "K" # actually CPX key_to_change_keys &0a34 d0 6b BNE &0aa1 ; leave_with_carry_clear &0a36 a9 0a LDA #&0a # R10: Cursor start register &0a38 8d 00 fe STA &fe00 ; video register number &0a3b a9 60 LDA #&60 # Enable cursor &0a3d 8d 01 fe STA &fe01 ; video register value &0a40 a0 00 LDY #&00 &0a42 a9 04 LDA #&04 &0a44 85 10 STA &10 ; key_offset ; set_keys_loop &0a46 b9 b0 0a LDA &0ab0,Y ; set_keys_string &0a49 c8 INY &0a4a c9 0d CMP #&0d &0a4c f0 05 BEQ &0a53 ; wait_for_keypress &0a4e 20 ee ff JSR &ffee ; OSWRCH &0a51 d0 f3 BNE &0a46 ; set_keys_loop ; wait_for_keypress &0a53 a5 ec LDA &ec ; os_most_recently_pressed_key &0a55 30 fc BMI &0a53 ; wait_for_keypress ; wait_for_key_release &0a57 a5 ec LDA &ec ; os_most_recently_pressed_key &0a59 10 fc BPL &0a57 ; wait_for_key_release &0a5b c9 f0 CMP #&f0 ; ESCAPE &0a5d f0 21 BEQ &0a80 ; quit_setting_keys &0a5f a6 10 LDX &10 ; key_offset &0a61 95 a0 STA &a0,X ; temporary_keys ; check_if_key_is_already_used_loop &0a63 e8 INX &0a64 e0 05 CPX #&05 &0a66 f0 06 BEQ &0a6e ; accept_key &0a68 d5 a0 CMP &a0,X ; temporary_keys &0a6a f0 e7 BEQ &0a53 ; wait_for_keypress &0a6c d0 f5 BNE &0a63 ; check_if_key_is_already_used_loop # Always branches ; accept_key &0a6e a9 07 LDA #&07 &0a70 20 ee ff JSR &ffee ; OSWRCH &0a73 c6 10 DEC &10 ; key_offset &0a75 10 cf BPL &0a46 ; set_keys_loop &0a77 a2 04 LDX #&04 ; copy_keys_loop &0a79 b5 a0 LDA &a0,X ; temporary_keys &0a7b 95 6b STA &6b,X ; keys &0a7d ca DEX &0a7e 10 f9 BPL &0a79 ; copy_keys_loop ; quit_setting_keys &0a80 a9 15 LDA #&15 ; Flush selected buffer &0a82 a2 00 LDX #&00 ; keyboard &0a84 20 f4 ff JSR &fff4 ; OSBYTE &0a87 a9 0a LDA #&0a # R10: Cursor start register &0a89 8d 00 fe STA &fe00 ; video register number &0a8c a9 20 LDA #&20 # Disable cursor &0a8e 8d 01 fe STA &fe01 ; video register value &0a91 a9 1a LDA #&1a ; restore default windows &0a93 20 ee ff JSR &ffee ; OSWRCH ; write_press_space_fire_tab_or_k_loop &0a96 bd b0 05 LDA &05b0,X ; press_space_fire_tab_or_k_string &0a99 20 ee ff JSR &ffee ; OSWRCH &0a9c e8 INX &0a9d e0 2a CPX #&2a &0a9f d0 f5 BNE &0a96 ; write_press_space_fire_tab_or_k_loop ; leave_with_carry_clear &0aa1 18 CLC # Leave with carry clear to indicate space not pressed &0aa2 60 RTS ; unused &0aa3 00 8d 0c b0 00 ; sound_11 # High score screen music ; chan vol pitch dur &0aa8 00 00 00 00 00 00 00 00 # (all values modified) ; set_keys_string &0ab0 1c 01 1f 26 1f ; define text window x:(&01, &26), y:(&1f, &1f) &0ab5 0c ; CLS &0ab6 53 45 54 20 4b 45 59 53 20 3a 20 44 52 41 57 3f ; "SET KEYS : DRAW?" &0ac6 08 0d &0ac8 2d 44 4f 57 4e 3f 08 0d ; "-DOWN?" &0ad0 2d 4c 45 46 54 3f 08 0d ; "-LEFT?" &0ad8 2d 52 49 47 48 54 3f 08 0d ; "-RIGHT?" &0ae1 2d 55 50 3f 08 0d ; "-UP?" ; set_logical_colour &0ae7 a9 13 LDA #&13 ; define logical colour &0ae9 20 ee ff JSR &ffee ; OSWRCH &0aec 8a TXA &0aed 20 ee ff JSR &ffee ; OSWRCH &0af0 98 TYA &0af1 20 ee ff JSR &ffee ; OSWRCH &0af4 a9 00 LDA #&00 &0af6 20 ee ff JSR &ffee ; OSWRCH &0af9 20 ee ff JSR &ffee ; OSWRCH &0afc 4c ee ff JMP &ffee ; OSWRCH ; channel_envelopes &0aff 00 0b 0c 0d ; split_bonus_string &0b03 1f 08 0f ; TAB(&08, &0f) &0b06 53 50 4c 49 54 2d 42 4f 4e 55 53 3a 31 30 30 30 ; "SPLIT-BONUS:1000" &0b16 10 10 10 10 10 0d ; unused &0b1c 00 8d 10 98 ; sound_12 # Death by sparkler ; chan vol pitch dur &0b20 10 01 f1 ff 03 00 50 00 ; sound_13 # Death by other causes ; chan vol pitch dur &0b28 10 01 f1 ff 07 00 30 00 ; sound_14 # Death shudder ; chan vol pitch dur &0b30 11 01 07 00 96 00 19 00 ; initial_level_variables &0b38 7e ; &90 player_x sprites_x &0b39 fa ; &91 player_y sprites_y &0b3a ff ; &92 fuse_x &0b3b ff ; &93 fuse_y &0b3c 04 ; &94 tracers_x &0b3d 7e ; &95 tracers_y &0b3e fa ; &96 tracers_x + 2 &0b3f 7e ; &97 tracers_y + 2 &0b40 ff ; &98 tracers_x + 4 &0b41 ff ; &99 tracers_y + 4 &0b42 ff ; &9a tracers_x + 6 &0b43 ff ; &9b tracers_y + 6 &0b44 00 ; &9c player_screen_address_low sprites_screen_address_low &0b45 00 ; &9d player_screen_address_high sprites_screen_address_high &0b46 00 ; &9e fuse_screen_address_low &0b47 00 ; &9f fuse_screen_address_high ; colour_0_pixel_values &0b48 00 ; &a0 tracers_screen_address_low &0b49 00 ; &a1 tracers_screen_address_high &0b4a 00 ; &a2 tracers_screen_address_low + 2 &0b4b 00 ; &a3 tracers_screen_address_high + 2 &0b4c 00 ; &a4 tracers_screen_address_low + 4 &0b4d 00 ; &a5 tracers_screen_address_high + 4 &0b4e 00 ; &a6 tracers_screen_address_low + 6 &0b4f 00 ; &a7 tracers_screen_address_high + 6 &0b50 29 ; &a8 player_base_data_offset sprites_base_data_offset &0b51 00 ; &a9 player_direction sprites_direction &0b52 65 ; &aa fuse_base_data_offset &0b53 ff ; &ab fuse_direction &0b54 a1 ; &ac tracers_base_data_offset &0b55 03 ; &ad tracers_direction &0b56 a1 ; &ae tracers_base_data_offset + 2 &0b57 03 ; &af tracers_direction + 2 &0b58 a1 ; &b0 tracers_base_data_offset + 4 &0b59 ff ; &b1 tracers_direction + 4 &0b5a a1 ; &b2 tracers_base_data_offset + 6 &0b5b ff ; &b3 tracers_direction + 6 &0b5c 00 ; &b4 frame_data_offsets frame_data_offsets &0b5d 0f ; &b5 frame_data_offsets + 1 &0b5e 1e ; &b6 frame_data_offsets + 2 &0b5f 2d ; &b7 frame_data_offsets + 3 ; irq2_handler &0b60 a9 20 LDA #&20 &0b62 8d 6d fe STA &fe6d ; User VIA interrupt flag register # Clear User VIA timer 2 timeout interrupt &0b64 a9 ff LDA #&ff &0b67 8d 6f 0b STA &0b6f ; timer_ready # Set to negative to indicate timer event has occurred &0b6a a5 fc LDA &fc ; irq_accumulator &0b6c 40 RTI ; unused &0b6d 8d 14 ; timer_ready &0b6f b8 ; colour_3_pixel_values &0b70 88 44 22 11 ; number_of_shifts_for_pixel_table &0b74 03 02 01 00 ; colour_2_pixel_values &0b78 80 40 20 10 ; colour_1_pixel_values &0b7c 08 04 02 01 ; line_x_directions_table &0b80 01 01 ff ff ; line_y_directions_table &0b84 01 ff 01 ff ; unused &0b88 49 4b 53 ; "IKS" ; pause_game &0b8b a9 00 LDA #&00 &0b8d 8d c3 02 STA &02c3 ; os_event_enable_flags + 4 # Disable v-sync events &0b90 24 64 BIT &64 ; demo_mode &0b92 30 03 BMI &0b97 &0b94 8d c4 02 STA &02c4 ; os_event_enable_flags + 5 # Disable interval timer events &0b97 a9 60 LDA #&60 ; RTS # Don't update sparklers &0b99 8d de 1e STA &1ede ; consider_updating_sparklers &0b9c a2 4f LDX #&4f ; backup_screen_loop &0b9e bd 50 56 LDA &5650,X ; screen_memory + &2650 &0ba1 9d 50 01 STA &0150,X ; backup_of_screen_behind_pause &0ba4 ca DEX &0ba5 10 f7 BPL &0b9e ; backup_screen_loop &0ba7 a2 0f LDX #&0f ; write_pause_loop &0ba9 bd 00 06 LDA &0600,X ; pause_string &0bac 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &0baf ca DEX &0bb0 10 f7 BPL &0ba9 ; write_pause_loop ; wait_for_unpause &0bb2 a5 66 LDA &66 ; last_key_pressed &0bb4 c9 4f CMP #&4f ; "O" &0bb6 f0 1d BEQ &0bd5 ; o_pressed &0bb8 c9 51 CMP #&51 ; "Q" &0bba d0 0e BNE &0bca ; q_not_pressed ; q_pressed &0bbc a2 01 LDX #&01 # Set to non-zero to disable sound &0bbe 8e 62 02 STX &0262 ; os_sound_suppression &0bc1 a9 0f LDA #&0f &0bc3 ca DEX ; 0 &0bc4 86 66 STX &66 ; last_key_pressed &0bc6 24 64 BIT &64 ; demo_mode # Positive if playing game &0bc8 10 05 BPL &0bcf ; skip_scrolltext # Unclear ; q_not_pressed &0bca 20 69 1e JSR &1e69 ; update_scrolltext &0bcd a9 13 LDA #&13 ; Wait for vertical retrace ; skip_scrolltext &0bcf 20 f4 ff JSR &fff4 ; OSBYTE &0bd2 18 CLC &0bd3 90 dd BCC &0bb2 ; wait_for_unpause ; o_pressed &0bd5 a2 07 LDX #&07 ; write_unpause_loop &0bd7 bd 10 06 LDA &0610,X ; unpause_string &0bda 20 ee ff JSR &ffee ; OSWRCH &0bdd ca DEX &0bde 10 f7 BPL &0bd7 ; write_unpause_loop &0be0 a2 4f LDX #&4f ; restore_screen_loop &0be2 bd 50 01 LDA &0150,X ; backup_of_screen_behind_pause &0be5 9d 50 56 STA &5650,X ; screen_memory + &2650 &0be8 ca DEX &0be9 10 f7 BPL &0be2 ; restore_screen_loop &0beb a9 ea LDA #&ea ; NOP # Update sparklers &0bed 8d de 1e STA &1ede ; consider_updating_sparklers &0bf0 a2 ff LDX #&ff # &ff to cause immediate timer event, enable events &0bf2 4c 39 24 JMP &2439 ; set_timer_and_enable_or_disable_events ; unused &0bf5 3d 32 00 8d 1b 38 00 00 07 3e ; character_block &0bff 31 &0c00 30 00 8d 1b c8 00 00 10 ; character_e1_definition &0c08 08 14 22 41 22 14 08 00 ; wipe_part_of_screen &0c10 a0 0f LDY #&0f ; wipe_part_of_screen_loop &0c12 b1 20 LDA (&20),Y ; wipe_address ; wipe_part_of_screen_op &0c14 49 ff EOR #&ff # Invert screen # also LDA #&00 # or wipe screen with black # or TXA; NOP # or fill screen with pattern &0c16 91 20 STA (&20),Y ; wipe_address &0c18 ea NOP &0c19 ea NOP &0c1a 88 DEY &0c1b 10 f5 BPL &0c12 ; wipe_part_of_screen_loop &0c1d 18 CLC &0c1e ca DEX &0c1f 60 RTS ; setup_screen &0c20 a2 30 LDX #&30 ; write_setup_screen_loop &0c22 bd 00 0c LDA &0c00,X ; setup_screen_string - &30 &0c25 20 ee ff JSR &ffee ; OSWRCH &0c28 e8 INX &0c29 e0 b0 CPX #&b0 &0c2b 90 f5 BCC &0c22 ; write_setup_screen_loop &0c2d 60 RTS &0c2e ea NOP &0c2f ea NOP ; setup_screen_string &0c30 16 01 ; MODE 1 ; enable_or_disable_cursor_string &0c32 17 00 0a 20 00 00 00 00 00 00 ; disable cursor &0c3c 12 01 80 ; GCOL 1, 128 (OR with background colour 0) &0c3f 1c 22 1e 27 01 ; define text window x:(&22, &27), y:(&01, &1e) &0c44 5f 5f 5f 5f 5f 5f 0d ; "______" &0c4b 0b 0b 0b 0b 0b ; move up five lines &0c50 5f 5f 5f 5f 5f 5f 0d ; "______" &0c56 0b 0b 0b ; move up three lines &0c5b e1 e1 e1 20 0d ; "*** " &0c60 0b ; move up one line &0c61 4c 49 56 45 53 0d ; "LIVES" &0c67 0b 0b 0b 0b ; move up four lines &0c6b 20 20 31 0d ; " 1" &0c6f 0b ; move up one line &0c70 4c 45 56 45 4c 0d ; "LEVEL" &0c76 0b 0b 0b 0b ; move up four lines &0c7a 20 20 20 20 20 20 0d ; " " &0c81 0b 0b ; move up two lines &0c83 48 49 47 48 0d ; "HIGH" &0c88 0b 0b 0b 0b ; move up four lines &0c8c 20 20 20 20 20 30 0d ; " 0" &0c93 0b 0b ; move up two lines &0c95 53 43 4f 52 45 0d ; "SCORE" &0c9b 0b 0b 0b 0b ; move up four lines &0c9f 20 20 30 20 25 0d ; " 0 %" &0ca5 0b ; move up one line &0ca6 46 49 4c 4c 45 44 0d ; "FILLED" &0cad 0b ; move up one line &0cae 1a ; restore default windows &0caf 07 ; bell ; oswrch_handler &0cb0 c9 41 CMP #&41 ; "A" &0cb2 90 43 BCC &0cf7 ; to_call_previous_oswrch_vector &0cb4 c9 5b CMP #&5b ; "Z" + 1 &0cb6 b0 3f BCS &0cf7 ; to_call_previous_oswrch_vector &0cb8 8d ff 0b STA &0bff ; character_block &0cbb 8a TXA &0cbc 48 PHA &0cbd 98 TYA &0cbe 48 PHA &0cbf a9 0a LDA #&0a ; Read character definition &0cc1 a2 ff LDX #&ff ; &0bff = character_block &0cc3 a0 0b LDY #&0b &0cc5 20 f1 ff JSR &fff1 ; OSWORD &0cc8 4e 00 0c LSR &0c00 ; character_block + 1 # Shift top three lines one pixel to right &0ccb 4e 01 0c LSR &0c01 ; character_block + 2 &0cce 4e 02 0c LSR &0c02 ; character_block + 3 &0cd1 0e 05 0c ASL &0c05 ; character_block + 6 # Shift bottom three lines one pixel to left &0cd4 0e 06 0c ASL &0c06 ; character_block + 7 &0cd7 0e 07 0c ASL &0c07 ; character_block + 8 &0cda a9 17 LDA #&17 # Define character &e0 (uses &0c00 - &0c07) &0cdc 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &0cdf a9 e0 LDA #&e0 &0ce1 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &0ce4 a2 00 LDX #&00 ; define_character_e0_loop &0ce6 bd 00 0c LDA &0c00,X ; character_block + 1 &0ce9 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &0cec e8 INX &0ced e0 08 CPX #&08 &0cef 90 f5 BCC &0ce6 ; define_character_e0_loop &0cf1 68 PLA &0cf2 a8 TAY &0cf3 68 PLA &0cf4 aa TAX &0cf5 a9 e0 LDA #&e0 # Write &e0, i.e. plot italic version of letter ; to_call_previous_oswrch_vector &0cf7 4c d8 03 JMP &03d8 ; call_previous_oswrch_vector ; unused &0cfa 49 00 8d 27 40 00 ; nmi_handler &0d00 40 RTI ; get_demo_movement &0d01 a9 00 LDA #&00 # Positive to unplot sprites &0d03 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &0d06 a5 90 LDA &90 ; player_x &0d08 a4 91 LDY &91 ; player_y &0d0a 20 b2 14 JSR &14b2 ; get_pixel # Get pixel underneath player (not yet set) &0d0d c9 11 CMP #&11 ; COLOUR_3_VALUE &0d0f d0 42 BNE &0d53 ; pixel_under_player_is_not_colour_3 ; player_is_moving_on_or_onto_a_filled_line &0d11 a2 ff LDX #&ff # Set to non-zero to press draw &0d13 86 83 STX &83 ; draw_pressed &0d15 66 fc ROR &fc ; irq_accumulator # Choose whether to draw or not at random &0d17 b0 01 BCS &0d1a ; set_draw &0d19 e8 INX ; 0 # Set to zero to not press draw ; set_draw &0d1a 86 23 STX &23 ; demo_player_draw_pressed &0d1c a6 90 LDX &90 ; player_x &0d1e a4 91 LDY &91 ; player_y &0d20 e4 24 CPX &24 ; demo_player_previous_x &0d22 08 PHP &0d23 c4 25 CPY &25 ; demo_player_previous_y &0d25 08 PHP &0d26 86 24 STX &24 ; demo_player_previous_x &0d28 84 25 STY &25 ; demo_player_previous_y &0d2a 28 PLP &0d2b d0 08 BNE &0d35 ; not_at_previous_position_with_plp &0d2d 28 PLP &0d2e d0 06 BNE &0d36 ; not_at_previous_position ; at_previous_position # If the player was unable to move previously, &0d30 a9 00 LDA #&00 # Set to zero to force change of direction &0d32 85 20 STA &20 ; demo_player_distance_to_travel &0d34 08 PHP ; not_at_previous_position_with_plp &0d35 28 PLP ; not_at_previous_position &0d36 a2 02 LDX #&02 # Demo only uses tracers one and two ; check_tracers_loop &0d38 a5 90 LDA &90 ; player_x &0d3a 55 94 EOR &94,X ; tracers_x &0d3c f0 0b BEQ &0d49 ; player_on_same_line_as_tracer # If the player is horizontally &0d3e 98 TYA &0d3f 55 95 EOR &95,X ; tracers_y &0d41 f0 06 BEQ &0d49 ; player_on_same_line_as_tracer # or vertically level with a tracer, &0d43 ca DEX &0d44 ca DEX &0d45 10 f1 BPL &0d38 ; check_tracers_loop &0d47 30 77 BMI &0dc0 ; consider_continuing_previous_movement # Always branches ; player_on_same_line_as_tracer &0d49 b5 ad LDA &ad,X ; tracers_direction # Then make the player move away from the tracer &0d4b 49 03 EOR #&03 ; up <-> down, left <-> right &0d4d aa TAX &0d4e 20 d7 0d JSR &0dd7 ; set_primary_direction_and_choose_random_secondary_direction &0d51 d0 61 BNE &0db4 ; set_primary_direction_from_secondary # Always branches ; pixel_under_player_is_not_colour_3 &0d53 c9 10 CMP #&10 ; COLOUR_2_VALUE &0d55 d0 23 BNE &0d7a ; pixel_under_player_is_not_colour_2_or_3 ; player_is_trying_to_move_onto_an_unfilled_line &0d57 a9 00 LDA #&00 # Set to zero to ensure move on next frame &0d59 85 23 STA &23 ; demo_player_draw_pressed &0d5b a5 7d LDA &7d ; draw_start_direction &0d5d c5 21 CMP &21 ; demo_player_primary_direction # If not moving in original draw direction, &0d5f f0 0a BEQ &0d6b ; player_is_moving_parallel_to_draw_start_direction &0d61 49 03 EOR #&03 ; up <-> down, left <-> right &0d63 c5 21 CMP &21 ; demo_player_primary_direction # or opposite to original draw direction, &0d65 f0 04 BEQ &0d6b ; player_is_moving_parallel_to_draw_start_direction &0d67 85 21 STA &21 ; demo_player_primary_direction # then use original draw direction for next move &0d69 d0 7b BNE &0de6 ; leave_after_setting_direction_keys # Always branches ; player_is_moving_parallel_to_draw_start_direction &0d6b 20 da 05 JSR &05da ; get_random_velocity &0d6e 29 01 AND #&01 ; up <-> right, left <-> down &0d70 d0 02 BNE &0d74 ; use_one_side ; use_other_side &0d72 a9 02 LDA #&02 ; up <-> left, right <-> down ; use_one_side &0d74 45 7d EOR &7d ; draw_start_direction &0d76 85 21 STA &21 ; demo_player_primary_direction # Otherwise, move to a random side of the line &0d78 10 6c BPL &0de6 ; leave_after_setting_direction_keys # Always branches ; pixel_under_player_is_not_colour_2_or_3 &0d7a aa TAX &0d7b d0 75 BNE &0df2 ; leave # Leave if the player is touching a sparkler (colour 1) ; player_is_moving_into_empty_pixel # Otherwise, the player is moving into an empty pixel &0d7d a5 23 LDA &23 ; demo_player_draw_pressed &0d7f 85 83 STA &83 ; draw_pressed &0d81 a5 21 LDA &21 ; demo_player_primary_direction # Check the next pixel in that direction &0d83 d0 08 BNE &0d8d ; not_moving_up &0d85 a5 90 LDA &90 ; player_x &0d87 a4 91 LDY &91 ; player_y &0d89 88 DEY &0d8a 88 DEY &0d8b d0 20 BNE &0dad ; check_pixel_in_direction # Always branches ; not_moving_up &0d8d c9 01 CMP #&01 ; DIRECTION_RIGHT &0d8f d0 09 BNE &0d9a ; not_moving_right &0d91 a4 90 LDY &90 ; player_x &0d93 c8 INY &0d94 c8 INY &0d95 98 TYA &0d96 a4 91 LDY &91 ; player_y &0d98 d0 13 BNE &0dad ; check_pixel_in_direction # Always branches ; not_moving_right &0d9a c9 02 CMP #&02 ; DIRECTION_LEFT &0d9c d0 09 BNE &0da7 ; not_moving_left &0d9e a4 90 LDY &90 ; player_x &0da0 88 DEY &0da1 88 DEY &0da2 98 TYA &0da3 a4 91 LDY &91 ; player_y &0da5 d0 06 BNE &0dad ; check_pixel_in_direction # Always branches ; not_moving_left &0da7 a5 90 LDA &90 ; player_x &0da9 a4 91 LDY &91 ; player_y &0dab c8 INY &0dac c8 INY ; check_pixel_in_direction &0dad 20 b2 14 JSR &14b2 ; get_pixel &0db0 c9 01 CMP #&01 ; COLOUR_1_VALUE &0db2 d0 0c BNE &0dc0 ; consider_continuing_previous_movement # Branches if not moving into sparkler ; set_primary_direction_from_secondary # Otherwise, use the secondary direction &0db4 a6 22 LDX &22 ; demo_player_secondary_direction &0db6 a5 21 LDA &21 ; demo_player_primary_direction &0db8 49 03 EOR #&03 ; up <-> down, left <-> right &0dba 85 22 STA &22 ; demo_player_secondary_direction # Secondary is opposite of previous primary &0dbc 86 21 STX &21 ; demo_player_primary_direction # Primary is previous secondary &0dbe 10 28 BPL &0de8 ; leave_after_setting_direction_keys_X # Always branches ; consider_continuing_previous_movement &0dc0 c6 20 DEC &20 ; demo_player_distance_to_travel # Continue for the previously chosen distance &0dc2 10 22 BPL &0de6 ; leave_after_setting_direction_keys &0dc4 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &0dc7 29 3f AND #&3f # Choose a random distance to travel &0dc9 85 20 STA &20 ; demo_player_distance_to_travel ; choose_random_direction &0dcb 20 da 05 JSR &05da ; get_random_velocity &0dce 29 03 AND #&03 # Choose a random direction &0dd0 aa TAX &0dd1 49 03 EOR #&03 ; up <-> down, left <-> right &0dd3 c5 21 CMP &21 ; demo_player_primary_direction &0dd5 f0 f4 BEQ &0dcb ; choose_random_direction # that isn't the opposite to the previous direction ; set_primary_direction_and_choose_random_secondary_direction &0dd7 86 21 STX &21 ; demo_player_primary_direction &0dd9 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB # Choose a secondary direction to a random side &0ddc 29 01 AND #&01 ; up <-> right, left <-> down &0dde d0 02 BNE &0de2 ; use_one_secondary ; use_other_secondary &0de0 a9 02 LDA #&02 ; up <-> left, right <-> down ; use_one_secondary &0de2 45 21 EOR &21 ; demo_player_primary_direction &0de4 85 22 STA &22 ; demo_player_secondary_direction ; leave_after_setting_direction_keys &0de6 a6 21 LDX &21 ; demo_player_primary_direction ; leave_after_setting_direction_keys_X &0de8 b5 6b LDA &6b,X ; keys &0dea 85 f2 STA &f2 ; player_primary_direction_key &0dec a6 22 LDX &22 ; demo_player_secondary_direction &0dee b5 6b LDA &6b,X ; keys &0df0 85 f3 STA &f3 ; player_secondary_direction_key ; leave &0df2 60 RTS ; unused &0df3 00 00 00 00 00 ; zero_filled_and_level_tab_string # Written backwards &0df8 11 23 1f ; TAB(&23, &11) &0dfb 30 20 ; " 0" &0dfd 02 23 1f ; TAB(&23, &02) ; update_game &0e00 24 64 BIT &64 ; demo_mode # Negative if demo mode &0e02 10 06 BPL &0e0a ; get_player_movement &0e04 20 01 0d JSR &0d01 ; get_demo_movement &0e07 4c ca 0e JMP &0eca ; update_tracers ; get_player_movement &0e0a 24 85 BIT &85 ; use_joystick # Positive if joystick not used &0e0c 10 60 BPL &0e6e ; get_player_movement_from_keyboard &0e0e a9 80 LDA #&80 ; Read I/O device or buffer status &0e10 a2 00 LDX #&00 ; joystick buttons &0e12 20 d0 03 JSR &03d0 ; call_previous_osbyte_vector &0e15 a0 ff LDY #&ff # Set to non-zero to indicate draw pressed &0e17 8a TXA &0e18 4a LSR A # Carry set if fire pressed &0e19 b0 01 BCS &0e1c ; fire_was_pressed &0e1b c8 INY # Set to zero to indicate draw not pressed ; fire_was_pressed &0e1c 84 83 STY &83 ; draw_pressed ; check_joystick_for_left_and_right &0e1e ad ba 02 LDA &02ba ; os_most_recent_analogue_value &0e21 c9 d3 CMP #&d3 &0e23 90 04 BCC &0e29 ; joystick_not_left &0e25 a4 6d LDY &6d ; key_left &0e27 d0 0a BNE &0e33 ; check_joystick_for_up_and_down # Always branches ; joystick_not_left &0e29 c9 2a CMP #&2a &0e2b b0 04 BCS &0e31 ; joystick_not_left &0e2d a4 6c LDY &6c ; key_right &0e2f d0 02 BNE &0e33 ; check_joystick_for_up_and_down # Always branches ; joystick_not_left &0e31 a0 00 LDY #&00 ; check_joystick_for_up_and_down &0e33 ad bb 02 LDA &02bb ; os_most_recent_analogue_value + 1 &0e36 c9 d3 CMP #&d3 &0e38 90 04 BCC &0e3e ; joystick_not_up &0e3a a6 6b LDX &6b ; key_up &0e3c d0 0a BNE &0e48 ; combine_joystick_directions # Always branches ; joystick_not_up &0e3e c9 2a CMP #&2a &0e40 b0 04 BCS &0e46 ; joystick_not_down &0e42 a6 6e LDX &6e ; key_down &0e44 d0 02 BNE &0e48 ; combine_joystick_directions # Always branches ; joystick_not_down &0e46 a2 00 LDX #&00 ; combine_joystick_directions &0e48 98 TYA &0e49 d0 06 BNE &0e51 ; has_horizontal_movement &0e4b 84 f3 STY &f3 ; player_secondary_direction_key &0e4d 86 f2 STX &f2 ; player_primary_direction_key &0e4f f0 74 BEQ &0ec5 ; unplot_sprites_after_getting_movement # Always branches ; has_horizontal_movement &0e51 8a TXA &0e52 d0 06 BNE &0e5a ; has_vertical_movement &0e54 86 f3 STX &f3 ; player_secondary_direction_key &0e56 84 f2 STY &f2 ; player_primary_direction_key &0e58 f0 6b BEQ &0ec5 ; unplot_sprites_after_getting_movement # Always branches ; has_vertical_movement &0e5a a5 f3 LDA &f3 ; player_secondary_direction_key &0e5c d0 67 BNE &0ec5 ; unplot_sprites_after_getting_movement &0e5e c4 f2 CPY &f2 ; player_primary_direction_key &0e60 d0 06 BNE &0e68 ; prefer_vertical_movement ; prefer_horizontal_movement &0e62 84 f3 STY &f3 ; player_secondary_direction_key &0e64 86 f2 STX &f2 ; player_primary_direction_key &0e66 f0 5d BEQ &0ec5 ; unplot_sprites_after_getting_movement ; prefer_vertical_movement &0e68 86 f3 STX &f3 ; player_secondary_direction_key &0e6a 84 f2 STY &f2 ; player_primary_direction_key &0e6c d0 57 BNE &0ec5 ; unplot_sprites_after_getting_movement # Always branches ; get_player_movement_from_keyboard &0e6e a9 79 LDA #&79 ; Keyboard scan &0e70 a6 6f LDX &6f ; key_draw &0e72 20 d0 03 JSR &03d0 ; call_previous_osbyte_vector # Returns X negative if key pressed &0e75 a0 00 LDY #&00 # Zero to indicate draw not pressed &0e77 8a TXA &0e78 10 01 BPL &0e7b ; set_draw_pressed &0e7a 88 DEY # Negative to indicate draw pressed ; set_draw_pressed &0e7b 84 83 STY &83 ; draw_pressed &0e7d a0 03 LDY #&03 ; check_for_keys_loop &0e7f 84 77 STY &77 ; key_offset &0e81 b6 6b LDX &6b,Y ; keys &0e83 a9 79 LDA #&79 ; Keyboard scan &0e85 20 d0 03 JSR &03d0 ; call_previous_osbyte_vector # Returns X negative if key pressed &0e88 8a TXA &0e89 10 19 BPL &0ea4 ; key_not_pressed &0e8b c5 e3 CMP &e3 ; previous_player_secondary_direction_key &0e8d f0 31 BEQ &0ec0 ; consider_next_key &0e8f c5 f3 CMP &f3 ; player_secondary_direction_key &0e91 f0 2d BEQ &0ec0 ; consider_next_key &0e93 c5 f2 CMP &f2 ; player_primary_direction_key &0e95 f0 29 BEQ &0ec0 ; consider_next_key &0e97 a6 f3 LDX &f3 ; player_secondary_direction_key &0e99 86 e3 STX &e3 ; previous_player_secondary_direction_key &0e9b a6 f2 LDX &f2 ; player_primary_direction_key &0e9d 86 f3 STX &f3 ; player_secondary_direction_key &0e9f 85 f2 STA &f2 ; player_primary_direction_key &0ea1 4c c0 0e JMP &0ec0 ; consider_next_key ; key_not_pressed &0ea4 a6 77 LDX &77 ; key_offset &0ea6 b5 6b LDA &6b,X ; keys &0ea8 c5 e3 CMP &e3 ; previous_player_secondary_direction_key &0eaa f0 10 BEQ &0ebc ; ignore_previous_secondary_direction &0eac c5 f3 CMP &f3 ; player_secondary_direction_key &0eae f0 08 BEQ &0eb8 ; ignore_secondary_direction &0eb0 c5 f2 CMP &f2 ; player_primary_direction_key &0eb2 d0 0c BNE &0ec0 ; consider_next_key &0eb4 a5 f3 LDA &f3 ; player_secondary_direction_key &0eb6 85 f2 STA &f2 ; player_primary_direction_key ; ignore_secondary_direction &0eb8 a5 e3 LDA &e3 ; previous_player_secondary_direction_key &0eba 85 f3 STA &f3 ; player_secondary_direction_key ; ignore_previous_secondary_direction &0ebc a9 00 LDA #&00 &0ebe 85 e3 STA &e3 ; previous_player_secondary_direction_key ; consider_next_key &0ec0 a4 77 LDY &77 ; key_offset &0ec2 88 DEY &0ec3 10 ba BPL &0e7f ; check_for_keys_loop ; unplot_sprites_after_getting_movement &0ec5 a9 00 LDA #&00 # Positive to unplot sprites &0ec7 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites ; update_tracers &0eca a2 04 LDX #&04 ; update_tracers_loop &0ecc 86 74 STX &74 ; sprite_offset &0ece b4 91 LDY &91,X ; sprites_y # &ff if no enemy in slot &0ed0 c0 ff CPY #&ff &0ed2 d0 03 BNE &0ed7 ; update_tracer &0ed4 4c bf 0f JMP &0fbf ; consider_next_tracer ; update_tracer &0ed7 84 73 STY &73 ; tracer_y &0ed9 b5 90 LDA &90,X ; sprites_x &0edb 85 72 STA &72 ; tracer_x &0edd a9 00 LDA #&00 &0edf 85 77 STA &77 ; available_vertical_movements &0ee1 85 7e STA &7e ; available_horizontal_movements &0ee3 b5 a9 LDA &a9,X ; sprites_direction &0ee5 85 7f STA &7f ; tracer_direction &0ee7 c9 03 CMP #&03 ; DIRECTION_DOWN &0ee9 f0 0a BEQ &0ef5 ; skip_checking_down &0eeb a5 72 LDA &72 ; tracer_x &0eed 88 DEY &0eee 20 b2 14 JSR &14b2 ; get_pixel &0ef1 c9 11 CMP #&11 ; COLOUR_3_VALUE &0ef3 26 77 ROL &77 ; available_vertical_movements ; skip_checking_down &0ef5 a5 7f LDA &7f ; tracer_direction &0ef7 c9 02 CMP #&02 ; DIRECTION_LEFT &0ef9 f0 0d BEQ &0f08 ; skip_checking_left &0efb a4 72 LDY &72 ; tracer_x &0efd c8 INY &0efe 98 TYA &0eff a4 73 LDY &73 ; tracer_y &0f01 20 b2 14 JSR &14b2 ; get_pixel &0f04 c9 11 CMP #&11 ; COLOUR_3_VALUE &0f06 26 7e ROL &7e ; available_horizontal_movements ; skip_checking_left &0f08 a5 7f LDA &7f ; tracer_direction &0f0a c9 01 CMP #&01 ; DIRECTION_RIGHT &0f0c f0 0d BEQ &0f1b ; skip_checking_right &0f0e a4 72 LDY &72 ; tracer_x &0f10 88 DEY &0f11 98 TYA &0f12 a4 73 LDY &73 ; tracer_y &0f14 20 b2 14 JSR &14b2 ; get_pixel &0f17 c9 11 CMP #&11 ; COLOUR_3_VALUE &0f19 26 7e ROL &7e ; available_horizontal_movements ; skip_checking_right &0f1b a5 7f LDA &7f ; tracer_direction &0f1d f0 0c BEQ &0f2b ; skip_checking_up &0f1f a5 72 LDA &72 ; tracer_x &0f21 a4 73 LDY &73 ; tracer_y &0f23 c8 INY &0f24 20 b2 14 JSR &14b2 ; get_pixel &0f27 c9 11 CMP #&11 ; COLOUR_3_VALUE &0f29 26 77 ROL &77 ; available_vertical_movements ; skip_checking_up &0f2b a6 74 LDX &74 ; sprite_offset &0f2d a5 80 LDA &80 ; frame_count &0f2f 25 87 AND &87 ; tracer_speed &0f31 f0 03 BEQ &0f36 ; not_slowed &0f33 4c bf 0f JMP &0fbf ; consider_next_tracer ; not_slowed &0f36 a5 7f LDA &7f ; tracer_direction &0f38 10 03 BPL &0f3d ; is_moving &0f3a 4c bf 0f JMP &0fbf ; consider_next_tracer ; is_moving &0f3d f0 43 BEQ &0f82 ; tracer_is_moving_vertically &0f3f c9 03 CMP #&03 ; DIRECTION_DOWN &0f41 f0 3f BEQ &0f82 ; tracer_is_moving_vertically ; tracer_is_moving_horizontally &0f43 a4 77 LDY &77 ; available_vertical_movements &0f45 d0 05 BNE &0f4c ; tracer_could_move_vertically ; keep_tracer_moving_horizontally &0f47 6a ROR A &0f48 90 6f BCC &0fb9 ; move_tracer_left # Carry clear if moving left &0f4a b0 61 BCS &0fad ; move_tracer_right # Carry set if moving right; always branches ; tracer_could_move_vertically &0f4c c0 03 CPY #&03 &0f4e f0 14 BEQ &0f64 ; tracer_could_move_left_or_right &0f50 a5 7e LDA &7e ; available_horizontal_movements &0f52 f0 0a BEQ &0f5e ; set_tracer_moving_vertically &0f54 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &0f57 6a ROR A &0f58 90 04 BCC &0f5e ; set_tracer_moving_vertically &0f5a a5 7f LDA &7f ; tracer_direction &0f5c b0 e9 BCS &0f47 ; keep_tracer_moving_horizontally ; set_tracer_moving_vertically &0f5e 98 TYA &0f5f 6a ROR A &0f60 90 08 BCC &0f6a ; set_tracer_moving_up &0f62 b0 12 BCS &0f76 ; set_tracer_moving_down # Always branches ; tracer_could_move_left_or_right &0f64 a5 73 LDA &73 ; tracer_y &0f66 c5 91 CMP &91 ; player_y &0f68 90 0c BCC &0f76 ; set_tracer_moving_down ; set_tracer_moving_up &0f6a a9 00 LDA #&00 ; DIRECTION_UP &0f6c 95 a9 STA &a9,X ; sprites_direction ; move_tracer_up &0f6e a4 73 LDY &73 ; tracer_y &0f70 88 DEY &0f71 88 DEY &0f72 94 91 STY &91,X ; sprites_y &0f74 d0 49 BNE &0fbf ; consider_next_tracer # Always branches ; set_tracer_moving_down &0f76 a9 03 LDA #&03 ; DIRECTION_DOWN &0f78 95 a9 STA &a9,X ; sprites_direction ; move_tracer_down &0f7a a4 73 LDY &73 ; tracer_y &0f7c c8 INY &0f7d c8 INY &0f7e 94 91 STY &91,X ; sprites_y &0f80 d0 3d BNE &0fbf ; consider_next_tracer # Always branches ; tracer_is_moving_vertically &0f82 a4 7e LDY &7e ; available_horizontal_movements &0f84 d0 05 BNE &0f8b ; tracer_could_move_horizontally ; keep_tracer_moving_vertically &0f86 6a ROR A &0f87 90 e5 BCC &0f6e ; move_tracer_up # Carry clear if moving up &0f89 b0 ef BCS &0f7a ; move_tracer_down # Carry set if moving down ; tracer_could_move_horizontally &0f8b c0 03 CPY #&03 &0f8d f0 14 BEQ &0fa3 ; tracer_could_move_left_or_right &0f8f a5 77 LDA &77 ; available_vertical_movements &0f91 f0 0a BEQ &0f9d ; set_tracer_moving_horizontally &0f93 ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &0f96 6a ROR A &0f97 b0 04 BCS &0f9d ; set_tracer_moving_horizontally &0f99 a5 7f LDA &7f ; tracer_direction &0f9b 90 e9 BCC &0f86 ; keep_tracer_moving_vertically ; set_tracer_moving_horizontally &0f9d 98 TYA &0f9e 6a ROR A &0f9f 90 08 BCC &0fa9 ; set_tracer_moving_right &0fa1 b0 12 BCS &0fb5 ; set_tracer_moving_left ; tracer_could_move_left_or_right &0fa3 a5 72 LDA &72 ; tracer_x &0fa5 c5 90 CMP &90 ; player_x &0fa7 b0 0c BCS &0fb5 ; set_tracer_moving_left ; set_tracer_moving_right &0fa9 a9 01 LDA #&01 ; DIRECTION_RIGHT &0fab 95 a9 STA &a9,X ; sprites_direction ; move_tracer_right &0fad a4 72 LDY &72 ; tracer_x &0faf c8 INY &0fb0 c8 INY &0fb1 94 90 STY &90,X ; sprites_x &0fb3 d0 0a BNE &0fbf ; consider_next_tracer # Always branches ; set_tracer_moving_left &0fb5 a9 02 LDA #&02 ; DIRECTION_LEFT &0fb7 95 a9 STA &a9,X ; sprites_direction ; move_tracer_left &0fb9 a4 72 LDY &72 ; tracer_x &0fbb 88 DEY &0fbc 88 DEY &0fbd 94 90 STY &90,X ; sprites_x ; consider_next_tracer &0fbf e8 INX &0fc0 e8 INX &0fc1 e0 0c CPX #&0c &0fc3 f0 03 BEQ &0fc8 ; update_fuse &0fc5 4c cc 0e JMP &0ecc ; update_tracers_loop ; update_fuse &0fc8 24 60 BIT &60 ; fuse_state # Negative if fuse is moving &0fca 30 03 BMI &0fcf ; update_active_fuse &0fcc 4c 57 10 JMP &1057 ; update_player ; update_active_fuse &0fcf a9 02 LDA #&02 &0fd1 85 40 STA &40 ; fuse_steps ; update_fuse_loop &0fd3 a5 ab LDA &ab ; fuse_direction &0fd5 c9 03 CMP #&03 ; DIRECTION_DOWN &0fd7 f0 18 BEQ &0ff1 ; fuse_can't_move_up &0fd9 a5 92 LDA &92 ; fuse_x &0fdb a4 93 LDY &93 ; fuse_y &0fdd 88 DEY &0fde 20 b2 14 JSR &14b2 ; get_pixel &0fe1 c9 10 CMP #&10 ; COLOUR_2_VALUE &0fe3 d0 0c BNE &0ff1 ; fuse_can't_move_up ; move_fuse_up &0fe5 a5 93 LDA &93 ; fuse_y &0fe7 e9 02 SBC #&02 &0fe9 85 93 STA &93 ; fuse_y &0feb a9 00 LDA #&00 ; DIRECTION_UP &0fed 85 ab STA &ab ; fuse_direction &0fef f0 5f BEQ &1050 ; consider_next_fuse_step # Always branches ; fuse_can't_move_up &0ff1 a5 ab LDA &ab ; fuse_direction &0ff3 c9 02 CMP #&02 ; DIRECTION_LEFT &0ff5 f0 19 BEQ &1010 ; fuse_can't_move_right &0ff7 a4 92 LDY &92 ; fuse_x &0ff9 c8 INY &0ffa 98 TYA &0ffb a4 93 LDY &93 ; fuse_y &0ffd 20 b2 14 JSR &14b2 ; get_pixel &1000 c9 10 CMP #&10 ; COLOUR_2_VALUE &1002 d0 0c BNE &1010 ; fuse_can't_move_right ; move_fuse_right &1004 a5 92 LDA &92 ; fuse_x &1006 69 01 ADC #&01 &1008 85 92 STA &92 ; fuse_x &100a a9 01 LDA #&01 ; DIRECTION_RIGHT &100c 85 ab STA &ab ; fuse_direction &100e d0 40 BNE &1050 ; consider_next_fuse_step # Always branches ; fuse_can't_move_right &1010 a5 ab LDA &ab ; fuse_direction &1012 c9 01 CMP #&01 ; DIRECTION_RIGHT &1014 f0 19 BEQ &102f ; fuse_can't_move_left &1016 a4 92 LDY &92 ; fuse_x &1018 88 DEY &1019 98 TYA &101a a4 93 LDY &93 ; fuse_y &101c 20 b2 14 JSR &14b2 ; get_pixel &101f c9 10 CMP #&10 ; COLOUR_2_VALUE &1021 d0 0c BNE &102f ; fuse_can't_move_left ; move_fuse_left &1023 a5 92 LDA &92 ; fuse_x &1025 e9 02 SBC #&02 &1027 85 92 STA &92 ; fuse_x &1029 a9 02 LDA #&02 ; DIRECTION_LEFT &102b 85 ab STA &ab ; fuse_direction &102d d0 21 BNE &1050 ; consider_next_fuse_step # Always branches ; fuse_can't_move_left &102f a5 ab LDA &ab ; fuse_direction &1031 f0 19 BEQ &104c ; fuse_can't_move_down &1033 a5 92 LDA &92 ; fuse_x &1035 a4 93 LDY &93 ; fuse_y &1037 c8 INY &1038 20 b2 14 JSR &14b2 ; get_pixel &103b c9 10 CMP #&10 ; COLOUR_2_VALUE &103d d0 0d BNE &104c ; fuse_can't_move_down ; move_fuse_down &103f a5 93 LDA &93 ; fuse_y &1041 18 CLC &1042 69 02 ADC #&02 &1044 85 93 STA &93 ; fuse_y &1046 a9 03 LDA #&03 ; DIRECTION_DOWN &1048 85 ab STA &ab ; fuse_direction &104a d0 04 BNE &1050 ; consider_next_fuse_step # Always branches ; fuse_can't_move_down &104c a9 ff LDA #&ff ; PLAYER_KILLED &104e 85 86 STA &86 ; game_state ; consider_next_fuse_step &1050 c6 40 DEC &40 ; fuse_steps &1052 f0 03 BEQ &1057 ; update_player &1054 4c d3 0f JMP &0fd3 ; update_fuse_loop ; update_player &1057 a5 84 LDA &84 ; player_is_drawing # Zero if player is not drawing &1059 f0 03 BEQ &105e ; update_player_when_not_drawing &105b 4c b1 11 JMP &11b1 ; update_player_when_drawing ; update_player_when_not_drawing &105e 85 77 STA &77 ; primary_or_secondary_direction # Set to zero to indicate primary direction &1060 a6 83 LDX &83 ; draw_pressed # Non-zero if draw was pressed &1062 d0 76 BNE &10da ; consider_starting_new_line &1064 a5 f2 LDA &f2 ; player_primary_direction_key ; check_direction &1066 c5 6b CMP &6b ; key_up &1068 d0 15 BNE &107f ; player_not_moving_up ; player_moving_up &106a a5 90 LDA &90 ; player_x &106c a4 91 LDY &91 ; player_y &106e 88 DEY &106f 20 b2 14 JSR &14b2 ; get_pixel &1072 c9 11 CMP #&11 ; COLOUR_3_VALUE &1074 d0 54 BNE &10ca ; consider_next_direction ; move_player_up &1076 a5 91 LDA &91 ; player_y &1078 e9 02 SBC #&02 &107a 85 91 STA &91 ; player_y &107c 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_moving_up &107f c5 6c CMP &6c ; key_right &1081 d0 16 BNE &1099 ; player_not_moving_right ; player_moving_right &1083 a4 90 LDY &90 ; player_x &1085 c8 INY &1086 98 TYA &1087 a4 91 LDY &91 ; player_y &1089 20 b2 14 JSR &14b2 ; get_pixel &108c c9 11 CMP #&11 ; COLOUR_3_VALUE &108e d0 3a BNE &10ca ; consider_next_direction ; move_player_right &1090 a5 90 LDA &90 ; player_x &1092 69 01 ADC #&01 &1094 85 90 STA &90 ; player_x &1096 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_moving_right &1099 c5 6d CMP &6d ; key_left &109b d0 15 BNE &10b2 ; player_not_moving_left ; player_moving_left &109d a4 90 LDY &90 ; player_x &109f 88 DEY &10a0 98 TYA &10a1 a4 91 LDY &91 ; player_y &10a3 20 b2 14 JSR &14b2 ; get_pixel &10a6 c9 11 CMP #&11 ; COLOUR_3_VALUE &10a8 d0 20 BNE &10ca ; consider_next_direction ; move_player_left &10aa a5 90 LDA &90 ; player_x &10ac e9 02 SBC #&02 &10ae 85 90 STA &90 ; player_x &10b0 d0 25 BNE &10d7 ; to_check_for_enemies_touching_player # Always branches ; player_not_moving_left &10b2 c5 6e CMP &6e ; key_down &10b4 d0 14 BNE &10ca ; consider_next_direction ; player_moving_down &10b6 a5 90 LDA &90 ; player_x &10b8 a4 91 LDY &91 ; player_y &10ba c8 INY &10bb 20 b2 14 JSR &14b2 ; get_pixel &10be c9 11 CMP #&11 ; COLOUR_3_VALUE &10c0 d0 08 BNE &10ca ; consider_next_direction ; move_player_down &10c2 a5 91 LDA &91 ; player_y &10c4 69 01 ADC #&01 &10c6 85 91 STA &91 ; player_y &10c8 d0 0d BNE &10d7 ; to_check_for_enemies_touching_player # Always branches ; consider_next_direction &10ca a5 77 LDA &77 ; primary_or_secondary_direction # Negative if secondary direction has been checked &10cc 30 09 BMI &10d7 ; to_check_for_enemies_touching_player ; consider_secondary_direction &10ce a5 f3 LDA &f3 ; player_secondary_direction_key &10d0 f0 05 BEQ &10d7 ; to_check_for_enemies_touching_player &10d2 c6 77 DEC &77 ; primary_or_secondary_direction # Set to negative to indicate secondary direction &10d4 4c 66 10 JMP &1066 ; check_direction ; to_check_for_enemies_touching_player &10d7 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; consider_starting_new_line &10da a5 f2 LDA &f2 ; player_primary_direction_key &10dc f0 f9 BEQ &10d7 ; to_check_for_enemies_touching_player &10de c5 6b CMP &6b ; key_up &10e0 d0 2b BNE &110d ; player_not_starting_to_draw_up ; player_starting_to_draw_up &10e2 a5 90 LDA &90 ; player_x &10e4 a4 91 LDY &91 ; player_y &10e6 88 DEY &10e7 20 b2 14 JSR &14b2 ; get_pixel &10ea a8 TAY &10eb d0 19 BNE &1106 ; player_starting_to_draw_up_into_line &10ed a4 91 LDY &91 ; player_y &10ef c0 04 CPY #&04 &10f1 f0 e4 BEQ &10d7 ; to_check_for_enemies_touching_player &10f3 84 7c STY &7c ; path_start_y &10f5 88 DEY &10f6 88 DEY &10f7 84 91 STY &91 ; player_y &10f9 c8 INY &10fa a5 90 LDA &90 ; player_x &10fc 85 7b STA &7b ; path_start_x &10fe 20 e8 14 JSR &14e8 ; set_pixel &1101 a9 00 LDA #&00 ; DIRECTION_UP &1103 4c 9d 11 JMP &119d ; start_drawing ; player_starting_to_draw_up_into_line &1106 c9 11 CMP #&11 ; COLOUR_3_VALUE &1108 d0 c4 BNE &10ce ; consider_secondary_direction &110a 4c 76 10 JMP &1076 ; move_player_up ; player_not_starting_to_draw_up &110d c5 6c CMP &6c ; key_right &110f d0 2d BNE &113e ; player_not_starting_to_draw_right &1111 a4 90 LDY &90 ; player_x &1113 c8 INY &1114 98 TYA &1115 a4 91 LDY &91 ; player_y &1117 20 b2 14 JSR &14b2 ; get_pixel &111a a8 TAY &111b d0 1a BNE &1137 ; player_starting_to_draw_right_into_line &111d a4 90 LDY &90 ; player_x &111f c0 fa CPY #&fa &1121 f0 b4 BEQ &10d7 ; to_check_for_enemies_touching_player &1123 84 7b STY &7b ; path_start_x &1125 c8 INY &1126 c8 INY &1127 84 90 STY &90 ; player_x &1129 88 DEY &112a 98 TYA &112b a4 91 LDY &91 ; player_y &112d 84 7c STY &7c ; path_start_y &112f 20 e8 14 JSR &14e8 ; set_pixel &1132 a9 01 LDA #&01 ; DIRECTION_RIGHT &1134 4c 9d 11 JMP &119d ; start_drawing ; player_starting_to_draw_right_into_line &1137 c9 11 CMP #&11 ; COLOUR_3_VALUE &1139 d0 93 BNE &10ce ; consider_secondary_direction &113b 4c 90 10 JMP &1090 ; move_player_right ; player_not_starting_to_draw_right &113e c5 6d CMP &6d ; key_left &1140 d0 2c BNE &116e ; player_not_starting_to_draw_left &1142 a4 90 LDY &90 ; player_x &1144 88 DEY &1145 98 TYA &1146 a4 91 LDY &91 ; player_y &1148 20 b2 14 JSR &14b2 ; get_pixel &114b a8 TAY &114c d0 19 BNE &1167 ; player_starting_to_draw_left_into_line &114e a4 90 LDY &90 ; player_x &1150 c0 04 CPY #&04 &1152 f0 57 BEQ &11ab ; to_check_for_enemies_touching_player &1154 84 7b STY &7b ; path_start_x &1156 88 DEY &1157 88 DEY &1158 84 90 STY &90 ; player_x &115a c8 INY &115b 98 TYA &115c a4 91 LDY &91 ; player_y &115e 84 7c STY &7c ; path_start_y &1160 20 e8 14 JSR &14e8 ; set_pixel &1163 a9 02 LDA #&02 ; DIRECTION_LEFT &1165 d0 36 BNE &119d ; start_drawing # Always branches ; player_starting_to_draw_left_into_line &1167 c9 11 CMP #&11 ; COLOUR_3_VALUE &1169 d0 43 BNE &11ae ; to_consider_secondary_direction &116b 4c aa 10 JMP &10aa ; move_player_left ; player_not_starting_to_draw_left &116e c5 6e CMP &6e ; key_down &1170 d0 39 BNE &11ab ; to_check_for_enemies_touching_player &1172 a5 90 LDA &90 ; player_x &1174 a4 91 LDY &91 ; player_y &1176 c8 INY &1177 20 b2 14 JSR &14b2 ; get_pixel &117a a8 TAY &117b d0 19 BNE &1196 ; player_starting_to_draw_down_into_line &117d a4 91 LDY &91 ; player_y &117f c0 fa CPY #&fa &1181 f0 28 BEQ &11ab ; to_check_for_enemies_touching_player &1183 84 7c STY &7c ; path_start_y &1185 c8 INY &1186 c8 INY &1187 84 91 STY &91 ; player_y &1189 88 DEY &118a a5 90 LDA &90 ; player_x &118c 85 7b STA &7b ; path_start_x &118e 20 e8 14 JSR &14e8 ; set_pixel &1191 a9 03 LDA #&03 ; DIRECTION_DOWN &1193 4c 9d 11 JMP &119d ; start_drawing ; player_starting_to_draw_down_into_line &1196 c9 11 CMP #&11 ; COLOUR_3_VALUE &1198 d0 14 BNE &11ae ; to_consider_secondary_direction &119a 4c c2 10 JMP &10c2 ; move_player_down ; start_drawing &119d 85 7d STA &7d ; draw_start_direction &119f 85 a9 STA &a9 ; player_direction &11a1 a9 ff LDA #&ff &11a3 85 84 STA &84 ; player_is_drawing # Set to negative to indicate player is drawing &11a5 85 63 STA &63 ; slow_fill # Set to negative to indicate slow fill &11a7 a9 0b LDA #&0b # Reset time before fuse appears &11a9 85 79 STA &79 ; fuse_timer ; to_check_for_enemies_touching_player &11ab 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; to_consider_secondary_direction &11ae 4c ce 10 JMP &10ce ; consider_secondary_direction ; update_player_when_drawing &11b1 a5 90 LDA &90 ; player_x &11b3 a4 91 LDY &91 ; player_y &11b5 20 b2 14 JSR &14b2 ; get_pixel &11b8 c9 11 CMP #&11 ; COLOUR_3_VALUE &11ba d0 03 BNE &11bf ; not_enclosing_area &11bc 4c a1 15 JMP &15a1 ; check_if_area_can_be_filled ; not_enclosing_area &11bf c9 01 CMP #&01 ; COLOUR_1_VALUE &11c1 d0 04 BNE &11c7 ; not_sparkler &11c3 a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &11c5 85 86 STA &86 ; game_state ; not_sparkler &11c7 c9 10 CMP #&10 ; COLOUR_2_VALUE &11c9 d0 48 BNE &1213 ; consider_drawing &11cb a5 60 LDA &60 ; fuse_state # Zero if no fuse &11cd f0 03 BEQ &11d2 ; to_consider_starting_fuse &11cf 20 17 15 JSR &1517 ; move_player_backwards_and_set_pixel_without_enemies_check ; to_consider_starting_fuse &11d2 4c d8 12 JMP &12d8 ; consider_starting_fuse ; move_player_backwards_and_set_pixel # Only called via &1517; never checks enemies afterwards &11d5 a5 a9 LDA &a9 ; player_direction &11d7 d0 0c BNE &11e5 ; not_moving_up &11d9 a5 90 LDA &90 ; player_x &11db a4 91 LDY &91 ; player_y &11dd c8 INY &11de c8 INY &11df 20 e8 14 JSR &14e8 ; set_pixel &11e2 4c be 12 JMP &12be ; move_player_down_and_draw ; not_moving_up &11e5 c9 01 CMP #&01 ; DIRECTION_RIGHT &11e7 d0 0d BNE &11f6 ; not_moving_right &11e9 a4 90 LDY &90 ; player_x &11eb 88 DEY &11ec 88 DEY &11ed 98 TYA &11ee a4 91 LDY &91 ; player_y &11f0 20 e8 14 JSR &14e8 ; set_pixel &11f3 4c 97 12 JMP &1297 ; move_player_left_and_draw ; not_moving_right &11f6 c9 02 CMP #&02 ; DIRECTION_LEFT &11f8 d0 0d BNE &1207 ; not_moving_left &11fa a4 90 LDY &90 ; player_x &11fc c8 INY &11fd c8 INY &11fe 98 TYA &11ff a4 91 LDY &91 ; player_y &1201 20 e8 14 JSR &14e8 ; set_pixel &1204 4c 6f 12 JMP &126f ; move_player_right_and_draw ; not_moving_left &1207 a5 90 LDA &90 ; player_x &1209 a4 91 LDY &91 ; player_y &120b 88 DEY &120c 88 DEY &120d 20 e8 14 JSR &14e8 ; set_pixel &1210 4c 48 12 JMP &1248 ; move_player_up_and_draw ; consider_drawing &1213 a5 83 LDA &83 ; draw_pressed &1215 25 63 AND &63 ; slow_fill &1217 f0 08 BEQ &1221 ; player_drawing_fast &1219 a5 80 LDA &80 ; frame_count &121b 6a ROR A &121c b0 05 BCS &1223 ; player_drawing &121e 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_drawing_fast &1221 85 63 STA &63 ; slow_fill ; player_drawing &1223 a5 f2 LDA &f2 ; player_primary_direction_key &1225 d0 03 BNE &122a ; player_drawing_in_direction &1227 4c d8 12 JMP &12d8 ; consider_starting_fuse ; player_drawing_in_direction &122a 85 77 STA &77 ; draw_direction &122c a5 90 LDA &90 ; player_x &122e a4 91 LDY &91 ; player_y &1230 20 e8 14 JSR &14e8 ; set_pixel # Set pixel for player's previous position &1233 a5 77 LDA &77 ; draw_direction &1235 c5 6b CMP &6b ; key_up &1237 d0 22 BNE &125b ; player_not_drawing_up ; player_drawing_up &1239 a5 90 LDA &90 ; player_x &123b a4 91 LDY &91 ; player_y &123d 88 DEY &123e 20 b2 14 JSR &14b2 ; get_pixel &1241 4a LSR A &1242 90 04 BCC &1248 ; move_player_up_and_draw &1244 a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &1246 85 86 STA &86 ; game_state ; move_player_up_and_draw &1248 a4 91 LDY &91 ; player_y &124a 88 DEY &124b 88 DEY &124c 84 91 STY &91 ; player_y &124e c8 INY &124f a5 90 LDA &90 ; player_x &1251 20 e8 14 JSR &14e8 ; set_pixel # Set pixel below player's new position &1254 a9 00 LDA #&00 &1256 85 a9 STA &a9 ; player_direction &1258 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_drawing_up &125b c5 6c CMP &6c ; key_right &125d d0 24 BNE &1283 ; player_not_drawing_right ; player_drawing_right &125f a4 90 LDY &90 ; player_x &1261 c8 INY &1262 98 TYA &1263 a4 91 LDY &91 ; player_y &1265 20 b2 14 JSR &14b2 ; get_pixel &1268 4a LSR A &1269 90 04 BCC &126f ; move_player_right_and_draw &126b a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &126d 85 86 STA &86 ; game_state ; move_player_right_and_draw &126f a4 90 LDY &90 ; player_x &1271 c8 INY &1272 c8 INY &1273 84 90 STY &90 ; player_x &1275 88 DEY &1276 98 TYA &1277 a4 91 LDY &91 ; player_y &1279 20 e8 14 JSR &14e8 ; set_pixel # Set pixel left of player's new position &127c a9 01 LDA #&01 ; DIRECTION_RIGHT &127e 85 a9 STA &a9 ; player_direction &1280 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_drawing_right &1283 c5 6d CMP &6d ; key_left &1285 d0 24 BNE &12ab ; player_not_drawing_left ; player_drawing_left &1287 a4 90 LDY &90 ; player_x &1289 88 DEY &128a 98 TYA &128b a4 91 LDY &91 ; player_y &128d 20 b2 14 JSR &14b2 ; get_pixel &1290 4a LSR A &1291 90 04 BCC &1297 ; move_player_left_and_draw &1293 a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &1295 85 86 STA &86 ; game_state ; move_player_left_and_draw &1297 a4 90 LDY &90 ; player_x &1299 88 DEY &129a 88 DEY &129b 84 90 STY &90 ; player_x &129d c8 INY &129e 98 TYA &129f a4 91 LDY &91 ; player_y &12a1 20 e8 14 JSR &14e8 ; set_pixel # Set pixel right of player's new position &12a4 a9 02 LDA #&02 ; DIRECTION_LEFT &12a6 85 a9 STA &a9 ; player_direction &12a8 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_drawing_left &12ab c5 6e CMP &6e ; key_down &12ad d0 22 BNE &12d1 ; player_not_drawing_down ; player_drawing_down &12af a5 90 LDA &90 ; player_x &12b1 a4 91 LDY &91 ; player_y &12b3 c8 INY &12b4 20 b2 14 JSR &14b2 ; get_pixel &12b7 4a LSR A &12b8 90 04 BCC &12be ; move_player_down_and_draw &12ba a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &12bc 85 86 STA &86 ; game_state ; move_player_down_and_draw &12be a4 91 LDY &91 ; player_y &12c0 c8 INY &12c1 c8 INY &12c2 84 91 STY &91 ; player_y &12c4 a5 90 LDA &90 ; player_x &12c6 88 DEY &12c7 20 e8 14 JSR &14e8 ; set_pixel # Set pixel above player's new position &12ca a9 03 LDA #&03 ; DIRECTION_DOWN &12cc 85 a9 STA &a9 ; player_direction &12ce 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; player_not_drawing_down &12d1 a5 90 LDA &90 ; player_x &12d3 a4 91 LDY &91 ; player_y &12d5 20 e8 14 JSR &14e8 ; set_pixel ; consider_starting_fuse &12d8 24 60 BIT &60 ; fuse_state # Negative if fuse is moving &12da 30 3a BMI &1316 ; check_for_enemies_touching_player &12dc a6 79 LDX &79 ; fuse_timer &12de ca DEX &12df 86 79 STX &79 ; fuse_timer &12e1 f0 22 BEQ &1305 ; start_fuse_moving &12e3 e0 08 CPX #&08 # Fuse appears after three frames of inactivity &12e5 d0 2f BNE &1316 ; check_for_enemies_touching_player ; make_fuse_appear &12e7 a9 07 LDA #&07 ; Generate a sound (SOUND) &12e9 a2 c0 LDX #&c0 ; &09c0 = sound_3 &12eb a0 09 LDY #&09 &12ed 20 f1 ff JSR &fff1 ; OSWORD # Play sound for fuse appearing (not demo) &12f0 a2 c8 LDX #&c8 ; &09c8 = sound_4 &12f2 a0 09 LDY #&09 &12f4 20 f1 ff JSR &fff1 ; OSWORD # Play sound for fuse appearing (not demo) &12f7 a5 7b LDA &7b ; path_start_x &12f9 85 92 STA &92 ; fuse_x &12fb a5 7c LDA &7c ; path_start_y &12fd 85 93 STA &93 ; fuse_y &12ff a9 01 LDA #&01 # Set to one to indicate fuse is present, but not moving &1301 85 60 STA &60 ; fuse_state &1303 d0 11 BNE &1316 ; check_for_enemies_touching_player # Always branches ; start_fuse_moving &1305 a9 ff LDA #&ff # Set to negative to set fuse moving &1307 85 60 STA &60 ; fuse_state &1309 a5 7d LDA &7d ; draw_start_direction &130b 85 ab STA &ab ; fuse_direction &130d a9 07 LDA #&07 ; Generate a sound (SOUND) &130f a2 d0 LDX #&d0 ; &09d0 = sound_5 &1311 a0 09 LDY #&09 &1313 20 f1 ff JSR &fff1 ; OSWORD # Play sound for fuse moving (not demo) ; check_for_enemies_touching_player &1316 a2 0a LDX #&0a # also RTS # Leave if moving player backwards without checking ; check_for_enemies_touching_player_loop &1318 86 74 STX &74 ; enemy_offset &131a b4 91 LDY &91,X ; sprites_y # &ff if no enemy in slot &131c c0 ff CPY #&ff &131e f0 7f BEQ &139f ; consider_next_enemy ; check_for_enemy_touching_player &1320 b5 90 LDA &90,X ; sprites_x &1322 c5 90 CMP &90 ; player_x &1324 d0 1d BNE &1343 ; enemy_isn't_horizontal_with_player ; enemy_is_horizontal_with_player # If the enemy is horizontally aligned with the player, &1326 98 TYA &1327 38 SEC &1328 e5 91 SBC &91 ; player_y &132a b0 04 BCS &1330 ; skip_inversion_y &132c 49 ff EOR #&ff &132e 69 01 ADC #&01 ; skip_inversion_y &1330 c9 03 CMP #&03 # Is the enemy within two pixels vertically? &1332 b0 69 BCS &139d ; consider_next_enemy_from_offset &1334 a5 91 LDA &91 ; player_y &1336 d5 91 CMP &91,X ; sprites_y &1338 90 02 BCC &133c ; enemy_is_below_player ; enemy_is_above_player &133a e9 03 SBC #&03 ; enemy_is_below_player &133c 69 01 ADC #&01 &133e a8 TAY &133f a5 90 LDA &90 ; player_x &1341 d0 1d BNE &1360 ; check_if_pixel_is_on_line # Always branches ; enemy_isn't_horizontal_with_player &1343 c4 91 CPY &91 ; player_y &1345 d0 56 BNE &139d ; consider_next_enemy_from_offset ; enemy_is_vertical_with_player # If the enemy is vertically aligned with the player, &1347 38 SEC &1348 e5 90 SBC &90 ; player_x &134a b0 04 BCS &1350 ; skip_inversion_x &134c 49 ff EOR #&ff &134e 69 01 ADC #&01 ; skip_inversion_x &1350 c9 03 CMP #&03 # Is the enemy within two pixels horizontally? &1352 b0 49 BCS &139d ; consider_next_enemy_from_offset &1354 a5 90 LDA &90 ; player_x &1356 d5 90 CMP &90,X ; sprites_x &1358 90 02 BCC &135c ; enemy_is_right_of_player ; enemy_is_left_of_player &135a e9 03 SBC #&03 ; enemy_is_right_of_player &135c 69 01 ADC #&01 &135e a4 91 LDY &91 ; player_y ; check_if_pixel_is_on_line # Check if there is a line joining enemy to player &1360 20 b2 14 JSR &14b2 ; get_pixel &1363 c9 10 CMP #&10 ; COLOUR_2_VALUE &1365 90 36 BCC &139d ; consider_next_enemy_from_offset # Branches if pixel isn't on filled or unfilled line &1367 24 86 BIT &86 ; game_state # Negative if player is already dead &1369 30 32 BMI &139d ; consider_next_enemy_from_offset &136b a9 ff LDA #&ff ; PLAYER_KILLED &136d 85 86 STA &86 ; game_state &136f a5 74 LDA &74 ; enemy_offset &1371 c9 02 CMP #&02 ; ENEMY_FUSE &1373 f0 08 BEQ &137d ; consider_fuse_state_for_killing_player &1375 24 84 BIT &84 ; player_is_drawing # Positive if player is not drawing &1377 10 24 BPL &139d ; consider_next_enemy_from_offset ; prevent_player_dying &1379 e6 86 INC &86 ; game_state # Tracers can't kill player on unfilled lines &137b f0 20 BEQ &139d ; consider_next_enemy_from_offset # Always branches ; consider_fuse_state_for_killing_player &137d 24 60 BIT &60 ; fuse_state # Positive if fuse is not moving &137f 10 f8 BPL &1379 ; prevent_player_dying # Fuse can't kill player if not active &1381 a5 90 LDA &90 ; player_x &1383 a4 91 LDY &91 ; player_y &1385 20 b2 14 JSR &14b2 ; get_pixel &1388 c9 10 CMP #&10 ; COLOUR_2_VALUE &138a d0 11 BNE &139d ; consider_next_enemy_from_offset &138c a5 a9 LDA &a9 ; player_direction &138e c5 ab CMP &ab ; fuse_direction &1390 08 PHP &1391 e6 86 INC &86 ; game_state &1393 20 17 15 JSR &1517 ; move_player_backwards_and_set_pixel_without_enemies_check &1396 28 PLP &1397 d0 04 BNE &139d ; consider_next_enemy_from_offset &1399 a6 74 LDX &74 ; enemy_offset &139b d0 83 BNE &1320 ; check_for_enemy_touching_player # Always branches ; consider_next_enemy_from_offset &139d a6 74 LDX &74 ; enemy_offset ; consider_next_enemy &139f ca DEX &13a0 ca DEX &13a1 f0 03 BEQ &13a6 ; plot_sprites &13a3 4c 18 13 JMP &1318 ; check_for_enemies_touching_player_loop ; plot_sprites &13a6 24 61 BIT &61 ; activate_tracer_three # Negative if activating tracer three &13a8 10 0e BPL &13b8 ; skip_activating_tracer_three &13aa a9 02 LDA #&02 ; DIRECTION_LEFT &13ac 85 b1 STA &b1 ; tracers_direction + 4 &13ae 85 61 STA &61 ; activate_tracer_three # Set to positive to indicate tracer three initialised &13b0 a9 fe LDA #&fe &13b2 85 98 STA &98 ; tracers_x + 4 &13b4 a9 50 LDA #&50 &13b6 85 99 STA &99 ; tracers_y + 4 ; skip_activating_tracer_three &13b8 24 62 BIT &62 ; activate_tracer_four # Negative if activating tracer four &13ba 10 0e BPL &13ca ; skip_activating_tracer_four &13bc a9 02 LDA #&02 ; DIRECTION_LEFT &13be 85 b3 STA &b3 ; tracers_direction + 6 &13c0 85 62 STA &62 ; activate_tracer_four # Set to positive to indicate tracer four initialised &13c2 a9 fe LDA #&fe &13c4 85 9a STA &9a ; tracers_x + 6 &13c6 a9 a0 LDA #&a0 &13c8 85 9b STA &9b ; tracers_y + 6 ; skip_activating_tracer_four &13ca a5 81 LDA &81 ; tracer_frame &13cc 24 82 BIT &82 ; previous_tracer_frame &13ce d0 12 BNE &13e2 ; skip_swapping_frame &13d0 85 82 STA &82 ; previous_tracer_frame &13d2 a6 b4 LDX &b4 ; frame_data_offsets &13d4 a4 b6 LDY &b6 ; frame_data_offsets + 2 &13d6 86 b6 STX &b6 ; frame_data_offsets + 2 &13d8 84 b4 STY &b4 ; frame_data_offsets &13da a6 b5 LDX &b5 ; frame_data_offsets + 1 &13dc a4 b7 LDY &b7 ; frame_data_offsets + 3 &13de 86 b7 STX &b7 ; frame_data_offsets + 3 &13e0 84 b5 STY &b5 ; frame_data_offsets + 1 ; skip_swapping_frame &13e2 a9 ff LDA #&ff # Negative to plot sprites ; plot_or_unplot_sprites &13e4 85 4d STA &4d ; plotting_mode # also RTS # Leave immediately if plotting suppressed &13e6 a2 0a LDX #&0a ; plot_sprites_loop &13e8 86 74 STX &74 ; sprite_offset &13ea b5 91 LDA &91,X ; sprites_y &13ec c9 ff CMP #&ff &13ee 90 03 BCC &13f3 ; plot_sprite &13f0 4c aa 14 JMP &14aa ; consider_next_sprite ; plot_sprite &13f3 86 74 STX &74 ; sprite_offset &13f5 24 4d BIT &4d ; plotting_mode # Positive to use previous sprite addresses, i.e. unplot &13f7 30 0a BMI &1403 ; calculate_sprite_screen_address &13f9 b5 9c LDA &9c,X ; sprites_screen_address_low &13fb 85 70 STA &70 ; screen_address_low &13fd b5 9d LDA &9d,X ; sprites_screen_address_high &13ff 85 71 STA &71 ; screen_address_high &1401 90 31 BCC &1434 ; plot_sprite_at_screen_address # Always branches ; calculate_sprite_screen_address &1403 e9 03 SBC #&03 &1405 a8 TAY &1406 b5 90 LDA &90,X ; sprites_x &1408 e9 04 SBC #&04 &140a 29 fc AND #&fc &140c 0a ASL A &140d 08 PHP &140e 85 70 STA &70 ; screen_address_low &1410 98 TYA &1411 29 f8 AND #&f8 &1413 4a LSR A &1414 4a LSR A &1415 aa TAX &1416 98 TYA &1417 29 07 AND #&07 &1419 1d 82 03 ORA &0382,X ; row_multiplication_table + 1 &141c 65 70 ADC &70 ; screen_address_low &141e 85 70 STA &70 ; screen_address_low &1420 bd 81 03 LDA &0381,X ; row_multiplication_table &1423 69 30 ADC #&30 &1425 28 PLP &1426 69 00 ADC #&00 &1428 85 71 STA &71 ; screen_address_high &142a a6 74 LDX &74 ; sprite_offset &142c a5 70 LDA &70 ; screen_address_low &142e 95 9c STA &9c,X ; sprites_screen_address_low &1430 a5 71 LDA &71 ; screen_address_high &1432 95 9d STA &9d,X ; sprites_screen_address_high ; plot_sprite_at_screen_address &1434 b5 91 LDA &91,X ; sprites_y &1436 38 SEC &1437 e9 04 SBC #&04 &1439 29 07 AND #&07 &143b 49 07 EOR #&07 &143d 69 00 ADC #&00 &143f 8d 97 14 STA &1497 ; rows_before_group_break &1442 b5 90 LDA &90,X ; sprites_x &1444 4a LSR A &1445 29 01 AND #&01 &1447 a8 TAY &1448 b5 a8 LDA &a8,X ; sprites_base_data_offset &144a 79 b4 00 ADC &00b4,Y ; frame_data_offsets &144d 8d 5d 14 STA &145d ; sprite_data_offset_one &1450 8d 6a 14 STA &146a ; sprite_data_offset_two &1453 8d 76 14 STA &1476 ; sprite_data_offset_three &1456 a2 00 LDX #&00 &1458 a0 00 LDY #&00 ; plot_sprite_loop &145a b1 70 LDA (&70),Y ; screeen_address &145c 5d 00 2a EOR &2a00,X ; (sprite_data DIV 256) * &100 # actually EOR &2a00 + sprite_data_offset_one, X &145f 91 70 STA (&70),Y ; screeen_address &1461 18 CLC &1462 98 TYA &1463 69 08 ADC #&08 &1465 a8 TAY &1466 e8 INX &1467 b1 70 LDA (&70),Y ; screeen_address &1469 5d 00 2a EOR &2a00,X ; (sprite_data DIV 256) * &100 # actually EOR &2a00 + sprite_data_offset_two, X &146c 91 70 STA (&70),Y ; screeen_address &146e 98 TYA &146f 69 08 ADC #&08 &1471 a8 TAY &1472 e8 INX &1473 b1 70 LDA (&70),Y ; screeen_address &1475 5d 00 2a EOR &2a00,X ; (sprite_data DIV 256) * &100 # actually EOR &2a00 + sprite_data_offset_three, X &1478 91 70 STA (&70),Y ; screeen_address &147a e8 INX &147b e0 1b CPX #&1b &147d f0 29 BEQ &14a8 ; consider_next_sprite_using_offset &147f e0 0f CPX #&0f &1481 90 0e BCC &1491 ; skip_mirroring &1483 ad 5d 14 LDA &145d ; sprite_data_offset_one &1486 e9 06 SBC #&06 &1488 8d 5d 14 STA &145d ; sprite_data_offset_one &148b 8d 6a 14 STA &146a ; sprite_data_offset_two &148e 8d 76 14 STA &1476 ; sprite_data_offset_three ; skip_mirroring &1491 38 SEC &1492 98 TYA &1493 e9 0f SBC #&0f &1495 a8 TAY &1496 c9 00 CMP #&00 # actually CMP rows_before_group_break &1498 d0 c0 BNE &145a ; plot_sprite_loop &149a a5 70 LDA &70 ; screen_address_low &149c 69 77 ADC #&77 &149e 85 70 STA &70 ; screen_address_low &14a0 a5 71 LDA &71 ; screen_address_high &14a2 69 02 ADC #&02 &14a4 85 71 STA &71 ; screen_address_high &14a6 90 b2 BCC &145a ; plot_sprite_loop ; consider_next_sprite_using_offset &14a8 a6 74 LDX &74 ; sprite_offset ; consider_next_sprite &14aa ca DEX &14ab ca DEX &14ac 30 03 BMI &14b1 ; leave &14ae 4c e8 13 JMP &13e8 ; plot_sprites_loop ; leave &14b1 60 RTS ; get_pixel # Called with A = x, Y = y &14b2 48 PHA &14b3 29 fc AND #&fc &14b5 0a ASL A &14b6 08 PHP &14b7 85 70 STA &70 ; screen_address_low &14b9 98 TYA &14ba 29 f8 AND #&f8 &14bc 4a LSR A &14bd 4a LSR A &14be aa TAX &14bf 98 TYA &14c0 29 07 AND #&07 &14c2 1d 82 03 ORA &0382,X ; row_multiplication_table + 1 &14c5 65 70 ADC &70 ; screen_address_low &14c7 85 70 STA &70 ; screen_address_low &14c9 bd 81 03 LDA &0381,X ; row_multiplication_table &14cc 69 30 ADC #&30 &14ce 28 PLP &14cf 69 00 ADC #&00 &14d1 85 71 STA &71 ; screen_address_high &14d3 68 PLA &14d4 29 03 AND #&03 &14d6 aa TAX &14d7 bd 70 0b LDA &0b70,X ; colour_3_pixel_values &14da a0 00 LDY #&00 &14dc 31 70 AND (&70),Y ; screen_address &14de bc 74 0b LDY &0b74,X ; number_of_shifts_for_pixel_table &14e1 f0 04 BEQ &14e7 ; leave ; shift_loop &14e3 4a LSR A &14e4 88 DEY &14e5 d0 fc BNE &14e3 ; shift_loop ; leave &14e7 60 RTS # Leaves with A = pixel value ; set_pixel # Called with A = x, Y = y; colour in pixel_value_offset &14e8 48 PHA &14e9 29 fc AND #&fc &14eb 0a ASL A &14ec 08 PHP &14ed 85 70 STA &70 ; screen_address_low &14ef 98 TYA &14f0 29 f8 AND #&f8 &14f2 4a LSR A &14f3 4a LSR A &14f4 aa TAX &14f5 98 TYA &14f6 29 07 AND #&07 &14f8 1d 82 03 ORA &0382,X ; row_multiplication_table + 1 &14fb 65 70 ADC &70 ; screen_address_low &14fd 85 70 STA &70 ; screen_address_low &14ff bd 81 03 LDA &0381,X ; row_multiplication_table &1502 69 30 ADC #&30 &1504 28 PLP &1505 69 00 ADC #&00 &1507 85 71 STA &71 ; screen_address_high &1509 68 PLA &150a 29 03 AND #&03 &150c aa TAX &150d bd 78 0b LDA &0b78,X ; colour_2_pixel_values # actually LDA &0b00 + pixel_value_offset, X &1510 a0 00 LDY #&00 &1512 51 70 EOR (&70),Y ; screen_address &1514 91 70 STA (&70),Y ; screen_address &1516 60 RTS ; move_player_backwards_and_set_pixel_without_enemies_check &1517 a9 60 LDA #&60 ; RTS &1519 8d 16 13 STA &1316 ; check_for_enemies_touching_player &151c 20 d5 11 JSR &11d5 ; move_player_backwards_and_set_pixel &151f a9 a2 LDA #&a2 ; LDX &1521 8d 16 13 STA &1316 ; check_for_enemies_touching_player &1524 60 RTS ; game_event_handler &1525 08 PHP &1526 48 PHA &1527 c9 05 CMP #&05 ; interval timer crossing zero &1529 f0 10 BEQ &153b ; is_timer_event ; v-sync_handler &152b ad 51 02 LDA &0251 ; flashing_colours_counter &152e c9 01 CMP #&01 &1530 d0 06 BNE &1538 ; leave &1532 a5 81 LDA &81 ; tracer_frame &1534 49 03 EOR #&03 &1536 85 81 STA &81 ; tracer_frame ; leave &1538 68 PLA &1539 28 PLP &153a 60 RTS ; is_timer_event &153b a2 ff LDX #&ff &153d 8e 9c 02 STX &029c ; os_countdown_timer &1540 8e 9d 02 STX &029d ; os_countdown_timer + 1 &1543 8e 9e 02 STX &029e ; os_countdown_timer + 2 &1546 8e 9f 02 STX &029f ; os_countdown_timer + 3 &1549 a5 89 LDA &89 ; timer_interval &154b 8d a0 02 STA &02a0 ; os_countdown_timer + 4 &154e a5 78 LDA &78 ; game_time &1550 29 07 AND #&07 &1552 a8 TAY &1553 d0 0d BNE &1562 ; skip_changing_group &1555 18 CLC &1556 a5 75 LDA &75 ; time_bar_screen_address_low &1558 69 80 ADC #&80 &155a 85 75 STA &75 ; time_bar_screen_address_low &155c a5 76 LDA &76 ; time_bar_screen_address_high &155e 69 02 ADC #&02 &1560 85 76 STA &76 ; time_bar_screen_address_high ; skip_changing_group &1562 a9 00 LDA #&00 &1564 91 75 STA (&75),Y ; time_bar_screen_address &1566 a4 78 LDY &78 ; game_time &1568 c8 INY &1569 84 78 STY &78 ; game_time &156b d0 04 BNE &1571 ; not_out_of_time &156d 86 86 STX &86 ; game_state # Set to &ff (PLAYER_KILLED) to indicate out of time &156f f0 24 BEQ &1595 ; skip_adding_fourth_tracer # Always branches ; not_out_of_time &1571 98 TYA &1572 4a LSR A &1573 49 7f EOR #&7f # Make background drone faster as time reduces &1575 8d e0 08 STA &08e0 ; envelope_3 + 0 (step length) # Set envelope for background drone (sound_6) &1578 8d f0 08 STA &08f0 ; envelope_4 + 0 (step length) # Set envelope for background drone (sound_7) &157b c0 50 CPY #&50 # Add third tracer at time &50 &157d d0 0a BNE &1589 ; skip_adding_third_tracer &157f a9 ff LDA #&ff &1581 85 61 STA &61 ; activate_tracer_three # Set to negative to activate tracer three &1583 a5 8a LDA &8a ; second_timer_interval &1585 85 89 STA &89 ; timer_interval &1587 d0 0c BNE &1595 ; skip_adding_fourth_tracer ; skip_adding_third_tracer &1589 c0 a0 CPY #&a0 # Add four tracer at time &a0 &158b d0 ab BNE &1538 ; leave &158d a9 ff LDA #&ff &158f 85 62 STA &62 ; activate_tracer_four # Set to negative to activate tracer four &1591 a5 8b LDA &8b ; third_timer_interval &1593 85 89 STA &89 ; timer_interval ; skip_adding_fourth_tracer &1595 a9 07 LDA #&07 ; Generate a sound (SOUND) &1597 a2 e8 LDX #&e8 ; &09e8 = sound_8 &1599 a0 09 LDY #&09 &159b 20 f1 ff JSR &fff1 ; OSWORD # Play sound for tracer appearing (not demo) &159e 4c 38 15 JMP &1538 ; leave ; check_if_area_can_be_filled &15a1 24 86 BIT &86 ; game_state &15a3 30 17 BMI &15bc ; to_check_for_enemies_touching_player &15a5 a5 90 LDA &90 ; player_x &15a7 c5 7b CMP &7b ; path_start_x &15a9 d0 31 BNE &15dc ; check_area_for_sparklers_and_fill &15ab a4 91 LDY &91 ; player_y &15ad c4 7c CPY &7c ; path_start_y &15af d0 2b BNE &15dc ; check_area_for_sparklers_and_fill &15b1 a5 7d LDA &7d ; draw_start_direction &15b3 49 03 EOR #&03 ; up <-> down, left <-> right &15b5 45 a9 EOR &a9 ; player_direction &15b7 d0 23 BNE &15dc ; actually_fill_area &15b9 20 17 15 JSR &1517 ; move_player_backwards_and_set_pixel_without_enemies_check ; to_check_for_enemies_touching_player &15bc 4c 16 13 JMP &1316 ; check_for_enemies_touching_player ; change_line_and_check_if_back_at_origin &15bf 84 7f STY &7f ; row_in_group &15c1 a5 40 LDA &40 ; next_line_direction &15c3 85 52 STA &52 ; area_line_direction &15c5 a5 41 LDA &41 ; next_inner_direction &15c7 85 53 STA &53 ; area_inner_direction &15c9 a5 72 LDA &72 ; boundary_screen_address_low &15cb 45 9c EOR &9c ; fill_origin_screen_address_low &15cd d0 0c BNE &15db ; leave &15cf a5 73 LDA &73 ; boundary_screen_address_high &15d1 45 9d EOR &9d ; fill_origin_screen_address_high &15d3 d0 06 BNE &15db ; leave &15d5 c4 7a CPY &7a ; fill_origin_row_in_group &15d7 d0 02 BNE &15db ; leave &15d9 e4 79 CPX &79 ; fill_origin_pixel_pair_in_byte # Leave with equal if at fill origin &15db 60 RTS ; check_area_for_sparklers_and_fill &15dc a6 64 LDX &64 ; demo_mode # Non-zero if demo mode &15de d0 0d BNE &15ed ; skip_disabling_events &15e0 8e c3 02 STX &02c3 ; os_event_enable_flags + 4 # Disable v-sync events &15e3 8e c4 02 STX &02c4 ; os_event_enable_flags + 5 # Disable interval timer events &15e6 a9 15 LDA #&15 ; Flush selected buffer &15e8 a2 04 LDX #&04 ; Sound channel 0 &15ea 20 f4 ff JSR &fff4 ; OSBYTE ; skip_disabling_events &15ed a2 ff LDX #&ff &15ef 86 93 STX &93 ; fuse_y &15f1 e8 INX ; 0 &15f2 86 84 STX &84 ; player_is_drawing # Set to zero to indicate player is not drawing &15f4 86 60 STX &60 ; fuse_state # Set to zero to indicate no fuse &15f6 86 00 STX &00 ; pixel_was_added_for_first_sparkler # Set to zero to indicate no pixel added &15f8 86 01 STX &01 ; pixel_was_added_for_second_sparkler # Set to zero to indicate no pixel added &15fa 86 44 STX &44 ; sparkler_in_areas_bits # Set to zero; bits will be rotated in for each area &15fc a2 02 LDX #&02 &15fe 86 43 STX &43 ; areas_to_check ; add_pixels_for_sparklers # Ensure each sparkler has at least one pixel present &1600 a9 7c LDA #&7c ; COLOUR_1_OFFSET # Use colour 1 to add pixels for sparklers &1602 8d 0e 15 STA &150e ; pixel_value_offset &1605 a5 c0 LDA &c0 ; sparklers_first_line_start_x &1607 a4 c1 LDY &c1 ; sparklers_first_line_start_y &1609 20 b2 14 JSR &14b2 ; get_pixel # Returns A = pixel value &160c aa TAX # Branch if pixel isn't empty &160d d0 09 BNE &1618 ; skip_adding_pixel_for_first_sparkler &160f a5 c0 LDA &c0 ; sparklers_first_line_start_x &1611 85 00 STA &00 ; pixel_was_added_for_first_sparkler # Set to non-zero to indicate pixel added &1613 a4 c1 LDY &c1 ; sparklers_first_line_start_y &1615 20 e8 14 JSR &14e8 ; set_pixel ; skip_adding_pixel_for_first_sparkler &1618 24 88 BIT &88 ; two_sparklers # Positive if only one sparkler &161a 10 13 BPL &162f ; skip_adding_pixel_for_second_sparkler &161c a5 c8 LDA &c8 ; sparklers_first_line_start_x + 8 &161e a4 c9 LDY &c9 ; sparklers_first_line_start_y + 8 &1620 20 b2 14 JSR &14b2 ; get_pixel # Returns A = pixel value &1623 aa TAX # Branch if pixel isn't empty &1624 d0 09 BNE &162f ; skip_adding_pixel_for_second_sparkler &1626 a5 c8 LDA &c8 ; sparklers_first_line_start_x + 8 &1628 85 01 STA &01 ; pixel_was_added_for_second_sparkler # Set to non-zero to indicate pixel added &162a a4 c9 LDY &c9 ; sparklers_first_line_start_y + 8 &162c 20 e8 14 JSR &14e8 ; set_pixel ; skip_adding_pixel_for_second_sparkler ; check_areas_on_either_side_of_boundary_for_sparklers &162f a5 a9 LDA &a9 ; player_direction &1631 85 52 STA &52 ; area_line_direction # Using the direction along the boundary of the area, &1633 49 01 EOR #&01 ; up <-> right, left <-> down &1635 85 54 STA &54 ; initial_area_inner_direction # choose a direction into the area on one side &1637 85 53 STA &53 ; area_inner_direction &1639 a5 91 LDA &91 ; player_y &163b 29 f8 AND #&f8 &163d a8 TAY &163e a5 90 LDA &90 ; player_x &1640 20 b2 14 JSR &14b2 ; get_pixel # Calculate screen address of player, i.e. end of area &1643 a5 70 LDA &70 ; screen_address_low &1645 85 72 STA &72 ; boundary_screen_address_low &1647 85 9c STA &9c ; fill_origin_screen_address_low &1649 a5 71 LDA &71 ; screen_address_high &164b 85 73 STA &73 ; boundary_screen_address_high &164d 85 9d STA &9d ; fill_origin_screen_address_high &164f a5 90 LDA &90 ; player_x &1651 29 02 AND #&02 &1653 4a LSR A &1654 aa TAX &1655 86 79 STX &79 ; fill_origin_pixel_pair_in_byte &1657 d0 04 BNE &165d ; use_right_mask &1659 a9 cc LDA #&cc ; 3300 # Set mask to be left two pixels ; use_left_mask &165b d0 02 BNE &165f ; set_pixel_pair_mask ; use_right_mask &165d a9 33 LDA #&33 ; 0033 # Set mask to be right two pixels ; set_pixel_pair_mask &165f 85 7e STA &7e ; pixel_pair_mask &1661 85 42 STA &42 ; initial_pixel_pair_mask &1663 a5 91 LDA &91 ; player_y &1665 29 07 AND #&07 &1667 a8 TAY &1668 84 7a STY &7a ; fill_origin_row_in_group &166a 84 7f STY &7f ; row_in_group ; check_column_of_area_for_sparkler &166c a5 72 LDA &72 ; boundary_screen_address_low &166e 85 70 STA &70 ; area_screen_address_low &1670 a5 73 LDA &73 ; boundary_screen_address_high &1672 85 71 STA &71 ; area_screen_address_high &1674 a5 53 LDA &53 ; area_inner_direction # If the area is above the boundary, &1676 d0 2e BNE &16a6 ; not_checking_upwards_column ; check_upwards_column # Check a column of the area from bottom to top &1678 88 DEY # Move up a pixel &1679 10 0f BPL &168a ; not_group_checking_up &167b a0 07 LDY #&07 &167d 38 SEC &167e a5 70 LDA &70 ; area_screen_address_low &1680 e9 80 SBC #&80 &1682 85 70 STA &70 ; area_screen_address_low &1684 a5 71 LDA &71 ; area_screen_address_high &1686 e9 02 SBC #&02 &1688 85 71 STA &71 ; area_screen_address_high ; not_group_checking_up &168a b1 70 LDA (&70),Y ; area_screen_address # Get a pixel pair from the column &168c 25 7e AND &7e ; pixel_pair_mask &168e f0 e8 BEQ &1678 ; check_upwards_column # Continue until it contains something &1690 c9 10 CMP #&10 ; 1111 + 1 &1692 90 43 BCC &16d7 ; to_sparkler_was_in_area # Branches only if pair contains colour 1 pixel(s) &1694 48 PHA &1695 a5 52 LDA &52 ; area_line_direction &1697 c9 02 CMP #&02 ; DIRECTION_LEFT &1699 d0 3f BNE &16da ; move_along_boundary_after_pla_and_ldy &169b 68 PLA &169c 29 55 AND #&55 ; 0303 # Check right pixel of pair &169e f0 d8 BEQ &1678 ; check_upwards_column # Continue checking if it is colour 0 &16a0 c9 10 CMP #&10 ; 1111 + 1 &16a2 b0 37 BCS &16db ; move_along_boundary_after_ldy # Branches if pixel is colour 2 or 3; otherwise colour 1 &16a4 90 31 BCC &16d7 ; to_sparkler_was_in_area # Always branches ; not_checking_upwards_column &16a6 c9 03 CMP #&03 ; DIRECTION_DOWN # If the area is below the boundary, &16a8 d0 33 BNE &16dd ; move_along_boundary ; check_downwards_column # Check a column of the area from top to bottom &16aa c8 INY # Move down a pixel &16ab c0 08 CPY #&08 &16ad 90 0e BCC &16bd ; not_group_checking_down &16af a0 00 LDY #&00 &16b1 a5 70 LDA &70 ; area_screen_address_low &16b3 69 7f ADC #&7f &16b5 85 70 STA &70 ; area_screen_address_low &16b7 a5 71 LDA &71 ; area_screen_address_high &16b9 69 02 ADC #&02 &16bb 85 71 STA &71 ; area_screen_address_high ; not_group_checking_down &16bd b1 70 LDA (&70),Y ; area_screen_address # Get a pixel pair from the column &16bf 25 7e AND &7e ; pixel_pair_mask &16c1 f0 e7 BEQ &16aa ; check_downwards_column # Continue until it contains something &16c3 c9 10 CMP #&10 ; 1111 + 1 &16c5 90 10 BCC &16d7 ; to_sparkler_was_in_area # Branches only if pair contains colour 1 pixel(s) &16c7 48 PHA &16c8 a5 52 LDA &52 ; area_line_direction &16ca c9 02 CMP #&02 ; DIRECTION_LEFT &16cc d0 0c BNE &16da ; move_along_boundary_after_pla_and_ldy &16ce 68 PLA &16cf 29 55 AND #&55 ; 0303 # Check right pixel of pair &16d1 f0 d7 BEQ &16aa ; check_downwards_column # Continue checking if it is colour 0 &16d3 c9 10 CMP #&10 ; 1111 + 1 &16d5 b0 04 BCS &16db ; move_along_boundary_after_ldy # Branches if pixel is colour 2 or 3; otherwise colour 1 ; to_sparkler_was_in_area # Carry clear to indicate sparkler is present in area &16d7 4c d2 17 JMP &17d2 ; sparkler_was_in_area ; move_along_boundary_after_pla_and_ldy &16da 68 PLA ; move_along_boundary_after_ldy &16db a4 7f LDY &7f ; row_in_group ; move_along_boundary &16dd a9 01 LDA #&01 &16df 85 77 STA &77 ; check_pass &16e1 a5 52 LDA &52 ; area_line_direction # On first pass, check for turn to one side &16e3 49 03 EOR #&03 ; up <-> down, left <-> right &16e5 85 41 STA &41 ; next_inner_direction &16e7 a5 53 LDA &53 ; area_inner_direction &16e9 85 40 STA &40 ; next_line_direction ; check_for_boundary_in_direction # Called with A = next_line_direction &16eb d0 33 BNE &1720 ; not_following_boundary_up ; check_if_boundary_continues_up &16ed 88 DEY # Move up a pixel &16ee 10 11 BPL &1701 ; not_group_up &16f0 a0 07 LDY #&07 &16f2 38 SEC &16f3 a5 72 LDA &72 ; boundary_screen_address_low # Move up a group of eight rows &16f5 e9 80 SBC #&80 &16f7 85 70 STA &70 ; area_screen_address_low &16f9 a5 73 LDA &73 ; boundary_screen_address_high &16fb e9 02 SBC #&02 &16fd 85 71 STA &71 ; area_screen_address_high &16ff d0 08 BNE &1709 ; consider_pixel_pair_up ; not_group_up &1701 a5 72 LDA &72 ; boundary_screen_address_low &1703 85 70 STA &70 ; area_screen_address_low &1705 a5 73 LDA &73 ; boundary_screen_address_high &1707 85 71 STA &71 ; area_screen_address_high ; consider_pixel_pair_up &1709 b1 70 LDA (&70),Y ; area_screen_address &170b 25 7e AND &7e ; pixel_pair_mask &170d c9 10 CMP #&10 ; 1111 + 1 # Does the pixel pair contain a filled or unfilled line? &170f b0 03 BCS &1714 ; follow_boundary_up # Branches if pixel pair contains colour 2 or 3 &1711 4c ab 17 JMP &17ab ; check_next_direction_for_boundary ; follow_boundary_up &1714 88 DEY # Move up a pixel &1715 a5 70 LDA &70 ; area_screen_address_low &1717 85 72 STA &72 ; boundary_screen_address_low &1719 a5 71 LDA &71 ; area_screen_address_high &171b 85 73 STA &73 ; boundary_screen_address_high &171d 4c c9 17 JMP &17c9 ; consider_next_bit_of_boundary ; not_following_boundary_up &1720 c9 01 CMP #&01 ; DIRECTION_RIGHT &1722 d0 28 BNE &174c ; not_following_boundary_right ; check_if_boundary_continues_right &1724 b1 72 LDA (&72),Y ; boundary_screen_address &1726 25 7e AND &7e ; pixel_pair_mask &1728 29 55 AND #&55 ; 0303 # Check right pixel of pair &172a c9 10 CMP #&10 ; 1111 + 1 &172c b0 03 BCS &1731 ; follow_boundary_right # Branches if pixel is colour 2 or 3; otherwise colour 1 &172e 4c ab 17 JMP &17ab ; check_next_direction_for_boundary ; follow_boundary_right &1731 a5 7e LDA &7e ; pixel_pair_mask &1733 49 ff EOR #&ff # Use other pair of pixels for next mask &1735 85 7e STA &7e ; pixel_pair_mask &1737 8a TXA &1738 49 01 EOR #&01 # Move right two pixels &173a aa TAX &173b d0 0c BNE &1749 ; not_byte_right &173d a5 72 LDA &72 ; boundary_screen_address_low # Move right a column of eight bytes &173f 69 07 ADC #&07 &1741 85 72 STA &72 ; boundary_screen_address_low &1743 a5 73 LDA &73 ; boundary_screen_address_high &1745 69 00 ADC #&00 &1747 85 73 STA &73 ; boundary_screen_address_high ; not_byte_right &1749 4c c9 17 JMP &17c9 ; consider_next_bit_of_boundary ; not_following_boundary_right &174c c9 02 CMP #&02 ; DIRECTION_LEFT &174e d0 3d BNE &178d ; not_following_boundary_left ; check_if_boundary_continues_left &1750 ca DEX # Move left two pixels &1751 f0 10 BEQ &1763 ; not_byte_left &1753 a2 01 LDX #&01 &1755 a5 72 LDA &72 ; boundary_screen_address_low # Move left a column of eight bytes &1757 e9 08 SBC #&08 &1759 85 70 STA &70 ; area_screen_address_low &175b a5 73 LDA &73 ; boundary_screen_address_high &175d e9 00 SBC #&00 &175f 85 71 STA &71 ; area_screen_address_high &1761 d0 08 BNE &176b ; consider_pixel_pair_left # Always branches ; not_byte_left &1763 a5 72 LDA &72 ; boundary_screen_address_low &1765 85 70 STA &70 ; area_screen_address_low &1767 a5 73 LDA &73 ; boundary_screen_address_high &1769 85 71 STA &71 ; area_screen_address_high ; consider_pixel_pair_left &176b a5 7e LDA &7e ; pixel_pair_mask &176d 49 ff EOR #&ff # Use other pair of pixels &176f 29 55 AND #&55 ; 0303 # Check right pixel of pair &1771 31 70 AND (&70),Y ; area_screen_address &1773 c9 10 CMP #&10 ; 1111 + 1 # Does the pixel contain a filled or unfilled line? &1775 b0 06 BCS &177d ; follow_boundary_left # Branches if pixel is colour 2 or 3; otherwise colour 1 &1777 8a TXA &1778 49 01 EOR #&01 # Move left two pixels &177a aa TAX &177b 10 2e BPL &17ab ; check_next_direction_for_boundary # Always branches ; follow_boundary_left &177d a5 70 LDA &70 ; area_screen_address_low &177f 85 72 STA &72 ; boundary_screen_address_low &1781 a5 71 LDA &71 ; area_screen_address_high &1783 85 73 STA &73 ; boundary_screen_address_high &1785 a5 7e LDA &7e ; pixel_pair_mask &1787 49 ff EOR #&ff # Use other pair of pixels for next mask &1789 85 7e STA &7e ; pixel_pair_mask &178b d0 3c BNE &17c9 ; consider_next_bit_of_boundary # Always branches ; not_following_boundary_left ; check_if_boundary_continues_down &178d c8 INY # Move down a pixel &178e b1 72 LDA (&72),Y ; boundary_screen_address &1790 25 7e AND &7e ; pixel_pair_mask &1792 c9 10 CMP #&10 ; 1111 + 1 &1794 90 15 BCC &17ab ; consider_if_at_corner_of_boundary # Branches if not colour 2 or 3 &1796 c8 INY # Move down a pixel &1797 c0 08 CPY #&08 &1799 d0 2e BNE &17c9 ; consider_next_bit_of_boundary &179b a0 00 LDY #&00 # Move down a group of eight pixels &179d a5 72 LDA &72 ; boundary_screen_address_low &179f 69 7f ADC #&7f &17a1 85 72 STA &72 ; boundary_screen_address_low &17a3 a5 73 LDA &73 ; boundary_screen_address_high &17a5 69 02 ADC #&02 &17a7 85 73 STA &73 ; boundary_screen_address_high &17a9 90 1e BCC &17c9 ; consider_next_bit_of_boundary # Always branches ; check_next_direction_for_boundary &17ab a4 7f LDY &7f ; row_in_group &17ad c6 77 DEC &77 ; check_pass &17af 30 0b BMI &17bc ; third_pass ; second_pass &17b1 a5 53 LDA &53 ; area_inner_direction # On second pass, check for boundary continuing straight &17b3 85 41 STA &41 ; next_inner_direction &17b5 a5 52 LDA &52 ; area_line_direction &17b7 85 40 STA &40 ; next_line_direction &17b9 4c eb 16 JMP &16eb ; check_for_boundary_in_direction ; third_pass &17bc a5 52 LDA &52 ; area_line_direction # On third pass, check for turn on other side &17be 85 41 STA &41 ; next_inner_direction &17c0 a5 53 LDA &53 ; area_inner_direction &17c2 49 03 EOR #&03 ; up <-> down, left <-> right &17c4 85 40 STA &40 ; next_line_direction &17c6 4c eb 16 JMP &16eb ; check_for_boundary_in_direction ; consider_next_bit_of_boundary &17c9 20 bf 15 JSR &15bf ; change_line_and_check_if_back_at_origin # Returns zero if the entire area has been checked &17cc f0 03 BEQ &17d1 ; sparkler_wasn't_in_area # If so, sparkler isn't in area &17ce 4c 6c 16 JMP &166c ; check_column_of_area_for_sparkler # Otherwise, check next section of area ; sparkler_wasn't_in_area &17d1 38 SEC # Set carry to indicate sparkler not present in area ; sparkler_was_in_area # Called with carry clear to indicate sparkler present &17d2 26 44 ROL &44 ; sparkler_in_areas_bits &17d4 a5 a9 LDA &a9 ; player_direction &17d6 85 52 STA &52 ; area_line_direction &17d8 a5 9c LDA &9c ; fill_origin_screen_address_low &17da 85 72 STA &72 ; boundary_screen_address_low &17dc a5 9d LDA &9d ; fill_origin_screen_address_high &17de 85 73 STA &73 ; boundary_screen_address_high &17e0 a6 79 LDX &79 ; fill_origin_pixel_pair_in_byte &17e2 a4 7a LDY &7a ; fill_origin_row_in_group &17e4 84 7f STY &7f ; row_in_group &17e6 a5 42 LDA &42 ; initial_pixel_pair_mask &17e8 85 7e STA &7e ; pixel_pair_mask &17ea c6 43 DEC &43 ; areas_to_check # Have both sides of the boundary been checked? &17ec f0 09 BEQ &17f7 ; check_for_split_check &17ee a5 54 LDA &54 ; initial_area_inner_direction # If not, check the other side of the boundary &17f0 49 03 EOR #&03 ; up <-> down, left <-> right &17f2 85 53 STA &53 ; area_inner_direction &17f4 4c 6c 16 JMP &166c ; check_column_of_area_for_sparkler ; check_for_split_check &17f7 a5 54 LDA &54 ; initial_area_inner_direction &17f9 46 44 LSR &44 ; sparkler_in_areas_bit # Carry clear if second area contains a sparkler &17fb 90 04 BCC &1801 ; second_area_has_sparkler &17fd 49 03 EOR #&03 ; up <-> down, left <-> right &17ff 10 0b BPL &180c ; fill_area_without_sparkler # If not, fill second area; always branches ; second_area_has_sparkler &1801 46 44 LSR &44 ; sparkler_in_areas_bits # Carry set if first area doesn't contain a sparkler &1803 b0 07 BCS &180c ; fill_area_without_sparkler # If so, fill first area &1805 a9 3f LDA #&3f ; PLAYER_WON_BY_SPLITTING # Otherwise, both areas contain a sparkler; split bonus &1807 85 86 STA &86 ; game_state &1809 4c 3f 1a JMP &1a3f ; probably_finished_filling ; fill_area_without_sparkler &180c 85 53 STA &53 ; area_inner_direction &180e a5 63 LDA &63 ; slow_fill # &ff if slow fill &1810 29 0f AND #&0f &1812 85 45 STA &45 ; fill_pixel_value_eor # &f if slow fill to alternate rows, &0 if fast &1814 f0 06 BEQ &181c ; not_slow_fill &1816 a9 0a LDA #&0a ; 1010 # Use mixed colour for slow fill &1818 85 43 STA &43 ; initial_pixel_value &181a d0 04 BNE &1820 ; consider_filling_column_of_area ; not_slow_fill &181c a9 0f LDA #&0f ; 1111 # Use solid colour for fast fill, &181e 85 43 STA &43 ; initial_pixel_value ; consider_filling_column_of_area &1820 a5 53 LDA &53 ; area_inner_direction &1822 c9 03 CMP #&03 ; DIRECTION_DOWN &1824 d0 41 BNE &1867 ; move_along_boundary_for_fill ; fill_downwards_column &1826 a5 72 LDA &72 ; boundary_screen_address_low &1828 85 70 STA &70 ; area_screen_address_low &182a a5 73 LDA &73 ; boundary_screen_address_high &182c 85 71 STA &71 ; area_screen_address_high &182e a5 43 LDA &43 ; initial_pixel_value &1830 85 44 STA &44 ; fill_pixel_value ; fill_downwards_column_loop &1832 c8 INY # Move down a pixel &1833 c0 08 CPY #&08 &1835 d0 0e BNE &1845 ; not_group_filling_down &1837 a0 00 LDY #&00 &1839 a5 70 LDA &70 ; area_screen_address_low # Move down a group of eight pixels &183b 69 7f ADC #&7f &183d 85 70 STA &70 ; area_screen_address_low &183f a5 71 LDA &71 ; area_screen_address_high &1841 69 02 ADC #&02 &1843 85 71 STA &71 ; area_screen_address_high ; not_group_filling_down &1845 b1 70 LDA (&70),Y ; area_screen_address # Get a pixel pair from the column &1847 25 7e AND &7e ; pixel_pair_mask &1849 c9 10 CMP #&10 ; 1111 + 1 &184b b0 18 BCS &1865 ; move_along_boundary_for_fill_after_ldy # Branches if either of the pixels are colour 2 or 3 &184d a5 44 LDA &44 ; fill_pixel_value &184f 45 45 EOR &45 ; fill_pixel_value_eor # Alternate fill pattern if slow fill &1851 85 44 STA &44 ; fill_pixel_value &1853 25 7e AND &7e ; pixel_pair_mask &1855 11 70 ORA (&70),Y ; area_screen_address # Convert pair of pixels &1857 91 70 STA (&70),Y ; area_screen_address # (this fills all but the border of the area) &1859 a5 69 LDA &69 ; pixels_filled_low &185b 69 02 ADC #&02 &185d 85 69 STA &69 ; pixels_filled_low &185f d0 d1 BNE &1832 ; fill_downwards_column_loop &1861 e6 6a INC &6a ; pixels_filled_high &1863 d0 cd BNE &1832 ; fill_downwards_column_loop # Always branches ; move_along_boundary_for_fill_after_ldy &1865 a4 7f LDY &7f ; row_in_group ; move_along_boundary_for_fill &1867 a9 01 LDA #&01 &1869 85 77 STA &77 ; check_pass &186b a5 52 LDA &52 ; area_line_direction # On first pass, check for turn to one side &186d 49 03 EOR #&03 ; up <-> down, left <-> right &186f 85 41 STA &41 ; next_inner_direction &1871 a5 53 LDA &53 ; area_inner_direction &1873 85 40 STA &40 ; next_line_direction ; check_boundary_in_direction_for_fill # Called with A = next_line_direction &1875 d0 65 BNE &18dc ; not_following_boundary_up_for_fill ; check_if_boundary_continues_up_for_fill &1877 88 DEY # Move up a pixel &1878 10 11 BPL &188b ; not_group_up_for_fill &187a a0 07 LDY #&07 &187c 38 SEC &187d a5 72 LDA &72 ; boundary_screen_address_low # Move up a group of eight rows &187f e9 80 SBC #&80 &1881 85 70 STA &70 ; area_screen_address_low &1883 a5 73 LDA &73 ; boundary_screen_address_high &1885 e9 02 SBC #&02 &1887 85 71 STA &71 ; area_screen_address_high &1889 d0 08 BNE &1893 ; consider_pixel_pair_up_for_fill ; not_group_up_for_fill &188b a5 72 LDA &72 ; boundary_screen_address_low &188d 85 70 STA &70 ; area_screen_address_low &188f a5 73 LDA &73 ; boundary_screen_address_high &1891 85 71 STA &71 ; area_screen_address_high ; consider_pixel_pair_up_for_fill &1893 a5 53 LDA &53 ; area_inner_direction &1895 d0 08 BNE &189f ; skip_up_pixel &1897 a9 0a LDA #&0a ; 1010 # Convert left pixel of pair &1899 25 7e AND &7e ; pixel_pair_mask &189b 11 70 ORA (&70),Y ; area_screen_address &189d 91 70 STA (&70),Y ; area_screen_address ; skip_up_pixel &189f b1 70 LDA (&70),Y ; area_screen_address &18a1 25 7e AND &7e ; pixel_pair_mask &18a3 29 aa AND #&aa ; 3030 # Check left pixel of pair &18a5 c9 10 CMP #&10 ; 1111 + 1 # Does the pixel contain a filled or unfilled line? &18a7 b0 03 BCS &18ac ; follow_boundary_up_for_fill # Branches if pixel contains colour 2 or 3 &18a9 4c c7 19 JMP &19c7 ; check_next_direction_for_boundary_fill ; follow_boundary_up_for_fill &18ac 85 46 STA &46 ; existing_pixel &18ae a5 70 LDA &70 ; area_screen_address_low &18b0 85 72 STA &72 ; boundary_screen_address_low &18b2 a5 71 LDA &71 ; area_screen_address_high &18b4 85 73 STA &73 ; boundary_screen_address_high &18b6 a5 41 LDA &41 ; next_inner_direction &18b8 c9 01 CMP #&01 ; DIRECTION_RIGHT &18ba d0 0e BNE &18ca ; area_to_left_filling_up ; area_to_right_filling_up &18bc a5 69 LDA &69 ; pixels_filled_low &18be 69 01 ADC #&01 &18c0 85 69 STA &69 ; pixels_filled_low &18c2 d0 02 BNE &18c6 ; skip_overflow &18c4 e6 6a INC &6a ; pixels_filled_high ; skip_overflow &18c6 a9 0f LDA #&0f ; 1111 # Convert pixel to right of line as well &18c8 d0 02 BNE &18cc ; fill_line_up ; area_to_left_filling_up &18ca a9 0a LDA #&0a ; 1010 ; fill_line_up &18cc 25 7e AND &7e ; pixel_pair_mask &18ce 48 PHA &18cf 11 72 ORA (&72),Y ; boundary_screen_address # Convert right pixel of pair into filled line &18d1 91 72 STA (&72),Y ; boundary_screen_address &18d3 88 DEY # Move up a pixel &18d4 68 PLA &18d5 11 72 ORA (&72),Y ; boundary_screen_address # Convert right pixel of pair into filled line &18d7 91 72 STA (&72),Y ; boundary_screen_address &18d9 4c 29 1a JMP &1a29 ; count_pixel_and_consider_filling_column ; not_following_boundary_up_for_fill &18dc c9 01 CMP #&01 ; DIRECTION_RIGHT &18de d0 3a BNE &191a ; not_following_boundary_right_for_fill ; check_if_boundary_continues_right_for_fill &18e0 b1 72 LDA (&72),Y ; boundary_screen_address &18e2 25 7e AND &7e ; pixel_pair_mask &18e4 29 55 AND #&55 ; 0303 # Check right pixel of pair &18e6 c9 10 CMP #&10 ; 1111 + 1 &18e8 b0 05 BCS &18ef ; follow_boundary_right_for_fill # Branches if pixel is colour 2 or 3; otherwise colour 1 &18ea 4c c7 19 JMP &19c7 ; check_next_direction_for_boundary_fill ; unused &18ed 85 46 STA &46 ; existing_pixel # Unused code ; follow_boundary_right_for_fill &18ef a9 05 LDA #&05 ; 0101 &18f1 25 7e AND &7e ; pixel_pair_mask &18f3 11 72 ORA (&72),Y ; boundary_screen_address # Convert right pixel of pair into filled line &18f5 91 72 STA (&72),Y ; boundary_screen_address &18f7 a5 7e LDA &7e ; pixel_pair_mask &18f9 49 ff EOR #&ff # Use other pair of pixels for next mask &18fb 85 7e STA &7e ; pixel_pair_mask &18fd 8a TXA &18fe 49 01 EOR #&01 # Move right two pixel &1900 aa TAX &1901 d0 0c BNE &190f ; not_byte_right_for_fill &1903 a5 72 LDA &72 ; boundary_screen_address_low &1905 69 07 ADC #&07 &1907 85 72 STA &72 ; boundary_screen_address_low &1909 a5 73 LDA &73 ; boundary_screen_address_high &190b 69 00 ADC #&00 &190d 85 73 STA &73 ; boundary_screen_address_high ; not_byte_right_for_fill &190f a9 0a LDA #&0a ; 1010 &1911 25 7e AND &7e ; pixel_pair_mask &1913 11 72 ORA (&72),Y ; boundary_screen_address # Convert left pixel of pair into filled line &1915 91 72 STA (&72),Y ; boundary_screen_address &1917 4c 29 1a JMP &1a29 ; count_pixel_and_consider_filling_column ; not_following_boundary_right_for_fill &191a c9 02 CMP #&02 ; DIRECTION_LEFT &191c d0 57 BNE &1975 ; not_following_boundary_left_for_fill ; check_if_boundary_continues_left_for_fill &191e ca DEX # Move left two pixels &191f 10 10 BPL &1931 ; not_byte_left_for_fill &1921 a2 01 LDX #&01 &1923 a5 72 LDA &72 ; boundary_screen_address_low # Move left a column of eight bytes &1925 e9 08 SBC #&08 &1927 85 70 STA &70 ; area_screen_address_low &1929 a5 73 LDA &73 ; boundary_screen_address_high &192b e9 00 SBC #&00 &192d 85 71 STA &71 ; area_screen_address_high &192f d0 08 BNE &1939 ; consider_pixel_pair_left_for_fill # Always branches ; not_byte_left_for_fill &1931 a5 72 LDA &72 ; boundary_screen_address_low &1933 85 70 STA &70 ; area_screen_address_low &1935 a5 73 LDA &73 ; boundary_screen_address_high &1937 85 71 STA &71 ; area_screen_address_high ; consider_pixel_pair_left_for_fill &1939 a5 53 LDA &53 ; area_inner_direction &193b c9 02 CMP #&02 ; DIRECTION_LEFT &193d d0 0a BNE &1949 ; area_not_to_left &193f a5 7e LDA &7e ; pixel_pair_mask &1941 49 ff EOR #&ff # Use other pixel pair &1943 29 05 AND #&05 ; 0101 &1945 11 70 ORA (&70),Y ; area_screen_address # Convert right pixel of pair &1947 91 70 STA (&70),Y ; area_screen_address ; area_not_to_left &1949 a5 7e LDA &7e ; pixel_pair_mask &194b 49 ff EOR #&ff # Use other pixel pair &194d 29 55 AND #&55 ; 0303 # Check right pixel of pair &194f 31 70 AND (&70),Y ; area_screen_address &1951 c9 10 CMP #&10 ; 1111 + 1 # Does the pixel contain a filled or unfilled line? &1953 b0 07 BCS &195c ; follow_boundary_left_for_fill # Branches if pixel is colour 2 or 3; otherwise colour 1 &1955 8a TXA &1956 49 01 EOR #&01 # Move right two pixels &1958 aa TAX &1959 4c c7 19 JMP &19c7 ; check_next_direction_for_boundary_fill ; follow_boundary_left_for_fill &195c 85 46 STA &46 ; existing_pixel &195e a5 70 LDA &70 ; area_screen_address_low &1960 85 72 STA &72 ; boundary_screen_address_low &1962 a5 71 LDA &71 ; area_screen_address_high &1964 85 73 STA &73 ; boundary_screen_address_high &1966 a5 7e LDA &7e ; pixel_pair_mask &1968 49 ff EOR #&ff # Use other pair of pixels for next mask &196a 85 7e STA &7e ; pixel_pair_mask &196c 29 0f AND #&0f ; 1111 &196e 11 70 ORA (&70),Y ; area_screen_address # Convert both pixels into filled line &1970 91 70 STA (&70),Y ; area_screen_address &1972 4c 29 1a JMP &1a29 ; count_pixel_and_consider_filling_column ; not_following_boundary_left_for_fill ; check_if_boundary_continues_down_for_fill &1975 c8 INY # Move down a pixel &1976 a5 53 LDA &53 ; area_inner_direction &1978 c9 03 CMP #&03 ; DIRECTION_DOWN &197a d0 08 BNE &1984 ; area_not_down # Always branches &197c a9 0a LDA #&0a ; 1010 # Unused code &197e 25 7e AND &7e ; pixel_pair_mask &1980 11 72 ORA (&72),Y ; boundary_screen_address &1982 91 72 STA (&72),Y ; boundary_screen_address ; area_not_down &1984 b1 72 LDA (&72),Y ; boundary_screen_address &1986 25 7e AND &7e ; pixel_pair_mask &1988 29 aa AND #&aa ; 3030 # Check left pixel of pair &198a c9 10 CMP #&10 ; 1111 + 1 # Does the pixel contain a filled or unfilled line? &198c 90 39 BCC &19c7 ; check_next_direction_for_boundary_fill # If not, branch &198e 85 46 STA &46 ; existing_pixel &1990 a5 41 LDA &41 ; next_inner_direction &1992 c9 01 CMP #&01 ; DIRECTION_RIGHT &1994 d0 0e BNE &19a4 ; area_to_left_filling_down ; area_to_right_filling_down &1996 a5 69 LDA &69 ; pixels_filled_low &1998 69 01 ADC #&01 &199a 85 69 STA &69 ; pixels_filled_low &199c d0 02 BNE &19a0 ; skip_overflow &199e e6 6a INC &6a ; pixels_filled_high ; skip_overflow &19a0 a9 0f LDA #&0f ; 1111 # Convert pixel to right of line as well &19a2 d0 02 BNE &19a6 ; fill_line_down ; area_to_left_filling_down &19a4 a9 0a LDA #&0a ; 1010 ; fill_line_down &19a6 25 7e AND &7e ; pixel_pair_mask &19a8 48 PHA &19a9 11 72 ORA (&72),Y ; boundary_screen_address # Convert right pixel of pair into filled line &19ab 91 72 STA (&72),Y ; boundary_screen_address &19ad c8 INY # Move down a pixel &19ae c0 08 CPY #&08 &19b0 90 0e BCC &19c0 ; not_group_down_for_fill &19b2 a0 00 LDY #&00 &19b4 a5 72 LDA &72 ; boundary_screen_address_low # Move down a group of eight rows &19b6 69 7f ADC #&7f &19b8 85 72 STA &72 ; boundary_screen_address_low &19ba a5 73 LDA &73 ; boundary_screen_address_high &19bc 69 02 ADC #&02 &19be 85 73 STA &73 ; boundary_screen_address_high ; not_group_down_for_fill &19c0 68 PLA &19c1 11 72 ORA (&72),Y ; boundary_screen_address # Convert right pixel of pair into filled line &19c3 91 72 STA (&72),Y ; boundary_screen_address &19c5 90 62 BCC &1a29 ; count_pixel_and_consider_filling_column # Always branches ; check_next_direction_for_boundary_fill &19c7 c6 77 DEC &77 ; check_pass &19c9 30 0d BMI &19d8 ; consider_inner_corner_before_third_pass_for_fill ; second_pass_for_fill &19cb a4 7f LDY &7f ; row_in_group &19cd a5 53 LDA &53 ; area_inner_direction # On second pass, check for boundary continuing straight &19cf 85 41 STA &41 ; next_inner_direction &19d1 a5 52 LDA &52 ; area_line_direction &19d3 85 40 STA &40 ; next_line_direction &19d5 4c 75 18 JMP &1875 ; check_boundary_in_direction_for_fill ; consider_inner_corner_before_third_pass_for_fill &19d8 a5 52 LDA &52 ; area_line_direction &19da d0 0a BNE &19e6 ; not_inner_corner_filling_up ; inner_corner_filling_up &19dc a9 0f LDA #&0f ; 1111 &19de 25 7e AND &7e ; pixel_pair_mask &19e0 11 70 ORA (&70),Y ; area_screen_address # Convert inner corner &19e2 91 70 STA (&70),Y ; area_screen_address &19e4 d0 34 BNE &1a1a ; third_pass_for_fill # Always branches ; not_inner_corner_filling_up &19e6 c9 01 CMP #&01 ; DIRECTION_RIGHT &19e8 d0 0a BNE &19f4 ; not_inner_corner_filling_right ; inner_corner_filling_right &19ea a9 05 LDA #&05 ; 0101 &19ec 25 7e AND &7e ; pixel_pair_mask &19ee 11 72 ORA (&72),Y ; boundary_screen_address # Convert pixel on inner corner &19f0 91 72 STA (&72),Y ; boundary_screen_address &19f2 d0 26 BNE &1a1a ; third_pass_for_fill # Always branches ; not_inner_corner_filling_right &19f4 c9 02 CMP #&02 ; DIRECTION_LEFT &19f6 d0 0c BNE &1a04 ; not_inner_corner_filling_left ; inner_corner_filling_left &19f8 a5 7e LDA &7e ; pixel_pair_mask &19fa 49 ff EOR #&ff # Use other pixel pair &19fc 29 05 AND #&05 ; 0101 &19fe 11 70 ORA (&70),Y ; area_screen_address # Convert pixel on inner corner &1a00 91 70 STA (&70),Y ; area_screen_address &1a02 d0 16 BNE &1a1a ; third_pass_for_fill # Always branches ; not_inner_corner_filling_left ; inner_corner_filling_down &1a04 a9 0f LDA #&0f ; 1111 &1a06 25 7e AND &7e ; pixel_pair_mask &1a08 11 72 ORA (&72),Y ; boundary_screen_address # Convert inner corner &1a0a 91 72 STA (&72),Y ; boundary_screen_address &1a0c a5 53 LDA &53 ; area_inner_direction &1a0e 49 03 EOR #&03 ; up <-> down, left <-> right &1a10 85 52 STA &52 ; area_line_direction &1a12 a9 03 LDA #&03 ; DIRECTION_DOWN &1a14 85 53 STA &53 ; area_inner_direction &1a16 88 DEY &1a17 4c 20 18 JMP &1820 ; consider_filling_column_of_area ; third_pass_for_fill &1a1a a4 7f LDY &7f ; row_in_group &1a1c a5 52 LDA &52 ; area_line_direction # On third pass, check for turn on other side &1a1e 85 41 STA &41 ; next_inner_direction &1a20 a5 53 LDA &53 ; area_inner_direction &1a22 49 03 EOR #&03 ; up <-> down, left <-> right &1a24 85 40 STA &40 ; next_line_direction &1a26 4c 75 18 JMP &1875 ; check_boundary_in_direction_for_fill ; add_pixel_to_count_and_consider_filling_column_of_area &1a29 a5 46 LDA &46 ; existing_pixel &1a2b 29 0f AND #&0f ; 1111 &1a2d d0 08 BNE &1a37 ; skip_adding_pixel # Branches if any pixels are fill or filled line &1a2f e6 69 INC &69 ; pixels_filled_low &1a31 e6 69 INC &69 ; pixels_filled_low &1a33 d0 02 BNE &1a37 ; skip_overflow &1a35 e6 6a INC &6a ; pixels_filled_high ; skip_overflow ; skip_adding_pixel &1a37 20 bf 15 JSR &15bf ; change_line_and_check_if_back_at_origin # Returns zero if the entire area has been filled &1a3a f0 03 BEQ &1a3f ; remove_any_pixels_added_for_sparklers &1a3c 4c 20 18 JMP &1820 ; consider_filling_column_of_area ; remove_any_pixels_added_for_sparklers &1a3f a5 00 LDA &00 ; pixel_was_added_for_first_sparkler # Zero if no pixel added &1a41 f0 05 BEQ &1a48 ; skip_removing_pixel_for_first_sparkler &1a43 a4 c1 LDY &c1 ; sparklers_first_line_start_y &1a45 20 e8 14 JSR &14e8 ; set_pixel ; skip_removing_pixel_for_first_sparkler &1a48 24 88 BIT &88 ; two_sparklers # Positive if only one sparkler &1a4a 10 09 BPL &1a55 ; skip_removing_pixel_for_second_sparkler &1a4c a5 01 LDA &01 ; pixel_was_added_for_second_sparkler # Zero if no pixel added &1a4e f0 05 BEQ &1a55 ; skip_removing_pixel_for_second_sparkler &1a50 a4 c9 LDY &c9 ; sparklers_first_line_start_y + 8 &1a52 20 e8 14 JSR &14e8 ; set_pixel ; skip_removing_pixel_for_second_sparkler &1a55 a9 78 LDA #&78 ; COLOUR_2_OFFSET &1a57 8d 0e 15 STA &150e ; pixel_value_offset &1a5a a5 86 LDA &86 ; game_state &1a5c c9 3f CMP #&3f ; PLAYER_WON_BY_SPLITTING &1a5e d0 0f BNE &1a6f ; didn't_split_single_sparkler &1a60 24 88 BIT &88 ; two_sparklers # Negative if two sparklers &1a62 30 0b BMI &1a6f ; didn't_split_single_sparkler &1a64 a2 fe LDX #&fe ; PLAYER_KILLED_BY_SPARKLER # If only one sparkler, kill the player for splitting it &1a66 86 86 STX &86 ; game_state &1a68 e8 INX &1a69 86 84 STX &84 ; player_is_drawing # Set to negative to unplot line on death &1a6b 8a TXA # Negative to plot sprites &1a6c 4c e4 13 JMP &13e4 ; plot_or_unplot_sprites ; didn't_split_single_sparkler &1a6f a9 ff LDA #&ff # Negative to plot sprites &1a71 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &1a74 a5 64 LDA &64 ; demo_mode # Zero if game &1a76 f0 01 BEQ &1a79 ; add_fill_bonus &1a78 60 RTS ; add_fill_bonus &1a79 85 70 STA &70 ; pixels_scored_low &1a7b 85 71 STA &71 ; pixels_scored_high &1a7d a9 03 LDA #&03 # Score 3 points for each % filled fast < 75% &1a7f 24 63 BIT &63 ; slow_fill &1a81 10 02 BPL &1a85 ; not_slow &1a83 a9 30 LDA #&30 # Score 30 points for each % filled slow < 75% ; not_slow &1a85 85 77 STA &77 ; fill_bonus ; add_fill_bonus_loop &1a87 18 CLC &1a88 a5 70 LDA &70 ; pixels_scored_low &1a8a 69 58 ADC #&58 # 600 pixels = 1% &1a8c 85 70 STA &70 ; pixels_scored_low &1a8e a5 71 LDA &71 ; pixels_scored_high &1a90 69 02 ADC #&02 &1a92 85 71 STA &71 ; pixels_scored_high &1a94 c5 6a CMP &6a ; pixels_filled_high &1a96 b0 21 BCS &1ab9 ; write_filled_percentage_and_consider_if_game_won &1a98 f8 SED &1a99 a5 11 LDA &11 ; filled_bcd &1a9b 69 01 ADC #&01 &1a9d 85 11 STA &11 ; filled_bcd &1a9f c9 75 CMP #&75 &1aa1 d0 0e BNE &1ab1 ; add_fill_bonus_for_percent &1aa3 a9 7f LDA #&7f ; PLAYER_WON # Set to &7f to indicate more than 75% of screen filled &1aa5 85 86 STA &86 ; game_state &1aa7 a9 90 LDA #&90 # Score 90 points for each % filled fast >= 75% &1aa9 24 63 BIT &63 ; slow_fill &1aab 10 02 BPL &1aaf ; set_fill_bonus &1aad a9 99 LDA #&99 # Score 99 points for each % filled slow >= 75% ; set_fill_bonus &1aaf 85 77 STA &77 ; fill_bonus ; add_fill_bonus_for_percent &1ab1 a5 77 LDA &77 ; fill_bonus &1ab3 20 30 1c JSR &1c30 ; increase_and_update_score &1ab6 4c 87 1a JMP &1a87 ; add_fill_bonus_loop ; write_filled_percentage_and_consider_if_game_won &1ab9 a5 70 LDA &70 ; pixels_scored_low &1abb e9 58 SBC #&58 &1abd 85 70 STA &70 ; pixels_scored_low &1abf a5 71 LDA &71 ; pixels_scored_high &1ac1 e9 02 SBC #&02 &1ac3 85 71 STA &71 ; pixels_scored_high &1ac5 a5 69 LDA &69 ; pixels_filled_low &1ac7 e5 70 SBC &70 ; pixels_scored_low &1ac9 85 69 STA &69 ; pixels_filled_low &1acb a5 6a LDA &6a ; pixels_filled_high &1acd e5 71 SBC &71 ; pixels_scored_high &1acf 85 6a STA &6a ; pixels_filled_high &1ad1 a9 1f LDA #&1f # TAB(&23, &02) &1ad3 20 ee ff JSR &ffee ; OSWRCH &1ad6 a9 23 LDA #&23 &1ad8 20 ee ff JSR &ffee ; OSWRCH &1adb a9 02 LDA #&02 &1add 20 ee ff JSR &ffee ; OSWRCH &1ae0 a5 11 LDA &11 ; filled_bcd &1ae2 29 f0 AND #&f0 &1ae4 f0 06 BEQ &1aec ; skip_tens &1ae6 4a LSR A &1ae7 4a LSR A &1ae8 4a LSR A &1ae9 4a LSR A &1aea 09 10 ORA #&10 ; "0" - " " ; skip_tens &1aec 09 20 ORA #&20 ; " " &1aee 20 ee ff JSR &ffee ; OSWRCH # Write first digit of filled percentage &1af1 a5 11 LDA &11 ; filled_bcd &1af3 29 0f AND #&0f &1af5 09 30 ORA #&30 ; "0" &1af7 20 ee ff JSR &ffee ; OSWRCH # Write second digit of filled percentage &1afa a5 86 LDA &86 ; game_state &1afc d0 03 BNE &1b01 ; level_was_won &1afe 4c 22 1c JMP &1c22 ; play_sound_after_filling ; level_was_won &1b01 a9 15 LDA #&15 ; Flush selected buffer &1b03 a2 06 LDX #&06 ; Sound channel 2 &1b05 20 f4 ff JSR &fff4 ; OSBYTE &1b08 e8 INX ; &07 ; Sound channel 3 &1b09 20 f4 ff JSR &fff4 ; OSBYTE &1b0c a5 86 LDA &86 ; game_state &1b0e c9 3f CMP #&3f ; PLAYER_WON_BY_SPLITTING &1b10 f0 08 BEQ &1b1a ; level_was_won_by_splitting ; level_was_won_by_filling &1b12 a9 10 LDA #&10 ; CLG &1b14 20 ee ff JSR &ffee ; OSWRCH &1b17 4c ab 1b JMP &1bab ; add_time_bonus ; level_was_won_by_splitting &1b1a a9 ff LDA #&ff # Negative to plot sprites &1b1c 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &1b1f a9 7c LDA #&7c ; COLOUR_1_OFFSET # Convert unfilled line into filled line &1b21 8d 0e 15 STA &150e ; pixel_value_offset &1b24 a5 90 LDA &90 ; player_x &1b26 85 7b STA &7b ; path_start_x &1b28 a5 91 LDA &91 ; player_y &1b2a 85 7c STA &7c ; path_start_y ; backtrack_path_loop &1b2c a5 7b LDA &7b ; path_start_x &1b2e a4 7c LDY &7c ; path_start_y &1b30 88 DEY &1b31 20 b2 14 JSR &14b2 ; get_pixel &1b34 c9 10 CMP #&10 ; COLOUR_2_VALUE &1b36 d0 04 BNE &1b3c ; path_doesn't_continue_up ; path_continues_up &1b38 c6 7c DEC &7c ; path_start_y &1b3a d0 30 BNE &1b6c ; convert_pixel_and_continue_backtracking # Always branches ; path_doesn't_continue_up &1b3c a4 7b LDY &7b ; path_start_x &1b3e c8 INY &1b3f 98 TYA &1b40 a4 7c LDY &7c ; path_start_y &1b42 20 b2 14 JSR &14b2 ; get_pixel &1b45 c9 10 CMP #&10 ; COLOUR_2_VALUE &1b47 d0 04 BNE &1b4d ; path_doesn't_continue_right ; path_continues_right &1b49 e6 7b INC &7b ; path_start_x &1b4b d0 1f BNE &1b6c ; convert_pixel_and_continue_backtracking # Always branches ; path_doesn't_continue_right &1b4d a4 7b LDY &7b ; path_start_x &1b4f 88 DEY &1b50 98 TYA &1b51 a4 7c LDY &7c ; path_start_y &1b53 20 b2 14 JSR &14b2 ; get_pixel &1b56 c9 10 CMP #&10 ; COLOUR_2_VALUE &1b58 d0 04 BNE &1b5e ; path_doesn't_continue_left ; path_continues_left &1b5a c6 7b DEC &7b ; path_start_x &1b5c d0 0e BNE &1b6c ; convert_pixel_and_continue_backtracking # Always branches ; path_doesn't_continue_left &1b5e a5 7b LDA &7b ; path_start_x &1b60 a4 7c LDY &7c ; path_start_y &1b62 c8 INY &1b63 20 b2 14 JSR &14b2 ; get_pixel &1b66 c9 10 CMP #&10 ; COLOUR_2_VALUE &1b68 d0 0c BNE &1b76 ; finished_backtracking_path ; path_continues_down &1b6a e6 7c INC &7c ; path_start_y ; convert_pixel_and_continue_backtracking &1b6c a5 7b LDA &7b ; path_start_x &1b6e a4 7c LDY &7c ; path_start_y &1b70 20 e8 14 JSR &14e8 ; set_pixel # Convert pixel of path &1b73 4c 2c 1b JMP &1b2c ; backtrack_path_loop ; finished_backtracking_path &1b76 a9 78 LDA #&78 ; COLOUR_2_OFFSET &1b78 8d 0e 15 STA &150e ; pixel_value_offset &1b7b a9 ff LDA #&ff # Negative to plot sprites &1b7d 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &1b80 a9 07 LDA #&07 ; Generate a sound (SOUND) &1b82 a2 b0 LDX #&b0 ; &09b0 = sound_1 &1b84 a0 09 LDY #&09 &1b86 20 f1 ff JSR &fff1 ; OSWORD # Play sound for split bonus (not demo) &1b89 a2 20 LDX #&20 ; " " # Score 100 points for fast split &1b8b a0 31 LDY #&31 ; "1" &1b8d a9 01 LDA #&01 ; 100 &1b8f f8 SED &1b90 18 CLC &1b91 24 63 BIT &63 ; slow_fill # Negative if slow fill &1b93 10 06 BPL &1b9b ; add_split_bonus &1b95 a2 31 LDX #&31 ; "1" # Score 1000 points for slow split &1b97 a0 30 LDY #&30 ; "0" &1b99 a9 10 LDA #&10 ; 1000 ; add_split_bonus &1b9b 8e 12 0b STX &0b12 ; split_bonus_string + &f &1b9e 8c 13 0b STY &0b13 ; split_bonus_string + &10 &1ba1 65 13 ADC &13 ; score + 1 &1ba3 20 3a 1c JSR &1c3a ; update_score_from_hundreds &1ba6 a9 ff LDA #&ff # Negative to write "SPLIT-BONUS" and invert screen &1ba8 20 80 08 JSR &0880 ; wipe_screen ; add_time_bonus &1bab a9 ff LDA #&ff &1bad 8d bc 09 STA &09bc ; sound_2 + 4 (pitch low) ; add_time_bonus_loop &1bb0 ee bc 09 INC &09bc ; sound_2 + 4 (pitch low) &1bb3 a9 07 LDA #&07 ; Generate a sound (SOUND) &1bb5 a2 b8 LDX #&b8 ; &09b8 = sound_2 &1bb7 a0 09 LDY #&09 &1bb9 20 f1 ff JSR &fff1 ; OSWORD # Play sound for time bonus (not demo) &1bbc a9 03 LDA #&03 # Score 3 points for every pixel of time remaining &1bbe 20 30 1c JSR &1c30 ; increase_and_update_score &1bc1 a5 78 LDA &78 ; game_time &1bc3 f0 1a BEQ &1bdf ; done_bonus &1bc5 29 07 AND #&07 &1bc7 a8 TAY &1bc8 d0 0d BNE &1bd7 ; not_group &1bca 18 CLC &1bcb a5 75 LDA &75 ; time_bar_screen_address_low &1bcd 69 80 ADC #&80 &1bcf 85 75 STA &75 ; time_bar_screen_address_low &1bd1 a5 76 LDA &76 ; time_bar_screen_address_high &1bd3 69 02 ADC #&02 &1bd5 85 76 STA &76 ; time_bar_screen_address_high ; not_group &1bd7 a9 00 LDA #&00 &1bd9 91 75 STA (&75),Y ; time_bar_screen_address &1bdb e6 78 INC &78 ; game_time &1bdd d0 d1 BNE &1bb0 ; add_time_bonus_loop ; done_bonus &1bdf a9 ff LDA #&ff # Negative to plot sprites &1be1 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &1be4 20 ab 1c JSR &1cab ; gain_life_after_clearing_level # Restore life used by playing level &1be7 a2 02 LDX #&02 &1be9 20 f5 20 JSR &20f5 ; animate_sparklers_at_end_of_level &1bec a9 00 LDA #&00 # Zero to wipe screen with black &1bee 20 80 08 JSR &0880 ; wipe_screen &1bf1 a9 7f LDA #&7f ; PLAYER_WON &1bf3 85 86 STA &86 ; game_state &1bf5 a2 07 LDX #&07 ; write_zero_filled_and_level_tab_loop # Write filled percentage of zero on screen &1bf7 bd f8 0d LDA &0df8,X ; zero_filled_and_level_tab_string # and tab to level number &1bfa 20 ee ff JSR &ffee ; OSWRCH &1bfd ca DEX &1bfe 10 f7 BPL &1bf7 ; write_zero_filled_and_level_tab_loop &1c00 e6 1c INC &1c ; level_as_offset &1c02 f8 SED &1c03 a5 15 LDA &15 ; level_as_number &1c05 69 01 ADC #&01 &1c07 85 15 STA &15 ; level_as_number &1c09 d8 CLD &1c0a 29 f0 AND #&f0 &1c0c f0 06 BEQ &1c14 ; skip_tens &1c0e 4a LSR A &1c0f 4a LSR A &1c10 4a LSR A &1c11 4a LSR A &1c12 09 10 ORA #&10 ; "0" - " " ; skip_tens &1c14 09 20 ORA #&20 ; " " &1c16 20 ee ff JSR &ffee ; OSWRCH # Write first digit of level number &1c19 a5 15 LDA &15 ; level_as_number &1c1b 29 0f AND #&0f &1c1d 09 30 ORA #&30 &1c1f 4c ee ff JMP &ffee ; OSWRCH # Write second digit of level number ; play_sound_after_filling &1c22 a2 ff LDX #&ff # &ff to cause immediate timer event, enable events &1c24 20 39 24 JSR &2439 ; set_timer_and_enable_or_disable_events &1c27 a9 07 LDA #&07 ; Generate a sound (SOUND) &1c29 a2 f8 LDX #&f8 ; &09f8 = sound_10 &1c2b a0 09 LDY #&09 &1c2d 4c f1 ff JMP &fff1 ; OSWORD # Play sound for filling (not demo) ; increase_and_update_score &1c30 f8 SED &1c31 18 CLC &1c32 65 12 ADC &12 ; score_as_bcd &1c34 85 12 STA &12 ; score_as_bcd &1c36 a5 13 LDA &13 ; score + 1 &1c38 69 00 ADC #&00 ; update_score_from_hundreds &1c3a 08 PHP &1c3b 85 13 STA &13 ; score + 1 &1c3d a5 14 LDA &14 ; score + 2 &1c3f 69 00 ADC #&00 &1c41 85 14 STA &14 ; score + 2 &1c43 d8 CLD &1c44 a9 1f LDA #&1f # TAB(&22, &07) &1c46 20 ee ff JSR &ffee ; OSWRCH &1c49 a9 22 LDA #&22 &1c4b 20 ee ff JSR &ffee ; OSWRCH &1c4e a9 07 LDA #&07 &1c50 20 ee ff JSR &ffee ; OSWRCH &1c53 a0 00 LDY #&00 # Set to zero to use leading spaces &1c55 84 73 STY &73 ; leading_space &1c57 a2 02 LDX #&02 ; convert_score_to_digits_loop &1c59 b5 12 LDA &12,X ; score_as_bcd &1c5b 29 f0 AND #&f0 &1c5d d0 08 BNE &1c67 ; use_digit_for_tens &1c5f 24 73 BIT &73 ; leading_space # Zero if using leading spaces &1c61 30 04 BMI &1c67 ; use_digit_for_tens &1c63 a9 20 LDA #&20 ; " " &1c65 d0 08 BNE &1c6f ; set_character_for_tens # Always branches ; use_digit_for_tens &1c67 c6 73 DEC &73 ; leading_space # Set to negative to stop using leading spaces &1c69 4a LSR A &1c6a 4a LSR A &1c6b 4a LSR A &1c6c 4a LSR A &1c6d 09 30 ORA #&30 ; "0" ; set_character_for_tens &1c6f 99 16 00 STA &0016,Y ; score_as_digits &1c72 20 ee ff JSR &ffee ; OSWRCH &1c75 c8 INY &1c76 b5 12 LDA &12,X ; score_as_bcd &1c78 29 0f AND #&0f &1c7a d0 08 BNE &1c84 ; use_digit_for_ones &1c7c 24 73 BIT &73 ; leading_space # Zero if using leading spaces &1c7e 30 04 BMI &1c84 ; use_digit_for_ones &1c80 a9 20 LDA #&20 ; " " &1c82 d0 04 BNE &1c88 ; set_character_for_ones # Always branches ; use_digit_for_ones &1c84 c6 73 DEC &73 ; leading_space # Set to negative to stop using leading spaces &1c86 09 30 ORA #&30 ; "0" ; set_character_for_ones &1c88 99 16 00 STA &0016,Y ; score_as_digits &1c8b 20 ee ff JSR &ffee ; OSWRCH &1c8e c8 INY &1c8f ca DEX &1c90 10 c7 BPL &1c59 ; convert_score_to_digits_loop &1c92 28 PLP &1c93 d8 CLD &1c94 b0 01 BCS &1c97 ; gain_life &1c96 60 RTS ; gain_life &1c97 a9 07 LDA #&07 ; Generate a sound (SOUND) &1c99 a2 f0 LDX #&f0 ; &09f0 = sound_9 &1c9b a0 09 LDY #&09 &1c9d 20 f1 ff JSR &fff1 ; OSWORD # Play sound for extra life (not demo) &1ca0 a5 11 LDA &11 ; filled_bcd &1ca2 c9 75 CMP #&75 &1ca4 b0 05 BCS &1cab ; skip_clearing_screen &1ca6 a9 10 LDA #&10 ; CLG &1ca8 20 ee ff JSR &ffee ; OSWRCH ; skip_clearing_screen ; gain_life_after_clearing_level &1cab e6 10 INC &10 ; player_lives &1cad a6 10 LDX &10 ; player_lives &1caf e0 07 CPX #&07 &1cb1 b0 e4 BCS &1c97 ; gain_life # Bug: removes all but last life after 7 lives &1cb3 a9 1f LDA #&1f # TAB(&21 + lives, &16) &1cb5 20 ee ff JSR &ffee ; OSWRCH &1cb8 a9 21 LDA #&21 &1cba 18 CLC &1cbb 65 10 ADC &10 ; player_lives &1cbd 20 ee ff JSR &ffee ; OSWRCH &1cc0 a9 16 LDA #&16 &1cc2 20 ee ff JSR &ffee ; OSWRCH &1cc5 a9 e1 LDA #&e1 # Plot extra life &1cc7 4c ee ff JMP &ffee ; OSWRCH ; draw_line # Called with X = line_x, Y = line_y &1cca a9 00 LDA #&00 &1ccc 85 5a STA &5a ; delta_signs &1cce a5 50 LDA &50 ; line_start_x &1cd0 86 56 STX &56 ; x_delta &1cd2 38 SEC &1cd3 e5 56 SBC &56 ; x_delta &1cd5 b0 04 BCS &1cdb ; skip_inversion_x &1cd7 49 ff EOR #&ff &1cd9 69 01 ADC #&01 ; skip_inversion_x &1cdb 26 5a ROL &5a ; delta_signs &1cdd 85 56 STA &56 ; x_delta &1cdf a5 51 LDA &51 ; line_start_y &1ce1 84 57 STY &57 ; y_delta &1ce3 38 SEC &1ce4 e5 57 SBC &57 ; y_delta &1ce6 b0 04 BCS &1cec ; skip_inversion_y &1ce8 49 ff EOR #&ff &1cea 69 01 ADC #&01 ; skip_inversion_y &1cec 26 5a ROL &5a ; delta_signs &1cee 85 57 STA &57 ; y_delta &1cf0 05 56 ORA &56 ; x_delta &1cf2 d0 01 BNE &1cf5 ; not_null_line &1cf4 60 RTS ; not_null_line &1cf5 a6 5a LDX &5a ; delta_signs &1cf7 bd 80 0b LDA &0b80,X ; line_x_directions_table # If the line is shallow (i.e. x_delta > y_delta), &1cfa 85 52 STA &52 ; line_x_increment_either # then line_x_increment_either = +/- 1, both = +/- 1 &1cfc 85 54 STA &54 ; line_x_increment_both # line_y_increment_either = 0, both = +/- 1 &1cfe bd 84 0b LDA &0b84,X ; line_y_directions_table &1d01 85 55 STA &55 ; line_y_increment_both &1d03 a9 00 LDA #&00 &1d05 85 53 STA &53 ; line_y_increment_either &1d07 a4 57 LDY &57 ; y_delta &1d09 c4 56 CPY &56 ; x_delta &1d0b 90 0d BCC &1d1a ; line_is_shallow ; line_is_steep &1d0d 85 52 STA &52 ; line_x_increment_either # If the line is steep (i.e. x_delta <= y_delta) &1d0f bd 84 0b LDA &0b84,X ; line_y_directions_table # then line_x_increment_either = 0, both = +/- 1 &1d12 85 53 STA &53 ; line_y_increment_either # line_y_increment_either = +/- 1, both = +/- 1 &1d14 a5 56 LDA &56 ; x_delta &1d16 84 56 STY &56 ; x_delta # Swap x_delta and y_delta &1d18 85 57 STA &57 ; y_delta ; line_is_shallow &1d1a a5 56 LDA &56 ; x_delta &1d1c c5 8c CMP &8c ; maximum_line_length &1d1e 90 02 BCC &1d22 ; not_clipped &1d20 a5 8c LDA &8c ; maximum_line_length ; not_clipped &1d22 85 5a STA &5a ; line_length # line_length is the largest of x and y deltas, clipped &1d24 4a LSR A &1d25 18 CLC &1d26 65 57 ADC &57 ; y_delta &1d28 85 58 STA &58 ; line_substep_low &1d2a a9 00 LDA #&00 &1d2c 2a ROL A &1d2d 85 59 STA &59 ; line_substep_high &1d2f a5 56 LDA &56 ; x_delta &1d31 38 SEC &1d32 e5 57 SBC &57 ; y_delta &1d34 85 5b STA &5b ; line_substep_delta &1d36 a5 51 LDA &51 ; line_start_y # Calculate screen address of start of line &1d38 29 f8 AND #&f8 &1d3a 4a LSR A &1d3b 4a LSR A &1d3c aa TAX &1d3d a5 50 LDA &50 ; line_start_x &1d3f 29 fc AND #&fc &1d41 0a ASL A &1d42 08 PHP &1d43 85 4e STA &4e ; line_start_x_byte_offset &1d45 18 CLC &1d46 bd 82 03 LDA &0382,X ; row_multiplication_table + 1 &1d49 69 00 ADC #&00 # actually ADC row_offset &1d4b 65 4e ADC &4e ; line_start_x_byte_offset &1d4d 85 4e STA &4e ; line_screen_address_low &1d4f bd 81 03 LDA &0381,X ; row_multiplication_table &1d52 69 30 ADC #&30 &1d54 28 PLP &1d55 69 00 ADC #&00 &1d57 85 4f STA &4f ; line_screen_address_high &1d59 a5 50 LDA &50 ; line_start_x &1d5b 29 03 AND #&03 &1d5d aa TAX &1d5e a5 51 LDA &51 ; line_start_y &1d60 29 07 AND #&07 &1d62 a8 TAY ; draw_line_loop &1d63 a5 50 LDA &50 ; line_start_x &1d65 85 5c STA &5c ; line_last_pixel_x &1d67 a5 51 LDA &51 ; line_start_y &1d69 85 5d STA &5d ; line_last_pixel_y &1d6b a5 59 LDA &59 ; line_substep_high &1d6d f0 06 BEQ &1d75 ; consider_moving_along_line_in_either_or_both_x_and_y &1d6f a5 58 LDA &58 ; line_substep_low &1d71 38 SEC &1d72 4c f6 1d JMP &1df6 ; move_along_line_in_both_x_and_y ; consider_moving_along_line_in_either_or_both_x_and_y &1d75 a5 58 LDA &58 ; line_substep_low &1d77 c5 56 CMP &56 ; x_delta &1d79 b0 7b BCS &1df6 ; move_along_line_in_both_x_and_y &1d7b 65 57 ADC &57 ; y_delta &1d7d 85 58 STA &58 ; line_substep_low &1d7f 26 59 ROL &59 ; line_substep_high ; move_along_line_in_either_x_or_y &1d81 a5 52 LDA &52 ; line_x_increment_either &1d83 f0 29 BEQ &1dae ; move_up_or_down_either &1d85 30 15 BMI &1d9c ; move_left_a_pixel_either ; move_right_a_pixel_either &1d87 e6 50 INC &50 ; line_start_x &1d89 e8 INX &1d8a e0 04 CPX #&04 &1d8c 90 20 BCC &1dae ; move_up_or_down_either &1d8e a2 00 LDX #&00 &1d90 a5 4e LDA &4e ; line_screen_address_low &1d92 69 07 ADC #&07 &1d94 85 4e STA &4e ; line_screen_address_low &1d96 90 16 BCC &1dae ; move_up_or_down_either &1d98 e6 4f INC &4f ; line_screen_address_high &1d9a d0 12 BNE &1dae ; move_up_or_down_either # Always branches ; move_left_a_pixel_either &1d9c c6 50 DEC &50 ; line_start_x &1d9e ca DEX &1d9f 10 0d BPL &1dae ; move_up_or_down_either &1da1 a2 03 LDX #&03 &1da3 38 SEC &1da4 a5 4e LDA &4e ; line_screen_address_low &1da6 e9 08 SBC #&08 &1da8 85 4e STA &4e ; line_screen_address_low &1daa b0 02 BCS &1dae ; move_up_or_down_either &1dac c6 4f DEC &4f ; line_screen_address_high ; move_up_or_down_either &1dae a5 53 LDA &53 ; line_y_increment_either &1db0 f0 2d BEQ &1ddf ; consider_plotting_pixel_of_line &1db2 30 17 BMI &1dcb ; move_up_a_pixel_either ; move_down_a_pixel_either &1db4 e6 51 INC &51 ; line_start_y &1db6 c8 INY &1db7 c0 08 CPY #&08 &1db9 90 24 BCC &1ddf ; consider_plotting_pixel_of_line &1dbb a0 00 LDY #&00 &1dbd a5 4e LDA &4e ; line_screen_address_low &1dbf 69 7f ADC #&7f &1dc1 85 4e STA &4e ; line_screen_address_low &1dc3 a5 4f LDA &4f ; line_screen_address_high &1dc5 69 02 ADC #&02 &1dc7 85 4f STA &4f ; line_screen_address_high &1dc9 90 14 BCC &1ddf ; consider_plotting_pixel_of_line # Always branches ; move_up_a_pixel_either &1dcb c6 51 DEC &51 ; line_start_y &1dcd 88 DEY &1dce 10 0f BPL &1ddf ; consider_plotting_pixel_of_line &1dd0 a0 07 LDY #&07 &1dd2 38 SEC &1dd3 a5 4e LDA &4e ; line_screen_address_low &1dd5 e9 80 SBC #&80 &1dd7 85 4e STA &4e ; line_screen_address_low &1dd9 a5 4f LDA &4f ; line_screen_address_high &1ddb e9 02 SBC #&02 &1ddd 85 4f STA &4f ; line_screen_address_high ; skip_up_or_down ; consider_plotting_pixel_of_line &1ddf b1 4e LDA (&4e),Y ; line_screen_address &1de1 3d 78 0b AND &0b78,X ; colour_2_pixel_values &1de4 f0 01 BEQ &1de7 ; continue_drawing_line # If offset is 1, continue line after hitting something # actually BEQ &1de5 + line_continuation_branch_offset # also BEQ &1dee ; continue_without_drawing # If 8, don't continue line after hitting something ; consider_stopping_line &1de6 60 RTS # Leave with non-zero if line hit something # also NOP ; continue_drawing_line &1de7 b1 4e LDA (&4e),Y ; line_screen_address &1de9 5d 7c 0b EOR &0b7c,X ; colour_1_pixel_values # actually EOR &0b00 + line_colour_offset, X &1dec 91 4e STA (&4e),Y ; line_screen_address ; continue_without_drawing &1dee c6 5a DEC &5a ; line_length &1df0 f0 03 BEQ &1df5 ; leave # Leave with zero if line was completely drawn &1df2 4c 63 1d JMP &1d63 ; draw_line_loop ; leave &1df5 60 RTS ; move_along_line_in_both_x_and_y &1df6 e5 5b SBC &5b ; line_substep_delta &1df8 85 58 STA &58 ; line_substep_low &1dfa b0 02 BCS &1dfe ; skip_underflow &1dfc c6 59 DEC &59 ; line_substep_high ; skip_underflow &1dfe a5 54 LDA &54 ; line_x_increment_both &1e00 f0 29 BEQ &1e2b ; skip_left_or_right &1e02 30 15 BMI &1e19 ; move_left_a_pixel_both ; move_right_a_pixel_both &1e04 e6 50 INC &50 ; line_start_x &1e06 e8 INX &1e07 e0 04 CPX #&04 &1e09 90 20 BCC &1e2b ; skip_left_or_right &1e0b a2 00 LDX #&00 &1e0d a5 4e LDA &4e ; line_screen_address_low &1e0f 69 07 ADC #&07 &1e11 85 4e STA &4e ; line_screen_address_low &1e13 90 16 BCC &1e2b ; move_up_or_down_both &1e15 e6 4f INC &4f ; line_screen_address_high &1e17 d0 12 BNE &1e2b ; move_up_or_down_both # Always branches ; move_left_a_pixel_both &1e19 c6 50 DEC &50 ; line_start_x &1e1b ca DEX &1e1c 10 0d BPL &1e2b ; skip_left_or_right &1e1e a2 03 LDX #&03 &1e20 38 SEC &1e21 a5 4e LDA &4e ; line_screen_address_low &1e23 e9 08 SBC #&08 &1e25 85 4e STA &4e ; line_screen_address_low &1e27 b0 02 BCS &1e2b ; move_up_or_down_both &1e29 c6 4f DEC &4f ; line_screen_address_high ; move_up_or_down_both &1e2b a5 55 LDA &55 ; line_y_increment_both &1e2d f0 b0 BEQ &1ddf ; consider_plotting_pixel_of_line &1e2f 30 17 BMI &1e48 ; move_up_a_pixel_both ; move_down_a_pixel_both &1e31 e6 51 INC &51 ; line_start_y &1e33 c8 INY &1e34 c0 08 CPY #&08 &1e36 90 a7 BCC &1ddf ; consider_plotting_pixel_of_line &1e38 a0 00 LDY #&00 &1e3a a5 4e LDA &4e ; line_screen_address_low &1e3c 69 7f ADC #&7f &1e3e 85 4e STA &4e ; line_screen_address_low &1e40 a5 4f LDA &4f ; line_screen_address_high &1e42 69 02 ADC #&02 &1e44 85 4f STA &4f ; line_screen_address_high &1e46 90 97 BCC &1ddf ; consider_plotting_pixel_of_line # Always branches ; move_up_a_pixel_both &1e48 c6 51 DEC &51 ; line_start_y &1e4a 88 DEY &1e4b 10 92 BPL &1ddf ; consider_plotting_pixel_of_line &1e4d a0 07 LDY #&07 &1e4f 38 SEC &1e50 a5 4e LDA &4e ; line_screen_address_low &1e52 e9 80 SBC #&80 &1e54 85 4e STA &4e ; line_screen_address_low &1e56 a5 4f LDA &4f ; line_screen_address_high &1e58 e9 02 SBC #&02 &1e5a 85 4f STA &4f ; line_screen_address_high &1e5c b0 81 BCS &1ddf ; consider_plotting_pixel_of_line # Always branches ; update_scrolltext_after_resetting_timer &1e5e a9 18 LDA #&18 &1e60 8d 6f 0b STA &0b6f ; timer_ready # Set to positive to wait for next timer event &1e63 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1e66 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB ; update_scrolltext &1e69 a6 2c LDX &2c ; scrolltext_pixel &1e6b e8 INX &1e6c 86 2c STX &2c ; scrolltext_pixel &1e6e e0 08 CPX #&08 &1e70 d0 1f BNE &1e91 ; not_new_character &1e72 a2 00 LDX #&00 &1e74 86 2c STX &2c ; scrolltext_pixel &1e76 a6 2d LDX &2d ; scrolltext_offset &1e78 bd 00 07 LDA &0700,X ; game_scrolltext &1e7b 24 64 BIT &64 ; demo_mode # Negative if demo mode &1e7d 10 03 BPL &1e82 ; not_demo &1e7f bd 00 04 LDA &0400,X ; demo_scrolltext ; not_demo &1e82 8d ff 0b STA &0bff ; character_block &1e85 e8 INX &1e86 86 2d STX &2d ; scrolltext_offset &1e88 a9 0a LDA #&0a ; Read character definition &1e8a a2 ff LDX #&ff ; &0bff = character_block &1e8c a0 0b LDY #&0b &1e8e 20 f1 ff JSR &fff1 ; OSWORD ; not_new_character &1e91 a9 20 LDA #&20 ; &7820 = screen_memory + &4820 # Lower group of scrolltext &1e93 a0 78 LDY #&78 &1e95 a2 07 LDX #&07 # Use bottom four rows of character ; update_scrolltext_group_loop &1e97 85 70 STA &70 ; screen_address_low &1e99 84 71 STY &71 ; screen_address_high &1e9b a0 04 LDY #&04 &1e9d 78 SEI ; push_character_pixels_onto_stack_loop &1e9e 1e 00 0c ASL &0c00,X ; character_block + 1 # Rotate left pixel of character into carry &1ea1 08 PHP # Push processor status &1ea2 ca DEX &1ea3 88 DEY &1ea4 d0 f8 BNE &1e9e ; push_character_pixels_onto_stack_loop &1ea6 a0 5f LDY #&5f # Scrolltext is six characters wide ; end_of_group &1ea8 68 PLA # Pull processor status once for each pushed pixel &1ea9 68 PLA &1eaa 68 PLA &1eab 68 PLA &1eac a9 04 LDA #&04 &1eae 85 7e STA &7e ; rows &1eb0 98 TYA &1eb1 30 1c BMI &1ecf ; consider_next_group ; update_scrolltext_row_loop &1eb3 ba TSX &1eb4 bd 00 01 LDA &0100,X ; stack # Using values previously pushed and pulled &1eb7 29 01 AND #&01 # Get carry &1eb9 aa TAX &1eba b1 70 LDA (&70),Y ; screen_address &1ebc 0a ASL A # Rotate left pixel of screen byte into carry &1ebd 08 PHP # Push processor status onto stack &1ebe 29 ee AND #&ee ; 3330 &1ec0 1d fe 05 ORA &05fe,X ; colour_0_or_3_pixel_values # Convert right pixel depending on carry &1ec3 91 70 STA (&70),Y ; screen_address &1ec5 88 DEY # Move up a row &1ec6 91 70 STA (&70),Y ; screen_address &1ec8 88 DEY # Move up a row &1ec9 c6 7e DEC &7e ; rows &1ecb d0 e6 BNE &1eb3 ; update_scrolltext_row_loop &1ecd f0 d9 BEQ &1ea8 ; end_of_group # Always branches ; consider_next_group &1ecf 58 CLI &1ed0 a5 70 LDA &70 ; screen_address_low &1ed2 c9 a0 CMP #&a0 &1ed4 f0 08 BEQ &1ede ; consider_updating_sparklers &1ed6 a9 a0 LDA #&a0 ; &75a0 = screen_memory + &35a0 # Upper group of scrolltext &1ed8 a0 75 LDY #&75 &1eda a2 03 LDX #&03 # Use top four rows of character &1edc d0 b9 BNE &1e97 ; update_scrolltext_group_loop # Always branches ; consider_updating_sparklers &1ede ea NOP # also RTS # Leave if not updating sparklers ; wait_for_timer &1edf 2c 6f 0b BIT &0b6f ; timer_ready # Negative after timer event &1ee2 10 fb BPL &1edf ; wait_for_timer &1ee4 a9 00 LDA #&00 # Set to zero to indicate sparklers don't need updating &1ee6 85 27 STA &27 ; sparklers_need_updating &1ee8 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites # Positive to unplot sprites &1eeb a5 8f LDA &8f ; level_speed &1eed 8d 6f 0b STA &0b6f ; timer_ready # Set to positive to wait for next timer event &1ef0 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &1ef3 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB ; update_sparklers &1ef6 a2 00 LDX #&00 &1ef8 86 4a STX &4a ; sparkler_offset &1efa a4 5e LDY &5e ; sparklers_line_to_use &1efc 84 ee STY &ee ; previous_sparklers_line_to_use ; update_sparklers_loop &1efe a5 80 LDA &80 ; frame_count &1f00 4a LSR A &1f01 b0 30 BCS &1f33 ; frame_one_or_three ; frame_zero_or_two &1f03 4a LSR A &1f04 90 03 BCC &1f09 ; frame_zero ; frame_two # In frame 2 % 4, do nothing &1f06 4c dd 20 JMP &20dd ; finished_plotting_or_unplotting_sparklers ; frame_zero # In frame 0 % 4, unplot oldest line of sparkler &1f09 b9 00 01 LDA &0100,Y ; sparkler_lines_start_x &1f0c 85 50 STA &50 ; line_start_x &1f0e b9 10 01 LDA &0110,Y ; sparkler_lines_start_y &1f11 85 51 STA &51 ; line_start_y &1f13 b9 20 01 LDA &0120,Y ; sparkler_lines_end_x &1f16 aa TAX &1f17 b9 30 01 LDA &0130,Y ; sparkler_lines_end_y &1f1a a8 TAY &1f1b 20 ca 1c JSR &1cca ; draw_line # Returns zero if line was completely drawn &1f1e f0 10 BEQ &1f30 ; to_consider_next_sparkler ; unplot_line_loop &1f20 b1 4e LDA (&4e),Y ; line_screen_address &1f22 3d 7c 0b AND &0b7c,X ; colour_1_pixel_values &1f25 d0 09 BNE &1f30 ; to_consider_next_sparkler # Branches if sparkler didn't hit unfilled line &1f27 a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER # Set to &fe to indicate sparkler hit unfilled line &1f29 85 86 STA &86 ; game_state &1f2b 20 e7 1d JSR &1de7 ; continue_drawing_line # Returns non-zero if line wasn't completely drawn &1f2e d0 f0 BNE &1f20 ; unplot_line_loop ; to_consider_next_sparkler &1f30 4c c7 20 JMP &20c7 ; consider_next_sparkler ; frame_one_or_three &1f33 4a LSR A &1f34 b0 03 BCS &1f39 ; frame_three ; to_frame_one &1f36 4c 53 20 JMP &2053 ; frame_one ; frame_three # In frame 3 % 4, update velocities and coordinates &1f39 b5 c0 LDA &c0,X ; sparklers_first_line_start_x &1f3b 85 50 STA &50 ; line_start_x &1f3d b5 c1 LDA &c1,X ; sparklers_first_line_start_y &1f3f 85 51 STA &51 ; line_start_y &1f41 8a TXA # Zero if first sparkler &1f42 d0 08 BNE &1f4c ; use_same_line &1f44 c6 5e DEC &5e ; sparklers_line_to_use &1f46 10 04 BPL &1f4c ; skip_wraparound &1f48 a9 07 LDA #&07 &1f4a 85 5e STA &5e ; sparklers_line_to_use ; skip_wraparound ; use_same_line &1f4c ad 44 fe LDA &fe44 ; System VIA timer 1 counter LSB &1f4f 45 be EOR &be ; rnd_state + 6 &1f51 c9 19 CMP #&19 &1f53 a4 8e LDY &8e ; sparkler_random_velocity_mask &1f55 8a TXA &1f56 d0 10 BNE &1f68 ; consider_randomising_second_sparkler ; consider_randomising_first_sparkler &1f58 24 5f BIT &5f ; sparkler_stability_flags &1f5a 30 72 BMI &1fce ; apply_sparkler_velocities # Don't randomise if FIRST_SPARKLER_IS_STABLE is set &1f5c b0 18 BCS &1f76 ; randomise_velocities_using_mask # Use sparkler_random_velocity_mask 25 times out of 255 &1f5e a4 8d LDY &8d ; sparkler_boundary_velocity_mask # Otherwise use sparkler_boundary_velocity_mask &1f60 a5 5f LDA &5f ; sparkler_stability_flags &1f62 09 80 ORA #&80 ; FIRST_SPARKLER_IS_STABLE &1f64 85 5f STA &5f ; sparkler_stability_flags &1f66 d0 0e BNE &1f76 ; randomise_velocities_using_mask # Always branches ; consider_randomising_second_sparkler &1f68 24 5f BIT &5f ; sparkler_stability_flags &1f6a 70 62 BVS &1fce ; apply_sparkler_velocities # Don't randomise if SECOND_SPARKLER_IS_STABLE is set &1f6c b0 08 BCS &1f76 ; randomise_velocities_using_mask # Use sparkler_random_velocity_mask 25 times out of 255 &1f6e a4 8d LDY &8d ; sparkler_boundary_velocity_mask # Otherwise use sparkler_boundary_velocity_mask &1f70 a5 5f LDA &5f ; sparkler_stability_flags &1f72 09 40 ORA #&40 ; SECOND_SPARKLER_IS_STABLE &1f74 85 5f STA &5f ; sparkler_stability_flags ; randomise_velocities_using_mask &1f76 8c a8 1f STY &1fa8 ; velocity_mask &1f79 a5 4a LDA &4a ; sparkler_offset &1f7b 18 CLC &1f7c 69 04 ADC #&04 # Use sparkler_velocities + &0 to &3 for first sparkler &1f7e aa TAX # + &8 to &b for second sparkler ; randomise_velocities_loop &1f7f ca DEX &1f80 a0 08 LDY #&08 ; shuffle_prnd_loop &1f82 18 CLC &1f83 a5 be LDA &be ; rnd_state + 6 &1f85 10 13 BPL &1f9a ; skip_eor &1f87 a5 bb LDA &bb ; rnd_state + 3 &1f89 45 b8 EOR &b8 ; rnd_state &1f8b 85 bb STA &bb ; rnd_state + 3 &1f8d a5 bc LDA &bc ; rnd_state + 4 &1f8f 45 b9 EOR &b9 ; rnd_state + 1 &1f91 85 bc STA &bc ; rnd_state + 4 &1f93 a5 bd LDA &bd ; rnd_state + 5 &1f95 45 ba EOR &ba ; rnd_state + 2 &1f97 85 bd STA &bd ; rnd_state + 5 &1f99 38 SEC ; skip_eor &1f9a 26 bb ROL &bb ; rnd_state + 3 &1f9c 26 bc ROL &bc ; rnd_state + 4 &1f9e 26 bd ROL &bd ; rnd_state + 5 &1fa0 26 be ROL &be ; rnd_state + 6 &1fa2 88 DEY &1fa3 d0 dd BNE &1f82 ; shuffle_rnd_state_loop &1fa5 a5 be LDA &be ; rnd_state + 6 &1fa7 29 00 AND #&00 # actually AND velocity_mask &1fa9 09 02 ORA #&02 # Ensure sparkler keeps moving &1fab 95 c4 STA &c4,X ; sparkler_velocities &1fad e4 4a CPX &4a ; sparkler_offset &1faf d0 ce BNE &1f7f ; randomise_velocities_loop &1fb1 8a TXA &1fb2 d0 06 BNE &1fba ; consider_matching_ends_of_first_sparkler ; consider_matching_ends_of_first_sparkler &1fb4 24 5f BIT &5f ; sparkler_stability_flags &1fb6 10 16 BPL &1fce ; apply_sparkler_velocities # Branch if FIRST_SPARKLER_IS_STABLE is clear &1fb8 30 04 BMI &1fbe ; match_start_and_end_directions # Always branches ; consider_matching_ends_of__second_sparkler &1fba 24 5f BIT &5f ; sparkler_stability_flags &1fbc 50 10 BVC &1fce ; probably_skip_randomising # Branch if SECOND_SPARKLER_IS_STABLE clear ; match_start_and_end_directions # If using sparkler_random_velocity_mask, &1fbe b5 c4 LDA &c4,X ; sparkler_velocities &1fc0 09 1f ORA #&1f # Use direction of start_x velocity &1fc2 35 c6 AND &c6,X ; sparkler_velocities + 2 # and speed of end_x velocity &1fc4 95 c6 STA &c6,X ; sparkler_velocities + 2 # for new end_x velocity &1fc6 b5 c5 LDA &c5,X ; sparkler_velocities + 1 &1fc8 09 1f ORA #&1f # Use direction of start_y velocity &1fca 35 c7 AND &c7,X ; sparkler_velocities + 3 # and speed of end_y velocity &1fcc 95 c7 STA &c7,X ; sparkler_velocities + 3 # for new end_y velocity ; apply_sparkler_velocities &1fce a9 04 LDA #&04 &1fd0 a8 TAY &1fd1 18 CLC &1fd2 65 4a ADC &4a ; sparkler_offset &1fd4 aa TAX ; apply_sparkler_velocities_loop &1fd5 ca DEX &1fd6 b5 c4 LDA &c4,X ; sparkler_velocities &1fd8 10 09 BPL &1fe3 ; top_bit_of_velocity_clear # Top bit of velocity set if moving right or down ; top_bit_of_velocity_set &1fda 29 1f AND #&1f &1fdc 18 CLC &1fdd 75 c0 ADC &c0,X ; sparkler_coordinates &1fdf 90 12 BCC &1ff3 ; set_velocity_and_consider_next_velocity &1fe1 b0 07 BCS &1fea ; invert_velocity # Always_branches ; top_bit_of_velocity_clear &1fe3 b5 c0 LDA &c0,X ; sparkler_coordinates &1fe5 38 SEC &1fe6 f5 c4 SBC &c4,X ; sparkler_velocities &1fe8 b0 09 BCS &1ff3 ; set_velocity_and_consider_next_velocity ; invert_velocity &1fea b5 c4 LDA &c4,X ; sparkler_velocities &1fec 49 80 EOR #&80 &1fee 95 c4 STA &c4,X ; sparkler_velocities &1ff0 4c d8 1f JMP &1fd8 ; set_velocity_and_consider_next_velocity &1ff3 95 c0 STA &c0,X ; sparkler_coordinates &1ff5 88 DEY &1ff6 d0 dd BNE &1fd5 ; apply_sparkler_velocities_loop ; check_for_collision_in_frame_3 &1ff8 a5 8c LDA &8c ; maximum_line_length &1ffa 85 09 STA &09 ; previous_maximum_line_length &1ffc a9 ff LDA #&ff # Don't limit length of line &1ffe 85 8c STA &8c ; maximum_line_length &2000 a9 08 LDA #&08 # Set to 8 to not draw line after hitting something &2002 8d e5 1d STA &1de5 ; line_continuation_branch_offset &2005 a9 48 LDA #&48 ; COLOUR_0_OFFSET &2007 8d ea 1d STA &1dea ; line_colour_offset &200a b4 c1 LDY &c1,X ; sparklers_first_line_start_y # Draw line from end of previous line to start of this &200c b5 c0 LDA &c0,X ; sparklers_first_line_start_x # line, checking but not drawing anything (colour 0) &200e aa TAX &200f 20 ca 1c JSR &1cca ; draw_line # Returns zero if line completely drawn &2012 f0 2e BEQ &2042 ; restore_line_variables_and_consider_next_sparkler &2014 b1 4e LDA (&4e),Y ; line_screen_address &2016 3d 7c 0b AND &0b7c,X ; colour_1_pixel_values &2019 f0 11 BEQ &202c ; make_first_line_null ; sparkler_hit_boundary_in_frame_3 # If the sparkler hit a boundary, allow randomisation &201b a5 5f LDA &5f ; sparkler_stability_flags &201d a6 4a LDX &4a ; sparkler_offset &201f d0 04 BNE &2025 ; is_second_sparkler ; is_first_sparkler &2021 29 40 AND #&40 ; SECOND_SPARKLER_IS_STABLE # Clear FIRST_SPARKLER_IS_STABLE &2023 10 02 BPL &2027 ; set_sparkler_stability_flags ; is_second_sparkler &2025 29 80 AND #&80 ; FIRST_SPARKLER_IS_STABLE # Clear SECOND_SPARKLER_IS_STABLE ; set_sparkler_stability_flags &2027 85 5f STA &5f ; sparkler_stability_flags &2029 4c 3a 20 JMP &203a ; store_end_of_line_in_frame_3 ; make_first_line_null &202c a9 ff LDA #&ff # Set to negative to indicate sparklers need updating &202e 85 27 STA &27 ; sparklers_need_updating &2030 a6 4a LDX &4a ; sparkler_offset &2032 b5 c0 LDA &c0,X ; sparklers_first_line_start_x &2034 95 c2 STA &c2,X ; sparklers_first_line_end_x &2036 b5 c1 LDA &c1,X ; sparklers_first_line_start_y &2038 95 c3 STA &c3,X ; sparklers_first_line_end_y ; store_end_of_line_in_frame_3 &203a a5 5c LDA &5c ; line_last_pixel_x &203c 95 c0 STA &c0,X ; sparklers_first_line_start_x &203e a5 5d LDA &5d ; line_last_pixel_y &2040 95 c1 STA &c1,X ; sparklers_first_line_start_y ; restore_line_variables_and_consider_next_sparkler &2042 a5 09 LDA &09 ; previous_maximum_line_length &2044 85 8c STA &8c ; maximum_line_length &2046 a9 01 LDA #&01 # Set to 1 to draw line after hitting something &2048 8d e5 1d STA &1de5 ; line_continuation_branch_offset &204b a9 7c LDA #&7c ; COLOUR_1_OFFSET # Use colour 1 to draw line &204d 8d ea 1d STA &1dea ; line_colour_offset &2050 4c c7 20 JMP &20c7 ; consider_next_sparkler ; frame_one # In frame 1 % 4, plot new line of sparkler &2053 b5 c0 LDA &c0,X ; sparklers_first_line_start_x &2055 85 50 STA &50 ; line_start_x &2057 99 00 01 STA &0100,Y ; sparkler_lines_start_x &205a b5 c1 LDA &c1,X ; sparklers_first_line_start_y &205c 85 51 STA &51 ; line_start_y &205e 99 10 01 STA &0110,Y ; sparkler_lines_start_y &2061 b5 c2 LDA &c2,X ; sparklers_first_line_end_x &2063 99 20 01 STA &0120,Y ; sparkler_lines_end_x &2066 b5 c3 LDA &c3,X ; sparklers_first_line_end_y &2068 99 30 01 STA &0130,Y ; sparkler_lines_end_y &206b a8 TAY &206c b5 c2 LDA &c2,X ; sparklers_first_line_end_x &206e aa TAX &206f 20 ca 1c JSR &1cca ; draw_line # Returns zero if line was completely drawn &2072 f0 10 BEQ &2084 ; store_end_of_line_in_frame_1 ; plot_line_loop &2074 b1 4e LDA (&4e),Y ; line_screen_address &2076 3d 7c 0b AND &0b7c,X ; colour_1_pixel_values &2079 d0 16 BNE &2091 ; sparkler_hit_boundary_in_frame_1 # Branches if sparkler hit colour 3 pixel (filled line) &207b a9 fe LDA #&fe ; PLAYER_KILLED_BY_SPARKLER &207d 85 86 STA &86 ; game_state &207f 20 e7 1d JSR &1de7 ; continue_drawing_line # Returns zero if line was completely drawn &2082 d0 f0 BNE &2074 ; plot_line_loop # Keep plotting line if sparkler hit player ; store_end_of_line_in_frame_1 &2084 a6 4a LDX &4a ; sparkler_offset &2086 a5 50 LDA &50 ; line_start_x &2088 95 c2 STA &c2,X ; sparklers_first_line_end_x &208a a5 51 LDA &51 ; line_start_y &208c 95 c3 STA &c3,X ; sparklers_first_line_end_y &208e 4c c7 20 JMP &20c7 ; consider_next_sparkler ; sparkler_hit_boundary_in_frame_1 &2091 a6 4a LDX &4a ; sparkler_offset &2093 a5 5c LDA &5c ; line_last_pixel_x # Use where sparkler hit boundary as end of line &2095 95 c2 STA &c2,X ; sparklers_first_line_end_x &2097 a5 5d LDA &5d ; line_last_pixel_y &2099 95 c3 STA &c3,X ; sparklers_first_line_end_y &209b 8a TXA # Use sparkler_velocities + &0 to &3 for first sparkler &209c 18 CLC # + &8 to &b for second sparkler &209d 69 04 ADC #&04 &209f aa TAX &20a0 a0 03 LDY #&03 ; change_velocities_loop &20a2 ca DEX &20a3 b5 c4 LDA &c4,X ; sparkler_velocities &20a5 59 94 00 EOR &0094,Y ; tracers_x # Use tracer coordinates to affect how sparkler bounces &20a8 25 8d AND &8d ; sparkler_boundary_velocity_mask &20aa 09 02 ORA #&02 # Ensure sparkler keeps moving &20ac 95 c4 STA &c4,X ; sparkler_velocities &20ae 88 DEY &20af 10 f1 BPL &20a2 ; change_velocities_loop ; consider_playing_sound_sparkler_hitting_boundary &20b1 8a TXA &20b2 4a LSR A &20b3 4a LSR A &20b4 4a LSR A &20b5 69 01 ADC #&01 # A = 1 for first sparkler, 2 for second sparkler &20b7 a6 60 LDX &60 ; fuse_state # Non-zero if fuse is present &20b9 d0 0c BNE &20c7 ; consider_next_sparkler &20bb 8d fc 06 STA &06fc ; sound_0 + 4 (pitch low) &20be a9 07 LDA #&07 ; Generate a sound (SOUND) &20c0 a2 f8 LDX #&f8 ; &06f8 = sound_0 &20c2 a0 06 LDY #&06 &20c4 20 d4 03 JSR &03d4 ; call_previous_osword_vector # Play sound for sparkler hitting boundary (demo) ; consider_next_sparkler &20c7 24 88 BIT &88 ; two_sparklers # Positive if only one sparkler &20c9 10 12 BPL &20dd ; finished_plotting_or_unplotting_sparklers &20cb a5 4a LDA &4a ; sparkler_offset &20cd 18 CLC &20ce 69 08 ADC #&08 &20d0 85 4a STA &4a ; sparkler_offset &20d2 aa TAX &20d3 65 ee ADC &ee ; previous_sparklers_line_to_use &20d5 a8 TAY &20d6 e0 10 CPX #&10 &20d8 f0 03 BEQ &20dd ; finished_plotting_or_unplotting_sparklers &20da 4c fe 1e JMP &1efe ; update_sparklers_loop ; finished_plotting_or_unplotting_sparklers &20dd e6 80 INC &80 ; frame_count &20df 24 27 BIT &27 ; sparklers_need_updating # Negative if sparklers need updating &20e1 10 07 BPL &20ea ; unplot_sprites_and_wait_for_timer &20e3 24 86 BIT &86 ; game_state # Negative if player has died &20e5 30 03 BMI &20ea ; unplot_sprites_and_wait_for_timer &20e7 4c f6 1e JMP &1ef6 ; update_sparklers ; unplot_sprites_and_wait_for_timer &20ea a9 00 LDA #&00 # Positive to unplot sprites &20ec 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites ; wait_for_timer &20ef 2c 6f 0b BIT &0b6f ; timer_ready # Negative after timer event &20f2 10 fb BPL &20ef ; wait_for_timer &20f4 60 RTS ; animate_sparklers_at_end_of_level &20f5 24 88 BIT &88 ; two_sparklers # Negative if two sparklers &20f7 30 02 BMI &20fb ; skip_lengthening &20f9 e8 INX # Longer animation if single sparkler &20fa e8 INX ; skip_lengthening &20fb 86 f9 STX &f9 ; count_high &20fd a9 60 LDA #&60 ; RTS # Suppress sprite plotting and unplotting &20ff 8d e4 13 STA &13e4 ; plot_or_unplot_sprites &2102 a0 ff LDY #&ff &2104 8c 6f 0b STY &0b6f ; timer_ready # Set to negative to force immediate replot &2107 c8 INY ; 0 &2108 84 f8 STY &f8 ; count_low &210a 84 27 STY &27 ; sparklers_need_updating # Set to zero to indicate sparklers don't need updating ; animate_sparklers_at_end_of_level_loop &210c 20 f6 1e JSR &1ef6 ; update_sparklers &210f e6 f8 INC &f8 ; count_low &2111 d0 f9 BNE &210c ; animate_sparklers_at_end_of_level_loop &2113 c6 f9 DEC &f9 ; count_high &2115 d0 f5 BNE &210c ; animate_sparklers_at_end_of_level_loop &2117 a9 85 LDA #&85 ; STA # Permit sprite plotting and unplotting &2119 8d e4 13 STA &13e4 ; plot_or_unplot_sprites &211c 60 RTS ; play_game &211d 20 20 0c JSR &0c20 ; setup_screen &2120 a2 00 LDX #&00 ; spiral_type_and_direction # Draw boxes from smallest to largest &2122 a0 00 LDY #&00 ; spiral_flags # Draw edge boxes &2124 20 dd 2a JSR &2add ; draw_animated_spiral &2127 78 SEI &2128 a9 25 LDA #&25 ; &1525 = game_event_handler &212a 8d 20 02 STA &0220 ; event_vector_low &212d a9 15 LDA #&15 &212f 8d 21 02 STA &0221 ; event_vector_high &2132 a9 07 LDA #&07 &2134 8d a0 02 STA &02a0 ; os_countdown_timer + 4 &2137 85 2c STA &2c ; scrolltext_pixel &2139 58 CLI &213a a2 03 LDX #&03 # Player starts with 3 lives &213c 86 10 STX &10 ; player_lives &213e a2 01 LDX #&01 # Player starts on level 1 &2140 86 15 STX &15 ; level_as_number &2142 ca DEX ; 0 &2143 86 2d STX &2d ; scrolltext_offset &2145 86 12 STX &12 ; score_as_bcd &2147 86 13 STX &13 ; score + 1 &2149 86 14 STX &14 ; score + 2 &214b 86 1c STX &1c ; level_as_offset # Player starts on level 1 &214d 86 64 STX &64 ; demo_mode # Set to zero to indicate playing game &214f a2 06 LDX #&06 ; C &2151 86 47 STX &47 ; level_colour &2153 ca DEX ; 5 &2154 a9 20 LDA #&20 ; " " ; initialise_score_as_digits_loop &2156 95 16 STA &16,X ; score_as_digits &2158 ca DEX &2159 10 fb BPL &2156 ; initialise_score_as_digits_loop &215b a9 30 LDA #&30 ; "0" # Set score to " 0" &215d 85 1b STA &1b ; score_as_digits + 5 &215f 20 a8 21 JSR &21a8 ; initialise_level ; game_loop &2162 20 5e 1e JSR &1e5e ; update_scrolltext_after_resetting_timer &2165 20 00 0e JSR &0e00 ; update_game &2168 24 86 BIT &86 ; game_state &216a 50 0d BVC &2179 ; continue_game # &40 clear unless player died or cleared level &216c 10 08 BPL &2176 ; level_was_cleared # &80 clear unless player died &216e 20 62 22 JSR &2262 ; death_animation &2171 24 10 BIT &10 ; player_lives &2173 10 ed BPL &2162 ; game_loop ; leave &2175 60 RTS ; level_was_cleared &2176 20 a8 21 JSR &21a8 ; initialise_level # Start next level ; continue_game &2179 a6 66 LDX &66 ; last_key_pressed &217b e0 1b CPX #&1b ; ESCAPE &217d f0 f6 BEQ &2175 ; leave &217f e0 51 CPX #&51 ; Q &2181 d0 0d BNE &2190 ; q_not_pressed &2183 a2 01 LDX #&01 # Set to non-zero to disable sound &2185 8e 62 02 STX &0262 ; os_sound_suppression &2188 a9 0f LDA #&0f ; Flush all buffers &218a ca DEX ; 0 ; Flush all buffers &218b 86 66 STX &66 ; last_key_pressed # Set to zero to forget keypress &218d 20 f4 ff JSR &fff4 ; OSBYTE ; q_not_pressed &2190 e0 53 CPX #&53 ; S &2192 d0 0a BNE &219e ; s_not_pressed &2194 a9 00 LDA #&00 # Set to zero to enable sound &2196 8d 62 02 STA &0262 ; os_sound_suppression &2199 85 66 STA &66 ; last_key_pressed # Set to zero to forget keypress &219b 20 52 22 JSR &2252 ; play_background_drone ; s_not_pressed &219e e0 50 CPX #&50 ; P &21a0 d0 c0 BNE &2162 ; game_loop &21a2 20 8b 0b JSR &0b8b ; pause_game &21a5 4c 62 21 JMP &2162 ; game_loop ; initialise_level &21a8 a2 01 LDX #&01 # Set colour 1 to level colour &21aa a4 47 LDY &47 ; level_colour &21ac 20 e7 0a JSR &0ae7 ; set_logical_colour &21af c8 INY &21b0 c0 03 CPY #&03 ; Y &21b2 d0 02 BNE &21b6 ; skip_yellow_and_blue &21b4 c8 INY # Use R G M C for level colours &21b5 c8 INY ; skip_yellow_and_blue &21b6 c0 07 CPY #&07 &21b8 d0 02 BNE &21bc ; skip_wraparound &21ba a0 01 LDY #&01 ; R ; skip_wraparound &21bc 84 47 STY &47 ; level_colour &21be a5 1c LDA &1c ; level_as_offset &21c0 f0 05 BEQ &21c7 ; skip_spiral # Don't draw a spiral when starting level 1 &21c2 a2 ff LDX #&ff ; spiral_type_and_direction # Draw crosses &21c4 20 dd 2a JSR &2add ; draw_animated_spiral ; skip_spiral ; initialise_level_without_changing_colour_or_spiral &21c7 a9 ea LDA #&ea : NOP # Don't stop drawing line if it crosses another &21c9 8d e6 1d STA &1de6 ; consider_stopping_line &21cc a9 70 LDA #&70 ; COLOUR_3_OFFSET # Use colour 3 to draw line &21ce 8d ea 1d STA &1dea ; line_colour_offset &21d1 a9 ff LDA #&ff &21d3 85 8c STA &8c ; maximum_line_length &21d5 a0 04 LDY #&04 &21d7 84 50 STY &50 ; line_start_x &21d9 84 51 STY &51 ; line_start_y &21db a2 fa LDX #&fa &21dd 20 ca 1c JSR &1cca ; draw_line # Draw quadrant top border &21e0 a2 fa LDX #&fa &21e2 a0 fa LDY #&fa &21e4 20 ca 1c JSR &1cca ; draw_line # Draw quadrant right border &21e7 a2 04 LDX #&04 &21e9 a0 fa LDY #&fa &21eb 20 ca 1c JSR &1cca ; draw_line # Draw quadrant bottom border &21ee a2 04 LDX #&04 &21f0 a0 04 LDY #&04 &21f2 20 ca 1c JSR &1cca ; draw_line # Draw quadrant left border &21f5 a9 7c LDA #&7c ; COLOUR_1_OFFSET # Use colour 1 to draw line &21f7 8d ea 1d STA &1dea ; line_colour_offset &21fa a9 60 LDA #&60 ; RTS # Stop drawing line if it crosses another &21fc 8d e6 1d STA &1de6 ; consider_stopping_line ; copy_level_independent_variables &21ff a2 27 LDX #&27 ; copy_level_independent_variables_loop &2201 bd 38 0b LDA &0b38,X ; initial_level_variables &2204 95 90 STA &90,X ; level_independent_variables &2206 ca DEX &2207 10 f8 BPL &2201 ; copy_level_independent_variables_loop &2209 a6 1c LDX &1c ; level_as_offset &220b e0 14 CPX #&14 &220d d0 04 BNE &2213 ; skip_wraparound &220f a2 0a LDX #&0a # Levels 21 - 30 are the same as levels 11 - 20 &2211 86 1c STX &1c ; level_as_offset ; skip_wraparound &2213 a9 00 LDA #&00 &2215 85 5f STA &5f ; sparkler_stability_flags # Set to zero to allow sparkler randomisation &2217 85 60 STA &60 ; fuse_state # Set to zero to indicate no fuse &2219 85 61 STA &61 ; activate_tracer_three # Set to positive to skip activating tracer three &221b 85 62 STA &62 ; activate_tracer_four # Set to positive to skip activating tracer four &221d 85 69 STA &69 ; pixels_filled_low &221f 85 6a STA &6a ; pixels_filled_high &2221 85 84 STA &84 ; player_is_drawing # Set to zero to indicate player is not drawing &2223 85 86 STA &86 ; game_state # Set to zero to indicate player hasn't died or won &2225 85 11 STA &11 ; filled_bcd &2227 18 CLC ; calculate_level_data_offset_loop &2228 69 09 ADC #&09 &222a ca DEX &222b 10 fb BPL &2228 ; calculate_level_data_offset_loop &222d aa TAX &222e a0 08 LDY #&08 ; copy_level_dependent_variables_loop &2230 ca DEX &2231 bd 75 29 LDA &2975,X ; level_data &2234 99 87 00 STA &0087,Y ; level_dependent_variables &2237 88 DEY &2238 10 f6 BPL &2230 ; copy_level_dependent_variables_loop &223a 20 f4 23 JSR &23f4 ; initialise_time_bar_and_enemies &223d 18 CLC # Clear carry to plot highlight lines &223e 20 51 24 JSR &2451 ; start_life &2241 a2 0f LDX #&0f &2243 a9 80 LDA #&80 ; initialise_sparkler_coordinates_and_velocities_loop &2245 95 c0 STA &c0,X ; sparkler_coordinates &2247 ca DEX &2248 10 fb BPL &2245 ; initialise_sparkler_coordinates_and_velocities_loop &224a a2 5f LDX #&5f ; initialise_sparkler_lines_coordinates_loop &224c 9d 00 01 STA &0100,X ; sparkler_lines_coordinates &224f ca DEX &2250 10 fa BPL &224c ; initialise_sparkler_lines_coordinates_loop ; play_background_drone &2252 a9 07 LDA #&07 ; Generate a sound (SOUND) &2254 a2 d8 LDX #&d8 ; &09d8 = sound_6 &2256 a0 09 LDY #&09 &2258 20 f1 ff JSR &fff1 ; OSWORD # Play sound for background drone &225b a2 e0 LDX #&e0 ; &09d8 = sound_7 &225d a0 09 LDY #&09 &225f 4c f1 ff JMP &fff1 ; OSWORD # Play sound for background drone ; death_animation &2262 a9 0f LDA #&0f ; Flush all buffers &2264 a2 00 LDX #&00 ; Flush all buffers # Disable events &2266 20 49 24 JSR &2449 ; enable_or_disable_vsync_and_interval_timer_events &2269 20 f4 ff JSR &fff4 ; OSBYTE &226c a9 01 LDA #&01 &226e 85 67 STA &67 ; shudder_count ; shudder_loop &2270 a2 61 LDX #&61 &2272 20 e7 23 JSR &23e7 ; set_horizontal_sync_position &2275 a2 63 LDX #&63 &2277 20 e7 23 JSR &23e7 ; set_horizontal_sync_position &227a c6 67 DEC &67 ; shudder_count &227c 10 f2 BPL &2270 ; shudder_loop &227e a2 62 LDX #&62 &2280 20 e7 23 JSR &23e7 ; set_horizontal_sync_position &2283 a9 07 LDA #&07 ; Generate a sound (SOUND) &2285 a2 30 LDX #&30 ; &0b30 = sound_14 &2287 a0 0b LDY #&0b &2289 20 f1 ff JSR &fff1 ; OSWORD # Play sound for death shudder ; death_animation_without_shudder &228c a5 86 LDA &86 ; game_state &228e 4a LSR A # Carry set if player wasn't killed by sparkler &228f a9 07 LDA #&07 ; Generate a sound (SOUND) &2291 a0 0b LDY #&0b &2293 b0 1d BCS &22b2 ; death_animation_without_flashing_colour &2295 a2 20 LDX #&20 ; &0b20 = sound_12 &2297 20 f1 ff JSR &fff1 ; OSWORD # Play sound for death by sparkler &229a a2 02 LDX #&02 # Set colour 2 to flashing black and white &229c a0 08 LDY #&08 ; K/W &229e 20 e7 0a JSR &0ae7 ; set_logical_colour &22a1 a9 09 LDA #&09 ; Set first colour duration &22a3 a2 04 LDX #&04 &22a5 20 f4 ff JSR &fff4 ; OSBYTE &22a8 a9 0a LDA #&0a ; Set second colour duration &22aa a2 04 LDX #&04 &22ac 20 f4 ff JSR &fff4 ; OSBYTE &22af 4c b7 22 JMP &22b7 ; consider_backtrack ; death_animation_without_flashing_colour &22b2 a2 28 LDX #&28 ; &0b28 = sound_13 &22b4 20 f1 ff JSR &fff1 ; OSWORD # Play sound for death by other causes ; consider_backtrack &22b7 a9 00 LDA #&00 # Positive to unplot sprites &22b9 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites &22bc 24 84 BIT &84 ; player_is_drawing # Positive if player is not drawing &22be 10 0e BPL &22ce ; skip_backtrack &22c0 a5 90 LDA &90 ; player_x &22c2 a4 91 LDY &91 ; player_y &22c4 20 b2 14 JSR &14b2 ; get_pixel &22c7 c9 10 CMP #&10 ; COLOUR_2_VALUE &22c9 90 03 BCC &22ce ; skip_backtrack &22cb 20 17 15 JSR &1517 ; move_player_backwards_and_set_pixel_without_enemies_check ; skip_backtrack &22ce 38 SEC # Set carry to plot death lines &22cf 20 51 24 JSR &2451 ; start_life &22d2 a2 02 LDX #&02 # Set colour 2 to black &22d4 a0 ff LDY #&ff &22d6 84 93 STY &93 ; fuse_y &22d8 c8 INY ; 0, K &22d9 84 60 STY &60 ; fuse_state # Set to zero to remove fuse &22db 20 e7 0a JSR &0ae7 ; set_logical_colour &22de 24 84 BIT &84 ; player_is_drawing # Negative if player is drawing &22e0 30 03 BMI &22e5 ; unplot_path &22e2 4c 79 23 JMP &2379 ; start_tracers ; unplot_path # If there is an unfilled path, unplot it &22e5 a5 7b LDA &7b ; path_start_x # by following it backwards, one pixel at a time &22e7 85 90 STA &90 ; player_x &22e9 a5 7c LDA &7c ; path_start_y &22eb 85 91 STA &91 ; player_y &22ed a5 7d LDA &7d ; draw_start_direction &22ef d0 04 BNE &22f5 ; not_drawing_up ; was_drawing_up &22f1 c6 7c DEC &7c ; path_start_y &22f3 d0 7a BNE &236f ; unplot_path_pixel # Always branches ; not_drawing_up &22f5 c9 01 CMP #&01 ; DIRECTION_RIGHT &22f7 d0 04 BNE &22fd ; not_drawing_right ; was_drawing_right &22f9 e6 7b INC &7b ; path_start_x &22fb d0 72 BNE &236f ; unplot_path_pixel # Always branches ; not_drawing_right &22fd c9 02 CMP #&02 ; DIRECTION_LEFT &22ff d0 04 BNE &2305 ; not_drawing_left ; was_drawing_left &2301 c6 7b DEC &7b ; path_start_x &2303 d0 6a BNE &236f ; unplot_path_pixel # Always branches ; not_drawing_left ; was_drawing_odnw &2305 e6 7c INC &7c ; path_start_y &2307 d0 66 BNE &236f ; unplot_path_pixel # Always branches ; unplot_path_loop &2309 a5 7d LDA &7d ; draw_start_direction &230b c9 03 CMP #&03 ; DIRECTION_DOWN &230d f0 14 BEQ &2323 ; not_unplotting_up &230f a5 7b LDA &7b ; path_start_x &2311 a4 7c LDY &7c ; path_start_y &2313 88 DEY &2314 20 b2 14 JSR &14b2 ; get_pixel &2317 c9 10 CMP #&10 ; COLOUR_2_VALUE &2319 90 08 BCC &2323 ; not_unplotting_up &231b c6 7c DEC &7c ; path_start_y &231d a9 00 LDA #&00 ; DIRECTION_UP &231f 85 7d STA &7d ; draw_start_direction &2321 f0 4c BEQ &236f ; unplot_path_pixel # Always branches ; not_unplotting_up &2323 a5 7d LDA &7d ; draw_start_direction &2325 c9 02 CMP #&02 ; DIRECTION_LEFT &2327 f0 15 BEQ &233e ; not_unplotting_right &2329 a4 7b LDY &7b ; path_start_x &232b c8 INY &232c 98 TYA &232d a4 7c LDY &7c ; path_start_y &232f 20 b2 14 JSR &14b2 ; get_pixel &2332 c9 10 CMP #&10 ; COLOUR_2_VALUE &2334 90 08 BCC &233e ; not_unplotting_right &2336 e6 7b INC &7b ; path_start_x &2338 a9 01 LDA #&01 ; DIRECTION_RIGHT &233a 85 7d STA &7d ; draw_start_direction &233c d0 31 BNE &236f ; unplot_path_pixel # Always branches ; not_unplotting_right &233e a5 7d LDA &7d ; draw_start_direction &2340 c9 01 CMP #&01 ; DIRECTION_RIGHT &2342 f0 15 BEQ &2359 ; not_unplotting_left &2344 a4 7b LDY &7b ; path_start_x &2346 88 DEY &2347 98 TYA &2348 a4 7c LDY &7c ; path_start_y &234a 20 b2 14 JSR &14b2 ; get_pixel &234d c9 10 CMP #&10 ; COLOUR_2_VALUE &234f 90 08 BCC &2359 ; not_unplotting_left &2351 c6 7b DEC &7b ; path_start_x &2353 a9 02 LDA #&02 ; DIRECTION_LEFT &2355 85 7d STA &7d ; draw_start_direction &2357 d0 16 BNE &236f ; unplot_path_pixel # Always branches ; not_unplotting_left &2359 a5 7d LDA &7d ; draw_start_direction &235b f0 1c BEQ &2379 &235d a5 7b LDA &7b ; path_start_x &235f a4 7c LDY &7c ; path_start_y &2361 c8 INY &2362 20 b2 14 JSR &14b2 ; get_pixel &2365 c9 10 CMP #&10 ; COLOUR_2_VALUE &2367 90 10 BCC &2379 ; start_tracers &2369 e6 7c INC &7c ; path_start_y &236b a9 03 LDA #&03 ; DIRECTION_DOWN &236d 85 7d STA &7d ; draw_start_direction ; unplot_path_pixel &236f a5 7b LDA &7b ; path_start_x &2371 a4 7c LDY &7c ; path_start_y &2373 20 e8 14 JSR &14e8 ; set_pixel &2376 4c 09 23 JMP &2309 ; unplot_path_loop ; start_tracers &2379 a5 90 LDA &90 ; player_x # If the player is on the left or right edge, &237b c9 04 CMP #&04 &237d f0 14 BEQ &2393 ; start_tracers_on_top_and_bottom_edges # put the tracers on the top and bottom edges &237f c9 fa CMP #&fa &2381 f0 10 BEQ &2393 ; start_tracers_on_top_and_bottom_edges # Otherwise, put tracers on the left and right edges ; start_tracers_on_left_and_right_edges &2383 a9 04 LDA #&04 # Tracer one starts on left edge of screen &2385 85 94 STA &94 ; tracers_x &2387 a9 fa LDA #&fa # Tracer two starts on right edge of screen &2389 85 96 STA &96 ; tracers_x + 2 &238b a9 7e LDA #&7e # Tracers one and two start in middle of edge &238d 85 95 STA &95 ; tracers_y &238f 85 97 STA &97 ; tracers_y + 2 &2391 d0 0e BNE &23a1 ; start_tracers_on_top_and_bottom_edges &2393 a9 04 LDA #&04 # Tracer one starts on top edge of screen &2395 85 95 STA &95 ; tracers_y &2397 a9 fa LDA #&fa # Tracer two starts on bottom edge of screen &2399 85 97 STA &97 ; tracers_y + 2 &239b a9 7e LDA #&7e # Tracers one and two start in middle of edge &239d 85 94 STA &94 ; tracers_x &239f 85 96 STA &96 ; tracers_x + 2 &23a1 a9 09 LDA #&09 ; Set first colour duration &23a3 a2 0f LDX #&0f &23a5 20 f4 ff JSR &fff4 ; OSBYTE &23a8 a9 0a LDA #&0a ; Set second colour duration &23aa a2 0f LDX #&0f &23ac 20 f4 ff JSR &fff4 ; OSBYTE &23af a2 02 LDX #&02 # Set colour 2 to yellow &23b1 a0 03 LDY #&03 ; Y &23b3 20 e7 0a JSR &0ae7 ; set_logical_colour &23b6 a9 00 LDA #&00 &23b8 85 61 STA &61 ; activate_tracer_three # Set to positive to skip activating tracer three &23ba 85 62 STA &62 ; activate_tracer_four # Set to positive to skip activating tracer four &23bc 85 84 STA &84 ; player_is_drawing # Set to zero to indicate player is not drawing &23be 85 86 STA &86 ; game_state # Set to zero to indicate playing game &23c0 a5 10 LDA &10 ; player_lives &23c2 d0 05 BNE &23c9 ; not_end_of_game ; end_of_game &23c4 85 10 STA &10 ; player_lives &23c6 c6 10 DEC &10 ; player_lives &23c8 60 RTS ; not_end_of_game &23c9 a9 fc LDA #&fc &23cb 24 b1 BIT &b1 ; tracers_direction + 4 &23cd 30 02 BMI &23d1 ; tracer_three_not_active # If tracer three is active, &23cf 85 89 STA &89 ; timer_interval # Accelerate first section of time bar ; tracer_three_not_active &23d1 24 b3 BIT &b3 ; tracers_direction + 6 &23d3 30 02 BMI &23d7 ; tracer_four_not_active # If tracer four is active, &23d5 85 89 STA &89 ; timer_interval # Accelerate first section of time bar ; tracer_four_not_active &23d7 a5 66 LDA &66 ; last_key_pressed &23d9 49 1b EOR #&1b ; ESCAPE &23db f0 e7 BEQ &23c4 ; end_of_game # End game if ESCAPE pressed during death animation &23dd 20 f4 23 JSR &23f4 ; initialise_time_bar_and_enemies &23e0 18 CLC # Clear carry to plot highlight lines &23e1 20 51 24 JSR &2451 ; start_life &23e4 4c 52 22 JMP &2252 ; play_background_drone ; set_horizontal_sync_position &23e7 a9 02 LDA #&02 # R2: Horizontal sync position register &23e9 8d 00 fe STA &fe00 ; video register number &23ec 8e 01 fe STX &fe01 ; video register value &23ef a9 13 LDA #&13 ; Wait for vertical retrace &23f1 4c f4 ff JMP &fff4 ; OSBYTE ; initialise_time_bar_and_enemies &23f4 a9 88 LDA #&88 &23f6 85 70 STA &70 ; screen_address_low &23f8 85 75 STA &75 ; time_bar_screen_address_low &23fa a9 2f LDA #&2f &23fc 85 71 STA &71 ; screen_address_high &23fe 85 76 STA &76 ; time_bar_screen_address_high &2400 a2 00 LDX #&00 &2402 18 CLC ; plot_time_bar_loop &2403 8a TXA &2404 29 07 AND #&07 &2406 a8 TAY &2407 d0 0c BNE &2415 ; not_group &2409 a5 70 LDA &70 ; screen_address_low &240b 69 80 ADC #&80 &240d 85 70 STA &70 ; screen_address_low &240f a5 71 LDA &71 ; screen_address_high &2411 69 02 ADC #&02 &2413 85 71 STA &71 ; screen_address_high ; not_group &2415 a5 64 LDA &64 ; demo_mode # Don't plot time bar in demo mode &2417 49 ff EOR #&ff &2419 91 70 STA (&70),Y ; screen_address &241b e8 INX &241c d0 e5 BNE &2403 ; plot_time_bar_loop &241e 86 5f STX &5f ; sparkler_stability_flags # Set to zero to allow sparkler randomisation &2420 8e 8f 48 STX &488f ; screen_memory + &188f # Plot first gap in time bar &2423 8e 8f 61 STX &618f ; screen_memory + &318f # Plot second gap in time bar &2426 86 78 STX &78 ; game_time &2428 ca DEX ; &ff &2429 86 99 STX &99 ; sprites_y + 8 &242b 86 9b STX &9b ; sprites_y + 10 &242d 86 b1 STX &b1 ; tracers_direction + 4 # Set to negative to indicate tracer three not active &242f 86 b3 STX &b3 ; tracers_direction + 6 # Set to negative to indicate tracer four not active &2431 a9 7f LDA #&7f &2433 8d e0 08 STA &08e0 ; envelope_3 + 0 (step length) # Reset envelope for background drone (sound_6) &2436 8d f0 08 STA &08f0 ; envelope_4 + 0 (step length) # Reset envelope for background drone (sound_7) ; set_timer_and_enable_or_disable_events &2439 78 SEI &243a 8e 9c 02 STX &029c ; os_countdown_timer &243d 8e 9d 02 STX &029d ; os_countdown_timer + 1 &2440 8e 9e 02 STX &029e ; os_countdown_timer + 2 &2443 8e 9f 02 STX &029f ; os_countdown_timer + 3 &2446 8e a0 02 STX &02a0 ; os_countdown_timer + 4 ; enable_or_disable_vsync_and_interval_timer_events &2449 8e c3 02 STX &02c3 ; os_event_enable_flags + 4 # Enable v-sync events &244c 8e c4 02 STX &02c4 ; os_event_enable_flags + 5 # Enable interval timer events &244f 58 CLI &2450 60 RTS ; start_life # Called with carry clear for highlight lines &2451 a5 8c LDA &8c ; maximum_line_length # carry set for death lines &2453 48 PHA &2454 a2 ff LDX #&ff &2456 86 8c STX &8c ; maximum_line_length &2458 8e 6f 0b STX &0b6f ; timer_ready # Set to negative to plot death lines without waiting &245b a9 ea LDA #&ea ; NOP # Don't stop drawing line if it crosses another &245d 8d e6 1d STA &1de6 ; consider_stopping_line &2460 a9 70 LDA #&70 ; COLOUR_3_OFFSET # Use colour 3 to draw line &2462 8d ea 1d STA &1dea ; line_colour_offset &2465 a9 07 LDA #&07 &2467 85 44 STA &44 ; plot_count &2469 90 5c BCC &24c7 ; start_life_with_highlight_lines ; draw_death_lines_plot_loop &246b a9 05 LDA #&05 &246d 85 40 STA &40 ; player_line_x1 &246f a9 03 LDA #&03 &2471 85 41 STA &41 ; player_line_y1 &2473 a9 fb LDA #&fb &2475 85 42 STA &42 ; player_line_x2 &2477 a9 fd LDA #&fd &2479 85 43 STA &43 ; player_line_y2 ; draw_death_lines_loop &247b 20 88 25 JSR &2588 ; draw_player_line &247e 18 CLC &247f a5 40 LDA &40 ; player_line_x1 &2481 69 03 ADC #&03 &2483 85 40 STA &40 ; player_line_x1 &2485 49 ff EOR #&ff &2487 69 01 ADC #&01 &2489 85 42 STA &42 ; player_line_x2 &248b a5 41 LDA &41 ; player_line_y1 &248d 69 05 ADC #&05 &248f c9 df CMP #&df &2491 f0 0b BEQ &249e ; consider_next_plot &2493 85 41 STA &41 ; player_line_y1 &2495 49 ff EOR #&ff &2497 69 01 ADC #&01 &2499 85 43 STA &43 ; player_line_y2 &249b 4c 7b 24 JMP &247b ; draw_death_lines_loop ; consider_next_plot &249e c6 44 DEC &44 ; plot_count &24a0 30 0a BMI &24ac ; finished_plotting_death_lines &24a2 d0 c7 BNE &246b ; draw_death_lines_plot_loop &24a4 a9 10 LDA #&10 ; CLG &24a6 20 ee ff JSR &ffee ; OSWRCH &24a9 4c 6b 24 JMP &246b ; draw_death_lines_plot_loop ; finished_plotting_death_lines &24ac a9 10 LDA #&10 ; CLG &24ae 20 ee ff JSR &ffee ; OSWRCH &24b1 24 64 BIT &64 ; demo_mode # Negative if demo mode &24b3 30 0f BMI &24c4 ; skip_clearing &24b5 a9 0f LDA #&0f ; Flush all buffers &24b7 a2 00 LDX #&00 ; Flush all buffers &24b9 20 f4 ff JSR &fff4 ; OSBYTE &24bc a9 10 LDA #&10 ; CLG &24be 20 ee ff JSR &ffee ; OSWRCH &24c1 20 ee ff JSR &ffee ; OSWRCH ; skip_clearing &24c4 4c 6c 25 JMP &256c ; restore_line_variables_from_pla ; start_life_with_highlight_lines &24c7 e8 INX ; 0 &24c8 86 44 STX &44 ; plot_count &24ca 24 64 BIT &64 ; demo_mode # Negative if demo mode &24cc 30 24 BMI &24f2 ; skip_using_life &24ce a9 0f LDA #&0f ; Flush all buffers &24d0 20 f4 ff JSR &fff4 ; OSBYTE &24d3 a5 10 LDA &10 ; player_lives &24d5 c9 07 CMP #&07 &24d7 b0 17 BCS &24f0 ; skip_unplotting_life &24d9 a9 1f LDA #&1f # TAB(&21 + player_lives, &16) &24db 20 ee ff JSR &ffee ; OSWRCH &24de a9 21 LDA #&21 &24e0 18 CLC &24e1 65 10 ADC &10 ; player_lives &24e3 20 ee ff JSR &ffee ; OSWRCH &24e6 a9 16 LDA #&16 &24e8 20 ee ff JSR &ffee ; OSWRCH &24eb a9 20 LDA #&20 ; " " &24ed 20 ee ff JSR &ffee ; OSWRCH # Plot space over life ; skip_unplotting_life &24f0 c6 10 DEC &10 ; player_lives ; skip_using_life &24f2 a9 99 LDA #&99 &24f4 85 40 STA &40 ; player_line_x1 &24f6 a9 ff LDA #&ff &24f8 85 41 STA &41 ; player_line_y1 ; draw_highlight_lines_loop &24fa a5 41 LDA &41 ; player_line_y1 &24fc 29 08 AND #&08 &24fe d0 10 BNE &2510 ; draw_highlight_lines_without_sound &2500 a5 41 LDA &41 ; player_line_y1 &2502 49 ff EOR #&ff &2504 8d fc 09 STA &09fc ; sound_10 + 4 (pitch low) # Set pitch for highlight lines &2507 a9 07 LDA #&07 ; Generate a sound (SOUND) &2509 a0 09 LDY #&09 ; &09f8 = sound_10 &250b a2 f8 LDX #&f8 &250d 20 f1 ff JSR &fff1 ; OSWORD # Play sound for highlight lines ; draw_highlight_lines_without_sound &2510 18 CLC &2511 a5 40 LDA &40 ; player_line_x1 &2513 69 15 ADC #&15 &2515 85 40 STA &40 ; player_line_x1 &2517 49 ff EOR #&ff &2519 aa TAX &251a e8 INX &251b 86 42 STX &42 ; player_line_x2 &251d 18 CLC &251e a5 41 LDA &41 ; player_line_y1 &2520 69 23 ADC #&23 &2522 85 41 STA &41 ; player_line_y1 &2524 49 ff EOR #&ff &2526 aa TAX &2527 e8 INX &2528 86 43 STX &43 ; player_line_y2 &252a e6 44 INC &44 ; plot_count &252c a5 44 LDA &44 ; plot_count &252e c9 09 CMP #&09 &2530 90 07 BCC &2539 ; skip_line &2532 c9 3b CMP #&3b &2534 f0 29 BEQ &255f ; finished_plotting_highlight_lines &2536 20 7d 25 JSR &257d ; draw_player_line_with_timer ; skip_line &2539 38 SEC &253a a5 40 LDA &40 ; player_line_x1 &253c e9 18 SBC #&18 &253e 85 40 STA &40 ; player_line_x1 &2540 49 ff EOR #&ff &2542 aa TAX &2543 e8 INX &2544 86 42 STX &42 ; player_line_x2 &2546 38 SEC &2547 a5 41 LDA &41 ; player_line_y1 &2549 e9 28 SBC #&28 &254b 85 41 STA &41 ; player_line_y1 &254d 49 ff EOR #&ff &254f aa TAX &2550 e8 INX &2551 86 43 STX &43 ; player_line_y2 &2553 a5 44 LDA &44 ; plot_count &2555 c9 33 CMP #&33 &2557 b0 b7 BCS &2510 ; draw_highlight_lines_without_sound &2559 20 7d 25 JSR &257d ; draw_player_line_with_timer &255c 4c fa 24 JMP &24fa ; draw_highlight_lines_loop ; finished_plotting_highlight_lines &255f a9 f0 LDA #&f0 &2561 8d fc 09 STA &09fc ; sound_10 + 4 (pitch low) # Set pitch for filling &2564 a9 ff LDA #&ff &2566 8d ec 09 STA &09ec ; sound_8 + 4 (pitch low) # Unnecessary code &2569 20 e4 13 JSR &13e4 ; plot_or_unplot_sprites # Negative to plot sprites ; restore_line_variables_from_pla &256c a9 7c LDA #&7c ; COLOUR_1_OFFSET # Use colour 1 to draw line &256e 8d ea 1d STA &1dea ; line_colour_offset &2571 a9 60 LDA #&60 ; RTS # Stop drawing line if it crosses another &2573 8d e6 1d STA &1de6 ; consider_stopping_line &2576 8d 5a 02 STA &025a ; os_keyboard_status # Set CTRL pressed and SHIFT LOCK not engaged &2579 68 PLA ; maximum_line_length &257a 85 8c STA &8c ; maximum_line_length &257c 60 RTS ; draw_player_line_with_timer &257d a9 30 LDA #&30 &257f 8d 6f 0b STA &0b6f ; timer_ready # Set to positive to wait for next timer event &2582 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &2585 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB ; draw_player_line &2588 18 CLC &2589 a5 40 LDA &40 ; player_line_x1 &258b 65 90 ADC &90 ; player_x &258d b0 1b BCS &25aa ; skip_first_line &258f 85 50 STA &50 ; line_start_x &2591 a5 41 LDA &41 ; player_line_y1 &2593 65 91 ADC &91 ; player_y &2595 b0 13 BCS &25aa ; skip_first_line &2597 85 51 STA &51 ; line_start_y &2599 a5 41 LDA &41 ; player_line_y1 &259b 65 90 ADC &90 ; player_x &259d b0 0b BCS &25aa ; skip_first_line &259f aa TAX &25a0 a5 40 LDA &40 ; player_line_x1 &25a2 65 91 ADC &91 ; player_y &25a4 b0 04 BCS &25aa ; skip_first_line &25a6 a8 TAY &25a7 20 ca 1c JSR &1cca ; draw_line ; skip_first_line &25aa 18 CLC &25ab a5 40 LDA &40 ; player_line_x1 &25ad 65 90 ADC &90 ; player_x &25af b0 1c BCS &25cd ; skip_second_line &25b1 85 50 STA &50 ; line_start_x &25b3 a5 43 LDA &43 ; player_line_y2 &25b5 65 91 ADC &91 ; player_y &25b7 90 14 BCC &25cd ; skip_second_line &25b9 85 51 STA &51 ; line_start_y &25bb 18 CLC &25bc a5 41 LDA &41 ; player_line_y1 &25be 65 90 ADC &90 ; player_x &25c0 b0 0b BCS &25cd ; skip_second_line &25c2 aa TAX &25c3 a5 42 LDA &42 ; player_line_x2 &25c5 65 91 ADC &91 ; player_y &25c7 90 04 BCC &25cd ; skip_second_line &25c9 a8 TAY &25ca 20 ca 1c JSR &1cca ; draw_line ; skip_second_line &25cd 18 CLC &25ce a5 42 LDA &42 ; player_line_x2 &25d0 65 90 ADC &90 ; player_x &25d2 90 1e BCC &25f2 ; skip_third_line &25d4 85 50 STA &50 ; line_start_x &25d6 18 CLC &25d7 a5 43 LDA &43 ; player_line_y2 &25d9 65 91 ADC &91 ; player_y &25db 90 15 BCC &25f2 ; skip_third_line &25dd 85 51 STA &51 ; line_start_y &25df 18 CLC &25e0 a5 43 LDA &43 ; player_line_y2 &25e2 65 90 ADC &90 ; player_x &25e4 90 0c BCC &25f2 ; skip_third_line &25e6 aa TAX &25e7 18 CLC &25e8 a5 42 LDA &42 ; player_line_x2 &25ea 65 91 ADC &91 ; player_y &25ec 90 04 BCC &25f2 ; skip_third_line &25ee a8 TAY &25ef 20 ca 1c JSR &1cca ; draw_line ; skip_third_line &25f2 18 CLC &25f3 a5 42 LDA &42 ; player_line_x2 &25f5 65 90 ADC &90 ; player_x &25f7 90 1d BCC &2616 ; skip_fourth_line &25f9 85 50 STA &50 ; line_start_x &25fb 18 CLC &25fc a5 41 LDA &41 ; player_line_y1 &25fe 65 91 ADC &91 ; player_y &2600 b0 14 BCS &2616 ; skip_fourth_line &2602 85 51 STA &51 ; line_start_y &2604 a5 43 LDA &43 ; player_line_y2 &2606 65 90 ADC &90 ; player_x &2608 90 0c BCC &2616 ; skip_fourth_line &260a aa TAX &260b 18 CLC &260c a5 40 LDA &40 ; player_line_x1 &260e 65 91 ADC &91 ; player_y &2610 b0 04 BCS &2616 ; skip_fourth_line &2612 a8 TAY &2613 20 ca 1c JSR &1cca ; draw_line ; skip_fourth_line ; wait_for_timer &2616 2c 6f 0b BIT &0b6f ; timer_ready # Negative after timer event &2619 10 fb BPL &2616 ; wait_for_timer &261b 60 RTS ; start_game &261c 20 1d 21 JSR &211d ; play_game &261f a9 0f LDA #&0f ; Flush all buffers &2621 a2 00 LDX #&00 ; Flush all buffers # Disable events &2623 86 7c STX &7c ; new_high_score # Set to zero to indicate no new high score &2625 20 49 24 JSR &2449 ; enable_or_disable_vsync_and_interval_timer_events &2628 20 f4 ff JSR &fff4 ; OSBYTE &262b a9 09 LDA #&09 ; Set first colour duration &262d a2 0f LDX #&0f &262f 20 f4 ff JSR &fff4 ; OSBYTE &2632 a9 0a LDA #&0a ; Set second colour duration &2634 20 f4 ff JSR &fff4 ; OSBYTE &2637 a9 a0 LDA #&a0 # Set SHIFT enabled and SHIFT LOCK not engaged &2639 8d 5a 02 STA &025a ; os_keyboard_status &263c a9 10 LDA #&10 ; Set maximum number of ADC channel &263e a2 00 LDX #&00 ; no ADC sampling takes place &2640 20 f4 ff JSR &fff4 ; OSBYTE &2643 a5 66 LDA &66 ; last_key_pressed &2645 49 1b EOR #&1b ; ESCAPE &2647 d0 03 BNE &264c ; game_over &2649 4c 0b 27 JMP &270b ; high_score_screen_after_wipe_and_delay ; game_over &264c a2 00 LDX #&00 ; write_game_over_loop &264e bd 20 06 LDA &0620,X ; game_over_string &2651 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &2654 e8 INX &2655 e0 30 CPX #&30 &2657 d0 f5 BNE &264e ; write_game_over &2659 a2 04 LDX #&04 &265b 20 f5 20 JSR &20f5 ; animate_sparklers_at_end_of_level &265e a9 2f LDA #&2f ; &052f = high_scores &2660 85 70 STA &70 ; high_score_address_low &2662 a9 05 LDA #&05 &2664 85 71 STA &71 ; high_score_address_high &2666 85 73 STA &73 ; source_high_score_address_high &2668 85 75 STA &75 ; target_high_score_address_high &266a a2 01 LDX #&01 ; consider_existing_scores_loop &266c a0 00 LDY #&00 ; consider_existing_score_loop &266e b9 16 00 LDA &0016,Y ; score_as_digits &2671 d1 70 CMP (&70),Y ; high_score_address &2673 90 14 BCC &2689 ; consider_next_score &2675 d0 20 BNE &2697 ; player_scored_better &2677 c8 INY &2678 c0 06 CPY #&06 &267a 90 f2 BCC &266e ; consider_existing_score_loop &267c a5 70 LDA &70 ; high_score_address_low &267e 69 0f ADC #&0f &2680 85 70 STA &70 ; high_score_address_low &2682 e8 INX &2683 e0 09 CPX #&09 &2685 90 10 BCC &2697 ; player_scored_better &2687 b0 66 BCS &26ef ; skip_adding_high_score # Always branches ; consider_next_score &2689 18 CLC &268a a5 70 LDA &70 ; high_score_address_low &268c 69 10 ADC #&10 &268e 85 70 STA &70 ; high_score_address_low &2690 e8 INX &2691 e0 09 CPX #&09 &2693 90 d7 BCC &266c ; consider_existing_scores_loop &2695 b0 58 BCS &26ef ; skip_adding_high_score # Always branches ; player_scored_better &2697 86 7b STX &7b ; new_high_score_rank &2699 a9 ff LDA #&ff &269b 85 7c STA &7c ; new_high_score # Set to negative to indicate new high score &269d e0 01 CPX #&01 &269f d0 0b BNE &26ac ; not_highest_score &26a1 a0 05 LDY #&05 ; copy_score_into_setup_screen_string_loop &26a3 b9 16 00 LDA &0016,Y ; score_as_digits &26a6 99 7a 0c STA &0c7a,Y ; setup_screen_string + &4a # Copy score into game screen text &26a9 88 DEY &26aa 10 f7 BPL &26a3 ; copy_score_into_setup_screen_string_loop ; not_highest_score &26ac e0 08 CPX #&08 &26ae f0 1e BEQ &26ce ; skip_shuffling_high_scores &26b0 a9 8f LDA #&8f ; &058f = high_scores + &60 &26b2 85 72 STA &72 ; source_high_score_address_low &26b4 a9 9f LDA #&9f ; &059f = high_scores + &70 &26b6 85 74 STA &74 ; target_high_score_address_low ; shuffle_high_scores_rank_loop &26b8 a0 0c LDY #&0c ; shuffle_high_scores_digit_loop &26ba b1 72 LDA (&72),Y ; source_high_score_address &26bc 91 74 STA (&74),Y ; target_high_score_address &26be 88 DEY &26bf 10 f9 BPL &26ba ; shuffle_high_scores_digit_loop &26c1 38 SEC &26c2 a5 72 LDA &72 ; source_high_score_address_low &26c4 85 74 STA &74 ; target_high_score_address_low &26c6 e9 10 SBC #&10 &26c8 85 72 STA &72 ; source_high_score_address_low &26ca c5 70 CMP &70 ; high_score_address_low &26cc b0 ea BCS &26b8 ; shuffle_high_scores_rank_loop ; skip_shuffling_high_scores &26ce a0 05 LDY #&05 ; copy_score_into_high_score_table_loop &26d0 b9 16 00 LDA &0016,Y ; score_as_digits &26d3 91 70 STA (&70),Y ; high_score_address &26d5 88 DEY &26d6 10 f8 BPL &26d0 ; copy_score_into_high_score_table_loop &26d8 a9 0d LDA #&0d ; CR &26da a8 TAY &26db 91 70 STA (&70),Y ; high_score_address &26dd 88 DEY &26de a9 20 LDA #&20 ; " " ; wipe_high_score_name_loop &26e0 91 70 STA (&70),Y ; high_score_address &26e2 88 DEY &26e3 c0 06 CPY #&06 &26e5 d0 f9 BNE &26e0 ; wipe_high_score_name_loop &26e7 a5 70 LDA &70 ; high_score_address_low &26e9 18 CLC &26ea 69 07 ADC #&07 &26ec 8d 20 05 STA &0520 ; high_score_input_block ; skip_adding_high_score &26ef a2 00 LDX #&00 ; write_high_score_text_window_loop &26f1 bd 1b 05 LDA &051b,X ; high_score_text_window_string &26f4 20 ee ff JSR &ffee ; OSWRCH &26f7 e8 INX &26f8 e0 05 CPX #&05 &26fa d0 f5 BNE &26f1 ; write_high_score_text_window_loop &26fc a9 0c LDA #&0c ; CLS &26fe 20 ee ff JSR &ffee ; OSWRCH &2701 a2 40 LDX #&40 ; spiral_type_and_direction # Draw boxes from largest to smallest &2703 a0 00 LDY #&00 ; spiral_flags &2705 20 dd 2a JSR &2add ; draw_animated_spiral &2708 4c 1b 27 JMP &271b ; high_score_screen ; high_score_screen_after_wipe_and_delay &270b a9 19 LDA #&19 # Wait 25 frames &270d 85 23 STA &23 ; delay_count &270f 20 80 08 JSR &0880 ; wipe_screen # Positive to wipe screen with pattern &2712 a9 13 LDA #&13 ; Wait for vertical retrace ; delay_loop &2714 20 f4 ff JSR &fff4 ; OSBYTE &2717 c6 23 DEC &23 ; delay_count &2719 d0 f9 BNE &2714 ; delay_loop ; high_score_screen &271b a2 00 LDX #&00 ; write_high_score_table_loop &271d bd 25 05 LDA &0525,X ; high_score_table_string &2720 20 ee ff JSR &ffee ; OSWRCH &2723 e8 INX &2724 e0 8b CPX #&8b &2726 d0 f5 BNE &271d ; write_high_score_table_loop &2728 a2 01 LDX #&01 # Set colour 1 to cyan &272a a0 06 LDY #&06 ; C &272c 20 e7 0a JSR &0ae7 ; set_logical_colour &272f e8 INX ; 2 # Set colour 2 to white &2730 c8 INY ; 7, W &2731 20 e7 0a JSR &0ae7 ; set_logical_colour &2734 a9 12 LDA #&12 # GCOL 1, 128 (OR with background colour 0) &2736 20 ee ff JSR &ffee ; OSWRCH &2739 a9 01 LDA #&01 &273b 20 ee ff JSR &ffee ; OSWRCH &273e a9 80 LDA #&80 &2740 20 ee ff JSR &ffee ; OSWRCH &2743 24 7c BIT &7c ; new_high_score # Positive if no new high score &2745 10 52 BPL &2799 ; skip_entering_name &2747 a9 40 LDA #&40 # Enable cursor &2749 8d 35 0c STA &0c35 ; enable_or_disable_cursor_string + 3 &274c a2 00 LDX #&00 ; write_enable_cursor_loop &274e bd 32 0c LDA &0c32,X ; enable_or_disable_cursor_string &2751 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &2754 e8 INX &2755 e0 0a CPX #&0a &2757 d0 f5 BNE &274e ; write_enable_cursor_loop &2759 a2 00 LDX #&00 ; write_enter_a_name_loop &275b bd 30 09 LDA &0930,X ; enter_a_name_string &275e 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &2761 e8 INX &2762 e0 0f CPX #&0f &2764 d0 f5 BNE &275b ; write_enter_a_name_loop &2766 8a TXA ; &0f ; Flush input buffer &2767 20 f4 ff JSR &fff4 ; OSBYTE &276a a9 1f LDA #&1f # TAB(&13, (new_high_score_rank * 2) + 4) &276c 20 ee ff JSR &ffee ; OSWRCH &276f a9 13 LDA #&13 &2771 20 ee ff JSR &ffee ; OSWRCH &2774 a5 7b LDA &7b ; new_high_score_rank &2776 0a ASL A &2777 69 04 ADC #&04 &2779 20 ee ff JSR &ffee ; OSWRCH &277c a9 00 LDA #&00 ; Input line (INPUT) &277e a2 20 LDX #&20 ; &0520 = high_score_input_block &2780 a0 05 LDY #&05 &2782 20 f1 ff JSR &fff1 ; OSWORD # Get name into high score table &2785 ad 20 05 LDA &0520 ; high_score_input_block &2788 85 70 STA &70 ; high_score_address_low &278a a9 20 LDA #&20 ; " " &278c d0 03 BNE &2791 ; consider_padding_name # Always branches ; pad_name_loop &278e 91 70 STA (&70),Y ; high_score_address &2790 c8 INY ; consider_padding_name &2791 c0 06 CPY #&06 &2793 d0 f9 BNE &278e ; pad_name_loop &2795 a9 0d LDA #&0d ; CR &2797 91 70 STA (&70),Y ; high_score_address ; skip_entering_name &2799 a9 20 LDA #&20 # Disable cursor &279b 8d 35 0c STA &0c35 ; setup_screen_string + 5 &279e 8d 5a 02 STA &025a ; os_keyboard_status # Set SHIFT LOCK not engaged &27a1 a2 00 LDX #&00 &27a3 86 66 STX &66 ; last_key_pressed ; write_disable_cursor_loop &27a5 bd 32 0c LDA &0c32,X ; enable_or_disable_cursor_string + 3 &27a8 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &27ab e8 INX &27ac e0 0a CPX #&0a &27ae d0 f5 BNE &27a5 ; write_disable_cursor_loop ; write_press_space_fire_tab_or_k_loop &27b0 bd a6 05 LDA &05a6,X ; press_space_fire_tab_or_k_string - &a &27b3 20 ee ff JSR &ffee ; OSWRCH &27b6 e8 INX &27b7 e0 34 CPX #&34 &27b9 d0 f5 BNE &27b0 ; write_press_space_fire_tab_or_k_loop &27bb a9 40 LDA #&40 # Centre high score screen sparkler &27bd 8d 4a 1d STA &1d4a ; row_offset &27c0 a9 ea LDA #&ea ; NOP # Don't stop drawing line if it crosses another &27c2 8d e6 1d STA &1de6 ; consider_stopping_line &27c5 a9 60 LDA #&60 ; RTS # Suppress sprite plotting and unplotting &27c7 8d e4 13 STA &13e4 ; plot_or_unplot_sprites &27ca a9 80 LDA #&80 &27cc 85 8c STA &8c ; maximum_line_length &27ce a2 00 LDX #&00 ; initialise_high_score_screen_sparkler_lines_coordinates_loop &27d0 9d 00 01 STA &0100,X ; sparkler_lines_coordinates &27d3 e8 INX &27d4 e0 a0 CPX #&a0 ; initialise_high_score_screen_sparkler_lines_coordinates_loop &27d6 d0 f8 BNE &27d0 ; reset_sparkler_lines_coordinates &27d8 a2 0f LDX #&0f &27da 86 80 STX &80 ; frame_count ; initialise_high_score_screen_sparkler_coordinates_and_velocities_loop &27dc 95 c0 STA &c0,X &27de ca DEX &27df 10 fb BPL &27dc ; initialise_high_score_screen_sparkler_coordinates_and_velocities_loop &27e1 86 88 STX &88 ; two_sparklers # Set to negative to use two sparklers in demo mode &27e3 8e 6f 0b STX &0b6f ; timer_ready # Set to negative to plot immediately &27e6 e8 INX # Set to zero to indicate sparklers don't need updating &27e7 86 27 STX &27 ; sparklers_need_updating &27e9 86 ce STX &ce ; high_score_screen_sparkler_velocity_change_timer &27eb 86 5e STX &5e ; sparklers_line_to_use &27ed 86 5f STX &5f ; sparkler_stability_flags &27ef e8 INX &27f0 86 cf STX &cf ; high_score_screen_sparkler_line_to_use &27f2 a9 8f LDA #&8f &27f4 85 8d STA &8d ; sparkler_boundary_velocity_mask &27f6 85 8e STA &8e ; sparkler_random_velocity_mask &27f8 24 64 BIT &64 ; demo_mode # &40 set if previously in demo mode &27fa 70 2e BVS &282a ; skip_starting_music &27fc a9 f1 LDA #&f1 ; &2cf1 = high_score_music_data &27fe 85 2e STA &2e ; music_address_low &2800 a9 2c LDA #&2c ; &2c4b = high_score_screen_and_demo_event_handler &2802 85 2f STA &2f ; music_address_high &2804 8d 21 02 STA &0221 ; event_vector_high &2807 a9 4b LDA #&4b &2809 8d 20 02 STA &0220 ; event_vector_low &280c 8d a0 02 STA &02a0 ; os_countdown_timer + 4 &280f a2 ff LDX #&ff &2811 8e 9c 02 STX &029c ; os_countdown_timer &2814 8e 9d 02 STX &029d ; os_countdown_timer + 1 &2817 8e 9e 02 STX &029e ; os_countdown_timer + 2 &281a ca DEX ; &fe &281b 8e 9f 02 STX &029f ; os_countdown_timer + 3 &281e 8e c4 02 STX &02c4 ; os_event_enable_flags + 5 # Enable interval timer events &2821 a2 0c LDX #&0c &2823 8e 01 0b STX &0b01 ; channel_envelopes + 2 &2826 e8 INX &2827 8e 02 0b STX &0b02 ; channel_envelopes + 3 ; skip_starting_music ; high_score_screen_loop &282a 24 90 BIT &90 ; player_x &282c 10 0a BPL &2838 ; use_high_score_screen_sparkler # Use one sparkler if player ended to left of screen &282e 20 f6 1e JSR &1ef6 ; update_sparklers # Use two sparklers if player ended to right of screen &2831 a5 91 LDA &91 ; player_y &2833 85 5f STA &5f ; sparkler_stability_flags # If so, use player's vertical position to set stability &2835 4c 3b 28 JMP &283b ; after_updating_sparkler ; use_high_score_screen_sparkler &2838 20 61 06 JSR &0661 ; update_high_score_screen_sparkler ; after_updating_sparkler &283b 20 00 0a JSR &0a00 ; check_for_high_score_screen_keys # Returns carry set if space or fire pressed &283e 90 06 BCC &2846 ; space_or_fire_not_pressed &2840 20 db 28 JSR &28db ; reset_sparklers &2843 4c c5 28 JMP &28c5 ; leave_to_start_game ; space_or_fire_not_pressed &2846 e0 09 CPX #&09 ; TAB &2848 d0 e0 BNE &282a ; high_score_screen_loop &284a 20 db 28 JSR &28db ; reset_sparklers &284d 78 SEI &284e a9 13 LDA #&13 ; &2913 = demo_osword_handler # Suppress all sounds but music and sparkler hitting &2850 8d 0c 02 STA &020c ; osword_vector_low # boundary during demo &2853 a9 29 LDA #&29 &2855 8d 0d 02 STA &020d ; osword_vector_high &2858 58 CLI &2859 a2 ff LDX #&ff &285b 86 64 STX &64 ; demo_mode &285d 8e 33 0a STX &0a33 ; key_to_change_keys # Set to &ff to prevent changing of keys in demo &2860 e8 INX ; 0 &2861 86 10 STX &10 ; player_lives &2863 86 2d STX &2d ; scrolltext_offset ; write_demo_screen_setup_loop &2865 bd 00 05 LDA &0500,X ; demo_screen_setup_string &2868 20 d8 03 JSR &03d8 ; call_previous_oswrch_vector &286b e8 INX &286c e0 1b CPX #&1b &286e d0 f5 BNE &2865 ; write_demo_screen_setup_loop &2870 a9 07 LDA #&07 &2872 85 2c STA &2c ; scrolltext_pixel &2874 d0 05 BNE &287b ; start_demo_level_without_wiping_screen # Always branches ; start_demo_level &2876 a9 00 LDA #&00 # Zero to wipe screen with black &2878 20 80 08 JSR &0880 ; wipe_screen ; start_demo_level_without_wiping_screen &287b a2 00 LDX #&00 ; spiral_type_and_direction # Draw boxes from smallest to largest &287d 86 21 STX &21 ; demo_player_primary_direction # Set player direction to DIRECTION_UP to start demo &287f a0 04 LDY #&04 ; B # Set colour 0 to blue &2881 20 e7 0a JSR &0ae7 ; set_logical_colour &2884 a0 ff LDY #&ff ; spiral_flags # Then draw boxes from largest to smallest &2886 20 dd 2a JSR &2add ; draw_animated_spiral &2889 a9 02 LDA #&02 # Use level 3 parameters for demo level &288b 85 1c STA &1c ; level_as_offset &288d 20 c7 21 JSR &21c7 ; initialise_level_without_changing_colour_or_spiral &2890 a9 0d LDA #&0d # Use shorter sparklers &2892 85 8c STA &8c ; maximum_line_length &2894 a9 01 LDA #&01 # Slow tracers &2896 85 87 STA &87 ; tracer_speed ; demo_loop &2898 20 5e 1e JSR &1e5e ; update_scrolltext_after_resetting_timer &289b 20 00 0e JSR &0e00 ; update_game &289e a5 86 LDA &86 ; game_state &28a0 10 09 BPL &28ab ; demo_level_not_killed &28a2 20 8c 22 JSR &228c ; death_animation_without_shudder &28a5 e6 10 INC &10 ; player_lives # Demo mode has infinite lives &28a7 18 CLC &28a8 20 51 24 JSR &2451 ; start_life ; demo_level_not_killed &28ab c9 3f CMP #&3f ; PLAYER_WON_BY_SPLITTING &28ad d0 11 BNE &28c0 ; demo_level_not_split # Continue demo level until sparklers are split &28af a9 07 LDA #&07 ; BELL &28b1 20 ee ff JSR &ffee ; OSWRCH &28b4 a2 03 LDX #&03 &28b6 a9 10 LDA #&10 ; CLG ; write_clgs_loop &28b8 20 ee ff JSR &ffee ; OSWRCH &28bb ca DEX &28bc d0 fa BNE &28b8 ; write_clgs_loop &28be f0 b6 BEQ &2876 ; start_demo_level # Always branches ; demo_level_not_split &28c0 20 00 0a JSR &0a00 ; check_for_high_score_screen_keys # Returns carry set if space or fire pressed &28c3 90 2d BCC &28f2 ; continue_demo ; leave_to_start_game &28c5 a9 4b LDA #&4b ; "K" # Permit changing of keys &28c7 8d 33 0a STA &0a33 ; key_to_change_keys &28ca 78 SEI &28cb ad f2 02 LDA &02f2 ; previous_osword_vector_low # Enable sounds during game &28ce 8d 0c 02 STA &020c ; osword_vector_low &28d1 ad f3 02 LDA &02f3 ; previous_osword_vector_high &28d4 8d 0d 02 STA &020d ; osword_vector_high &28d7 58 CLI &28d8 4c 1c 26 JMP &261c ; start_game ; reset_sparklers &28db a9 80 LDA #&80 &28dd a2 10 LDX #&10 ; reset_sparklers_loop &28df 95 bf STA &bf,X ; sparkler_coordinates - 1 # Reset sparkler_coordinates and sparkler_velocities &28e1 ca DEX &28e2 d0 fb BNE &28df ; reset_sparklers_loop &28e4 8e 4a 1d STX &1d4a ; row_offset # Left align sparklers &28e7 a9 85 LDA #&85 ; STA # Permit sprite plotting and unplotting &28e9 8d e4 13 STA &13e4 ; plot_or_unplot_sprites &28ec a9 60 LDA #&60 ; NOP # Don't stop drawing line if it crosses another &28ee 8d e6 1d STA &1de6 ; consider_stopping_line ; leave &28f1 60 RTS ; continue_demo &28f2 e0 09 CPX #&09 ; TAB &28f4 f0 80 BEQ &2876 ; start_demo_level # Restart demo if TAB pressed &28f6 e0 50 CPX #&50 ; "P" &28f8 d0 03 BNE &28fd ; p_not_pressed_in_demo # Pause demo if P pressed &28fa 20 8b 0b JSR &0b8b ; pause_game ; p_not_pressed_in_demo &28fd 8a TXA &28fe 49 1b EOR #&1b ; ESCAPE &2900 d0 96 BNE &2898 ; demo_loop # Continue demo until ESCAPE pressed &2902 aa TAX ; 0 &2903 a8 TAY ; 0 &2904 a9 4b LDA #&4b ; "K" # Permit changing of keys &2906 8d 33 0a STA &0a33 ; key_to_change_keys &2909 86 7c STX &7c ; path_start_y &290b 20 e7 0a JSR &0ae7 ; set_logical_colour # Set colour 0 to black &290e 46 64 LSR &64 ; demo_mode # Clear &80 to indicate not in demo mode, set &40 to &2910 4c 0b 27 JMP &270b ; high_score_screen_after_wipe_and_delay # skip starting music on return to high score screen ; demo_osword_handler &2913 c9 07 CMP #&07 ; Generate a sound (SOUND) &2915 f0 da BEQ &28f1 ; leave # Suppress game sounds during demo &2917 4c d4 03 JMP &03d4 ; call_previous_osword_vector ; unused &291a 60 RTS &291b 60 RTS ; continue_wiping_screen &291c e6 22 INC &22 ; wipe_length &291e a6 22 LDX &22 ; wipe_length ; wipe_right_loop &2920 a5 20 LDA &20 ; wipe_address_low &2922 69 10 ADC #&10 # Move right eight pixels &2924 85 20 STA &20 ; wipe_address_low &2926 90 02 BCC &292a ; skip_overflow &2928 e6 21 INC &21 ; wipe_address_high ; skip_overflow &292a 20 10 0c JSR &0c10 ; wipe_part_of_screen # Returns X &292d d0 f1 BNE &2920 ; wipe_right_loop &292f a6 22 LDX &22 ; wipe_length ; wipe_up_loop &2931 a5 20 LDA &20 ; wipe_address_low &2933 e9 7f SBC #&7f # Move up eight pixels &2935 85 20 STA &20 ; wipe_address_low &2937 a5 21 LDA &21 ; wipe_address_high &2939 e9 02 SBC #&02 &293b 85 21 STA &21 ; wipe_address_high &293d 20 10 0c JSR &0c10 ; wipe_part_of_screen # Returns X &2940 d0 ef BNE &2931 ; wipe_up_loop &2942 e6 22 INC &22 ; wipe_length &2944 a6 22 LDX &22 ; wipe_length &2946 e0 20 CPX #&20 &2948 90 02 BCC &294c ; wipe_left_loop &294a ca DEX &294b 18 CLC ; wipe_left_loop &294c a5 20 LDA &20 ; wipe_address_low &294e e9 0f SBC #&0f # Move left eight pixels &2950 85 20 STA &20 ; wipe_address_low &2952 b0 02 BCS &2956 ; skip_underflow &2954 c6 21 DEC &21 ; wipe_address_high ; skip_underflow &2956 20 10 0c JSR &0c10 ; wipe_part_of_screen # Returns X &2959 d0 f1 BNE &294c ; wipe_left_loop &295b a6 22 LDX &22 ; wipe_length &295d e0 20 CPX #&20 &295f 90 01 BCC &2962 ; wipe_down_loop &2961 60 RTS ; wipe_down_loop &2962 a5 20 LDA &20 ; wipe_address_low &2964 69 80 ADC #&80 # Move down eight pixels &2966 85 20 STA &20 ; wipe_address_low &2968 a5 21 LDA &21 ; wipe_address_high &296a 69 02 ADC #&02 &296c 85 21 STA &21 ; wipe_address_high &296e 20 10 0c JSR &0c10 ; wipe_part_of_screen &2971 d0 ef BNE &2962 ; wipe_down_loop &2973 f0 a7 BEQ &291c ; continue_wiping_screen # Always branches ; level_data ; 87 88 89 8a 8b 8c 8d 8e 8f # &87 tracer_speed ; ts 2s t1 t2 t3 ll bv rv ls # &00 = fast, &01 = slow &2975 01 00 e0 f0 e0 50 87 87 34 ; level 1 # &88 two_sparklers &297e 01 ff e0 e8 e0 3c 87 87 34 ; level 2 # &00 = one sparkler, &ff = two sparklers &2987 00 ff d0 d8 e0 3c 8a 87 34 ; level 3 # &89 timer_interval &2990 01 00 e0 d8 d8 64 8a 8a 30 ; level 4 # speed of first section of time bar &2999 00 00 d8 e8 e0 c8 87 8b 30 ; level 5 # &8a second_timer_interval &29a2 01 ff e0 d8 d8 32 8a 8b 30 ; level 6 # speed of second section of time bar &29ab 01 ff d0 e0 d8 64 8b 87 30 ; level 7 # &8b third_timer_interval &29b4 00 00 c0 d0 e0 46 8a 8a 2c ; level 8 # speed of third section of time bar &29bd 01 00 fc fc 90 64 8a 8b 2c ; level 9 # &8c maximum_line_length &29c6 01 ff d0 e0 d0 28 87 8e 28 ; level 10 # maximum length of sparkler(s) &29cf 00 ff c0 c0 e0 50 8a 8b 28 ; level 11, 21, 31, ... # &8d sparkler_boundary_velocity_mask &29d8 01 ff d0 d0 d0 32 8a 8e 24 ; level 12, 22, 32, ... # &8e sparkler_random_velocity_mask &29e1 00 00 fc b0 c0 46 8a 8e 24 ; level 13, 23, 33, ... # maximum speed of sparkler(s) &29ea 01 ff d0 d0 d0 3c 8b 8f 24 ; level 14, 24, 34, ... # &8f level_speed &29f3 00 00 f0 f0 e0 32 8b 8b 24 ; level 15, 25, 35, ... # overall game speed &29fc 00 00 c0 d0 d0 50 8b 8f 20 ; level 16, 26, 36, ... &2a05 00 ff c0 d0 d0 32 8b 8f 20 ; level 17, 27, 37, ... &2a0e 01 00 e0 e0 d0 32 8b 92 20 ; level 18, 28, 38, ... &2a17 01 ff e0 e0 d0 1e 8b 92 20 ; level 19, 29, 39, ... &2a20 00 ff fc fc 80 28 8b 8f 20 ; level 20, 30, 40, ... ; sprite_data ; player_sprite_even_frame_0 &2a29 00 88 00 11 cc 00 22 22 00 44 11 00 cc 11 88 ; player_sprite_odd_frame_0 &2a38 00 22 00 00 77 00 00 88 88 11 00 44 33 00 66 ; player_sprite_even_frame_1 &2a47 00 08 00 01 84 00 12 c2 00 34 e1 00 7c f9 08 ; player_sprite_odd_frame_1 &2a56 00 02 00 00 27 00 00 7e 08 01 f0 84 13 f2 c6 ; fuse_sprite_even_frame_0 &2a65 ee 33 88 22 22 00 22 22 00 33 e6 00 10 c0 00 ; fuse_sprite_odd_frame_0 &2a74 33 88 ee 00 88 88 00 88 88 00 fd 88 00 70 00 ; fuse_sprite_even_frame_1 &2a83 88 00 88 88 00 88 ff 77 88 11 c4 00 10 c0 00 ; fuse_sprite_odd_frame_1 &2a92 22 00 22 22 00 22 33 dd ee 00 75 00 00 70 00 ; tracer_sprite_even_frame_0 &2aa1 11 cc 00 11 4c 00 11 4c 00 ff 7f 88 8f 07 88 ; tracer_sprite_odd_frame_0 &2ab0 00 77 00 00 57 00 00 57 00 33 df ee 23 0d 2e ; tracer_sprite_even_frame_1 &2abf cc 11 88 ae 23 88 57 57 00 23 ae 00 11 cc 00 ; tracer_sprite_odd_frame_1 &2ace 33 00 66 23 88 ae 11 5d 4c 00 af 88 00 77 00 ; draw_animated_spiral &2add a9 ff LDA #&ff &2adf 85 8c STA &8c ; maximum_line_length &2ae1 a9 01 LDA #&01 &2ae3 85 0a STA &0a ; spiral_plot_count &2ae5 84 f9 STY &f9 ; spiral_flags &2ae7 8a TXA &2ae8 85 f8 STA &f8 ; spiral_type_and_direction &2aea 30 79 BMI &2b65 ; draw_spiral_crosses # If direction has &80 set, draw spiral crosses ; draw_spiral_boxes # Otherwise, draw spiral boxes &2aec a9 ea LDA #&ea ; NOP # Don't stop drawing line if it crosses another &2aee 8d e6 1d STA &1de6 ; consider_stopping_line &2af1 a9 70 LDA #&70 ; COLOUR_3_OFFSET # Use colour 3 to draw line &2af3 8d ea 1d STA &1dea ; line_colour_offset ; draw_spiral_boxes_plot_loop &2af6 a2 00 LDX #&00 # If &40 unset, start with smallest section of spiral &2af8 24 f8 BIT &f8 ; spiral_type_and_direction &2afa 50 02 BVC &2afe ; draw_spiral_loop &2afc a2 2c LDX #&2c # If &40 set, start with largest section of spiral ; draw_spiral_boxes_loop &2afe 86 0b STX &0b ; spiral_count &2b00 bd f1 2b LDA &2bf1,X ; spirals_x &2b03 85 0c STA &0c ; spiral_x1 &2b05 85 50 STA &50 ; line_start_x # Move to (spirals_x[count], spirals_y[count]) &2b07 49 ff EOR #&ff &2b09 85 0d STA &0d ; spiral_x2 &2b0b a8 TAY &2b0c bd 1e 2c LDA &2c1e,X ; spirals_y &2b0f 85 0e STA &0e ; spiral_y1 &2b11 85 51 STA &51 ; line_start_y &2b13 aa TAX &2b14 49 ff EOR #&ff &2b16 85 0f STA &0f ; spiral_y2 &2b18 20 ca 1c JSR &1cca ; draw_line # Draw to (spirals_y[count], -spirals_x[count]) &2b1b a6 0d LDX &0d ; spiral_x2 &2b1d a4 0f LDY &0f ; spiral_y2 &2b1f 20 ca 1c JSR &1cca ; draw_line # Draw to (-spirals_x[count], -spirals_y[count]) &2b22 a6 0f LDX &0f ; spiral_y2 &2b24 a4 0c LDY &0c ; spiral_x1 &2b26 20 ca 1c JSR &1cca ; draw_line # Draw to (-spirals_y[count], spirals_x[count]) &2b29 a6 0c LDX &0c ; spiral_x1 &2b2b a4 0e LDY &0e ; spiral_y1 &2b2d 20 ca 1c JSR &1cca ; draw_line # Draw to (spirals_x[count], spirals_y[count]) &2b30 a6 0b LDX &0b ; spiral_count &2b32 24 f8 BIT &f8 ; spiral_type_and_direction &2b34 50 05 BVC &2b3b ; not_reversed ; is_reversed &2b36 ca DEX &2b37 10 c5 BPL &2afe ; draw_spiral_boxes_loop &2b39 30 05 BMI &2b40 ; consider_next_plot # Always branches ; not_reversed &2b3b e8 INX &2b3c e0 2d CPX #&2d &2b3e d0 be BNE &2afe ; draw_spiral_loop ; consider_next_plot &2b40 c6 0a DEC &0a ; spiral_plot_count &2b42 30 0b BMI &2b4f ; finished &2b44 24 f9 BIT &f9 ; spiral_flags # If flags has &80 set, reverse direction for unplotting &2b46 10 04 BPL &2b4c ; to_draw_spiral_plot_loop &2b48 a9 40 LDA #&40 # Set &40 to start with largest section of spiral &2b4a 85 f8 STA &f8 ; spiral_type_and_direction ; to_draw_spiral_boxes_plot_loop &2b4c 4c f6 2a JMP &2af6 ; draw_spiral_boxes_plot_loop ; finished &2b4f 24 f8 BIT &f8 ; spiral_type_and_direction # If direction has &40 set, don't draw edge boxes &2b51 70 07 BVS &2b5a ; skip_edge_boxes &2b53 24 f9 BIT &f9 ; spiral_flags # If flags has &40 set, don't draw edge boxes &2b55 70 03 BVS &2b5a ; skip_edge_boxes &2b57 20 b0 2b JSR &2bb0 ; draw_spiral_edge_boxes ; skip_edge_boxes &2b5a a9 60 LDA #&60 : RTS # Stop drawing line if it crosses another &2b5c 8d e6 1d STA &1de6 ; consider_stopping_line &2b5f a9 7c LDA #&7c ; COLOUR_1_OFFSET # Use colour 1 to draw line &2b61 8d ea 1d STA &1dea ; line_colour_offset &2b64 60 RTS ; draw_spiral_crosses &2b65 a2 00 LDX #&00 ; draw_spiral_crosses_loop &2b67 86 0b STX &0b ; spiral_count &2b69 a9 20 LDA #&20 &2b6b 8d 6f 0b STA &0b6f ; timer_ready # Set to positive to wait for next timer event &2b6e 8d 68 fe STA &fe68 ; User VIA timer 2 counter LSB &2b71 8d 69 fe STA &fe69 ; User VIA timer 2 counter MSB &2b74 bd f1 2b LDA &2bf1,X ; spirals_x &2b77 85 0c STA &0c ; spiral_x1 &2b79 85 50 STA &50 ; line_start_x # Move to (spirals_x[count], spirals_y[count]) &2b7b 49 ff EOR #&ff &2b7d 85 0d STA &0d ; spiral_x2 &2b7f bd 1e 2c LDA &2c1e,X ; spirals_y &2b82 85 0e STA &0e ; spiral_y1 &2b84 85 51 STA &51 ; line_start_y &2b86 49 ff EOR #&ff &2b88 85 0f STA &0f ; spiral_y2 &2b8a a8 TAY &2b8b a6 0d LDX &0d ; spiral_x2 &2b8d 20 ca 1c JSR &1cca ; draw_line # Draw to (-spiral_x[count], -spirals_y[count]) &2b90 a5 0e LDA &0e ; spiral_y1 &2b92 85 50 STA &50 ; line_start_x # Move to (spirals_y[count], -spirals_x[count]) &2b94 a5 0d LDA &0d ; spiral_x2 &2b96 85 51 STA &51 ; line_start_y &2b98 a6 0f LDX &0f ; spiral_y2 &2b9a a4 0c LDY &0c ; spiral_x1 &2b9c 20 ca 1c JSR &1cca ; draw_line # Draw to (-spirals_y[count], spirals_x[count]) ; wait_for_timer &2b9f 2c 6f 0b BIT &0b6f ; timer_ready # Negative after timer event &2ba2 10 fb BPL &2b9f ; wait_for_timer &2ba4 a6 0b LDX &0b ; spiral_count &2ba6 e8 INX &2ba7 e0 2d CPX #&2d &2ba9 d0 bc BNE &2b67 ; draw_spiral_crosses_loop &2bab c6 0a DEC &0a ; spiral_plot_count &2bad 10 b6 BPL &2b65 ; draw_spiral_crosses &2baf 60 RTS ; draw_spiral_edge_boxes &2bb0 a9 01 LDA #&01 # Plot, then unplot edge_boxes &2bb2 85 0a STA &0a ; spiral_plot_count ; draw_spiral_edge_boxes_plot_loop &2bb4 a9 e6 LDA #&e6 &2bb6 85 0b STA &0b ; box_x1 &2bb8 49 ff EOR #&ff &2bba 85 0c STA &0c ; box_x2 ; draw_spiral_edge_boxes_loop &2bbc a5 0b LDA &0b ; box_x1 &2bbe 85 50 STA &50 ; line_start_x # Move to (box_x1, box_x1) &2bc0 85 51 STA &51 ; line_start_y &2bc2 a8 TAY &2bc3 a6 0c LDX &0c ; box_x2 &2bc5 20 ca 1c JSR &1cca ; draw_line # Draw to (box_x2, box_x1) &2bc8 a6 0c LDX &0c ; box_x2 &2bca a4 0c LDY &0c ; box_x2 &2bcc 20 ca 1c JSR &1cca ; draw_line # Draw to (box_x2, box_x2) &2bcf a6 0b LDX &0b ; box_x1 &2bd1 a4 0c LDY &0c ; box_x2 &2bd3 20 ca 1c JSR &1cca ; draw_line # Draw to (box_x1, box_x2) &2bd6 a6 0b LDX &0b ; box_x1 &2bd8 a4 0b LDY &0b ; box_x1 &2bda 20 ca 1c JSR &1cca ; draw_line # Draw to (box_x1, box_x1) &2bdd a5 0b LDA &0b ; box_x1 &2bdf 18 CLC &2be0 69 05 ADC #&05 &2be2 85 0b STA &0b ; box_x1 &2be4 49 ff EOR #&ff &2be6 85 0c STA &0c ; box_x2 &2be8 c9 05 CMP #&05 &2bea d0 d0 BNE &2bbc ; draw_spiral_edge_boxes_loop &2bec c6 0a DEC &0a ; spiral_plot_count &2bee 10 c4 BPL &2bb4 ; draw_spiral_edge_boxes_plot_loop &2bf0 60 RTS ; spirals_x &2bf1 81 84 87 8b 8e 91 94 96 97 98 98 96 93 90 8b 85 &2c01 7e 76 6d 64 5b 52 48 40 38 31 2c 27 25 24 26 29 &2c11 2f 36 40 4c 59 68 78 89 9b ad bf d1 e1 ; spirals_y &2c1e 80 82 82 81 80 7e 7a 76 72 6d 67 61 5c 56 51 4d &2c2e 4a 47 46 46 48 4b 50 56 5e 67 71 7d 89 97 a4 b2 &2c3e bf cc d8 e2 eb f3 f8 fa fb f8 f4 ec e1 ; high_score_screen_and_demo_event_handler &2c4b 08 PHP &2c4c 48 PHA &2c4d c9 04 CMP #&04 ; vsync event &2c4f d0 03 BNE &2c54 ; update_high_score_screen_and_demo_music # Branches if interval timer event &2c51 4c 2b 15 JMP &152b ; v-sync_handler ; update_high_score_screen_and_demo_music &2c54 8a TXA &2c55 48 PHA &2c56 98 TYA &2c57 48 PHA &2c58 a9 ff LDA #&ff &2c5a 8d 9c 02 STA &029c ; os_countdown_timer &2c5d 8d 9d 02 STA &029d ; os_countdown_timer + 1 &2c60 8d 9e 02 STA &029e ; os_countdown_timer + 2 &2c63 8d 9f 02 STA &029f ; os_countdown_timer + 3 &2c66 a9 f8 LDA #&f8 &2c68 8d a0 02 STA &02a0 ; os_countdown_timer + 4 ; get_byte_of_music_data &2c6b a0 00 LDY #&00 &2c6d b1 2e LDA (&2e),Y ; music_address &2c6f c9 ff CMP #&ff # &ff marks end of music data &2c71 d0 0a BNE &2c7d ; skip_looping &2c73 a9 6f LDA #&6f ; &2d6f = high_score_music_data + &6e # Skip intro when looping music &2c75 85 2e STA &2e ; music_address_low &2c77 a9 2d LDA #&2d &2c79 85 2f STA &2f ; music_address_high &2c7b d0 ee BNE &2c6b ; get_byte_of_music_data # Always branches ; skip_looping &2c7d aa TAX # 84...... ........ channel high &2c7e 2a ROL A &2c7f 2a ROL A &2c80 2a ROL A &2c81 29 03 AND #&03 &2c83 8d a9 0a STA &0aa9 ; sound_11 + 1 (channel high) &2c86 8a TXA # ..21.... ........ channel low &2c87 29 30 AND #&30 &2c89 4a LSR A &2c8a 4a LSR A &2c8b 4a LSR A &2c8c 4a LSR A &2c8d 8d a8 0a STA &0aa8 ; sound_11 + 0 (channel low) &2c90 69 04 ADC #&04 # Consider sound output buffer for channel &2c92 49 ff EOR #&ff &2c94 aa TAX &2c95 a0 ff LDY #&ff &2c97 a9 80 LDA #&80 ; Read I/O device or buffer status &2c99 20 f4 ff JSR &fff4 ; OSBYTE &2c9c 8a TXA &2c9d f0 4b BEQ &2cea ; skip_note # Don't play note if channel isn't ready &2c9f a0 00 LDY #&00 &2ca1 b1 2e LDA (&2e),Y ; music_address &2ca3 29 0f AND #&0f # ....8421 ........ duration &2ca5 c9 0d CMP #&0d &2ca7 d0 02 BNE &2cab ; not_0d &2ca9 a9 18 LDA #&18 # &0d = &18, &0f = &30, other values used as is ; not_0d &2cab c9 0f CMP #&0f &2cad d0 02 BNE &2cb1 ; not_0f &2caf a9 30 LDA #&30 ; not_0f &2cb1 0a ASL A &2cb2 8d ae 0a STA &0aae ; sound_11 + 6 (duration low) &2cb5 ae a8 0a LDX &0aa8 ; sound_11 + 0 (channel low) &2cb8 c8 INY &2cb9 b1 2e LDA (&2e),Y ; music_address # ........ 84218421 pitch &2cbb c9 01 CMP #&01 &2cbd d0 0b BNE &2cca ; not_setting_envelope # &01 to set envelope from duration &2cbf ad ae 0a LDA &0aae ; sound_11 + 6 (duration low) &2cc2 4a LSR A &2cc3 69 0a ADC #&0a # Music uses envelopes 11 onwards &2cc5 9d ff 0a STA &0aff,X ; channel_envelopes &2cc8 90 15 BCC &2cdf ; move_to_next_pair_of_bytes # Always branches ; not_setting_envelope &2cca 8d ac 0a STA &0aac ; sound_11 + 4 (pitch low) &2ccd a8 TAY # &00 for silence &2cce f0 03 BEQ &2cd3 ; is_silence &2cd0 bd ff 0a LDA &0aff,X ; channel_envelopes ; is_silence &2cd3 8d aa 0a STA &0aaa ; sound_11 + 2 (volume low) &2cd6 a2 a8 LDX #&a8 ; &0aa8 = sound_11 &2cd8 a0 0a LDY #&0a &2cda a9 07 LDA #&07 ; Generate a sound (SOUND) &2cdc 20 d4 03 JSR &03d4 ; call_previous_osword_vector # Play sound for music ; move_to_next_pair_of_bytes &2cdf 18 CLC &2ce0 a5 2e LDA &2e ; music_address_low &2ce2 69 02 ADC #&02 &2ce4 85 2e STA &2e ; music_address_low &2ce6 90 02 BCC &2cea ; skip_page &2ce8 e6 2f INC &2f ; music_address_high ; skip_page ; skip_note &2cea 68 PLA &2ceb a8 TAY &2cec 68 PLA &2ced aa TAX &2cee 68 PLA &2cef 28 PLP &2cf0 60 RTS ; high_score_music_data &2cf1 22 3d 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 3d &2d01 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 49 21 49 &2d11 21 49 22 59 22 65 22 59 22 49 22 49 21 49 21 49 &2d21 22 59 22 65 22 59 22 49 22 21 21 21 21 21 22 2d &2d31 22 3d 22 2d 22 21 22 21 21 21 21 21 22 2d 22 3d &2d41 22 2d 22 21 22 2d 21 2d 21 2d 22 3d 22 49 22 3d &2d51 22 2d 22 2d 21 2d 21 2d 22 3d 22 49 22 3d 22 2d &2d61 22 3d 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 29 &2d71 21 29 21 29 22 39 22 45 22 39 22 29 24 01 34 01 &2d81 14 01 92 59 a2 49 b2 3d 92 59 a2 49 b2 3d 92 59 &2d91 a2 49 b2 3d 92 59 a2 49 b2 3d 92 59 a2 49 b2 3d &2da1 92 59 a2 49 b2 3d 92 29 a2 39 b2 45 92 29 a2 39 &2db1 b2 45 92 29 a2 39 b2 45 92 29 a2 39 b2 45 91 29 &2dc1 a2 39 b2 45 11 01 16 59 23 01 35 01 9c 6d a2 3d &2dd1 bc 0d 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 3d &2de1 21 3d 21 3d 22 49 96 75 b6 00 a2 59 22 49 22 3d &2df1 9c 79 bc 19 a2 49 21 49 21 49 22 59 22 65 22 59 &2e01 22 49 22 49 21 49 21 49 22 59 96 89 b6 00 a2 65 &2e11 22 59 22 49 9c 81 bc 21 a2 21 21 21 21 21 22 2d &2e21 22 3d 22 2d 22 21 22 21 21 21 21 21 22 2d 96 6d &2e31 b6 00 a2 3d 22 2d 22 21 9c 6d bc 2d a2 2d 21 2d &2e41 21 2d 22 3d 22 49 22 3d 22 2d 22 2d 21 2d 21 2d &2e51 22 3d 96 9d b6 00 a2 49 22 3d 22 2d 9c 9d bc 0d &2e61 a2 3d 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 3d &2e71 21 3d 21 3d 22 49 96 9d b6 00 a2 59 22 49 22 3d &2e81 9c 95 bc 19 a2 49 21 49 21 49 22 59 22 65 22 59 &2e91 22 49 22 49 21 49 21 49 22 59 96 89 b6 00 a2 65 &2ea1 22 59 22 49 9d 89 bc 29 a2 29 21 29 21 29 22 39 &2eb1 22 45 22 39 22 29 22 29 21 29 21 29 22 39 22 45 &2ec1 22 39 22 29 22 29 21 29 21 29 22 39 22 45 22 39 &2ed1 22 29 22 29 21 29 21 29 22 39 93 9d b6 00 a2 45 &2ee1 13 9d 22 39 22 29 9c 9d bc 0d a2 3d 21 3d 21 3d &2ef1 22 49 22 59 22 49 22 3d 22 3d 21 3d 21 3d 22 49 &2f01 96 75 b6 00 a2 59 22 49 22 3d 9c 79 bc 19 a2 49 &2f11 21 49 21 49 22 59 22 65 22 59 22 49 22 49 21 49 &2f21 21 49 22 59 96 89 b6 00 a2 65 22 59 22 49 96 81 &2f31 b6 21 a2 21 21 21 21 21 22 2d 96 6d b6 00 a2 3d &2f41 22 2d 22 21 96 6d b6 00 a2 21 21 21 21 21 22 2d &2f51 96 6d b6 00 a2 3d 22 2d 22 21 9c 6d bc 2d a2 2d &2f61 21 2d 21 2d 22 3d 22 49 22 3d 22 2d 22 2d 21 2d &2f71 21 2d 22 3d 96 6d b6 00 a2 49 22 3d 22 2d 9c 6d &2f81 bc 0d a2 3d 21 3d 21 3d 22 49 22 59 22 49 22 3d &2f91 22 3d 21 3d 21 3d 22 49 96 6d b6 00 a2 59 22 49 &2fa1 22 3d 9c 69 bc 29 a2 29 21 29 21 29 22 35 22 45 &2fb1 22 35 22 29 96 59 b6 00 a2 29 21 29 21 29 22 35 &2fc1 96 69 b6 00 a2 45 22 35 22 29 34 01 9c 6d bf 29 &2fd1 a2 3d 21 3d 21 3d 22 49 22 59 22 49 22 3d 22 29 &2fe1 21 29 21 29 22 39 22 45 22 39 22 29 22 3d 21 3d &2ff1 21 3d 22 49 22 59 22 49 22 3d &2ffb ff ; unused &2ffc 41 41 00 00 # &6200 - &6bff is used unrelocated ; title_screen &6200 a2 ff LDX #&ff &6202 9a TXS &6203 e8 INX ; 0 &6204 86 85 STX &85 ; use_joystick # Set to positive to not use joystick by default ; write_press_space_or_fire_loop &6206 bd 00 3a LDA &3a00,X ; press_space_or_fire_string &6209 20 ee ff JSR &ffee ; OSWRCH &620c a9 00 LDA #&00 &620e 9d 00 3a STA &3a00,X ; press_space_or_fire_string # Wipe before copy to &0800 - &0817 &6211 e8 INX &6212 e0 18 CPX #&18 &6214 d0 f0 BNE &6206 ; write_press_space_or_fire_loop ; wait_for_space_or_fire &6216 a9 80 LDA #&80 ; Read I/O device or buffer status &6218 a2 00 LDX #&00 ; joystick buttons &621a 20 f4 ff JSR &fff4 ; OSBYTE &621d 8a TXA &621e 4a LSR A &621f 90 06 BCC &6227 ; fire_not_pressed &6221 c6 85 DEC &85 ; use_joystick # Set to negative to use joystick &6223 a2 02 LDX #&02 # Sample joystick &6225 d0 0e BNE &6235 ; set_maximum_adc_channel # Always branches ; fire_not_pressed &6227 a9 81 LDA #&81 ; Scan for a particular key &6229 a0 ff LDY #&ff &622b a2 9d LDX #&9d ; SPACE &622d 20 f4 ff JSR &fff4 ; OSBYTE &6230 8a TXA &6231 10 e3 BPL &6216 ; wait_for_space_or_fire &6233 a2 00 LDX #&00 ; no ADC sampling takes place # Ignore joystick ; set_maximum_adc_channel &6235 a9 10 LDA #&10 ; Set maximum number of ADC channel &6237 20 f4 ff JSR &fff4 ; OSBYTE &623a 78 SEI &623b a9 0f LDA #&0f &623d a2 00 LDX #&00 &623f 8e c4 02 STX &02c4 ; os_event_enable_flags + 5 # Disable interval timer events &6242 86 70 STX &70 ; source_address_low &6244 86 72 STX &72 ; target_address_low &6246 20 f4 ff JSR &fff4 ; OSBYTE &6249 a9 35 LDA #&35 &624b 85 71 STA &71 ; source_address_high &624d a9 03 LDA #&03 &624f 85 73 STA &73 ; target_address_high &6251 a0 80 LDY #&80 ; move_3580_to_61ff_loop # Move &3580 - &61ff to &0380 - &2fff &6253 b1 70 LDA (&70),Y ; source_address &6255 91 72 STA (&72),Y ; target_address &6257 c8 INY &6258 d0 f9 BNE &6253 ; move_3500_to_61ff_loop &625a e6 71 INC &71 ; source_address_high &625c e6 73 INC &73 ; target_address_high &625e a5 73 LDA &73 ; target_address_high &6260 c9 30 CMP #&30 &6262 d0 ef BNE &6253 ; move_3500_to_61ff_loop &6264 a9 a0 LDA #&a0 # Enable interrupts for User VIA timer 2 &6266 8d 6e fe STA &fe6e ; User VIA interrupt enable register &6269 a2 00 LDX #&00 # One shot timers for timer 1 and timer 2 &626b 8e 6b fe STX &fe6b ; User VIA auxiliary control register &626e 86 5e STX &5e ; title_screen_sound_block + 6 (duration low) &6270 86 5f STX &5f ; title_screen_sound_block + 7 (duration high) &6272 86 64 STX &64 ; demo_mode # Set to zero to indicate not in demo mode &6274 86 66 STX &66 ; last_key_pressed &6276 86 90 STX &90 ; player_x &6278 a9 01 LDA #&01 &627a 85 81 STA &81 ; tracer_frame &627c 85 82 STA &82 ; previous_tracer_frame &627e a9 53 LDA #&53 &6280 85 b8 STA &b8 ; rnd_state &6282 a9 b5 LDA #&b5 &6284 85 b9 STA &b9 ; rnd_state + 1 &6286 a9 49 LDA #&49 &6288 85 ba STA &ba ; rnd_state + 2 &628a ad 96 02 LDA &0296 ; os_system_clock + 4 &628d 85 bb STA &bb ; rnd_state + 3 &628f ad 95 02 LDA &0295 ; os_system_clock + 3 &6292 85 bc STA &bc ; rnd_state + 4 &6294 ad b7 02 LDA &02b7 ; os_most_recent_analogue_value_low + 1 &6297 85 bd STA &bd ; rnd_state + 5 &6299 ad bb 02 LDA &02bb ; os_most_recent_analogue_value_high + 1 &629c 85 be STA &be ; rnd_state + 6 &629e a9 c8 LDA #&c8 ; ' &62a0 85 6b STA &6b ; key_up &62a2 a9 c2 LDA #&c2 ; X &62a4 85 6c STA &6c ; key_right &62a6 a9 e1 LDA #&e1 ; Z &62a8 85 6d STA &6d ; key_left &62aa a9 e8 LDA #&e8 ; / &62ac 85 6e STA &6e ; key_down &62ae a9 c9 LDA #&c9 ; ENTER &62b0 85 6f STA &6f ; key_draw &62b2 a9 60 LDA #&60 ; &0b60 = irq2_handler &62b4 8d 06 02 STA &0206 ; irq2_vector_low &62b7 a9 0b LDA #&0b &62b9 8d 07 02 STA &0207 ; irq2_vector_high &62bc a9 b0 LDA #&b0 ; &0cb0 = oswrch_handler &62be 8d 0e 02 STA &020e ; oswrch_vector_low &62c1 a9 0c LDA #&0c &62c3 8d 0f 02 STA &020f ; oswrch_vector_high &62c6 a9 5c LDA #&5c ; &065c = insv_handler &62c8 8d 2a 02 STA &022a ; insv_vector_low &62cb a9 06 LDA #&06 &62cd 8d 2b 02 STA &022b ; insv_vector_high &62d0 58 CLI &62d1 a9 09 LDA #&09 ; Set first colour duration &62d3 a2 0f LDX #&0f &62d5 20 f4 ff JSR &fff4 ; OSBYTE &62d8 a9 0a LDA #&0a ; Set second colour duration &62da a2 0f LDX #&0f &62dc 20 f4 ff JSR &fff4 ; OSBYTE &62df a9 0b LDA #&0b ; Set auto-repeat delay &62e1 a2 00 LDX #&00 &62e3 20 f4 ff JSR &fff4 ; OSBYTE &62e6 a9 e5 LDA #&e5 ; Write ESCAPE key status &62e8 a2 01 LDX #&01 ; insert ASCII value, don't cause escape condition &62ea a0 00 LDY #&00 &62ec 20 f4 ff JSR &fff4 ; OSBYTE &62ef a9 db LDA #&db ; Write ASCII code for TAB &62f1 a2 09 LDX #&09 &62f3 a0 00 LDY #&00 &62f5 20 f4 ff JSR &fff4 ; OSBYTE &62f8 a9 03 LDA #&03 ; Memory cleared on next reset, normal ESCAPE effect &62fa 8d 58 02 STA &0258 ; ESCAPE/BREAK effect &62fd 4c 1c 26 JMP &261c ; start_game ; entry_point &6300 78 SEI &6301 a2 05 LDX #&05 ; store_previous_vector_addresses_loop &6303 bd 0a 02 LDA &020a,X ; os_vector_table + &a &6306 9d f0 02 STA &02f0,X ; previous_vector_addresses &6309 ca DEX &630a 10 f7 BPL &6303 ; store_previous_vector_addresses_loop &630c ad 2a 02 LDA &022a ; insv_vector_low &630f 8d f6 02 STA &02f6 ; previous_insv_vector_low &6312 ad 2b 02 LDA &022b ; insv_vector_high &6315 8d f7 02 STA &02f7 ; previous_insv_vector_high &6318 a9 16 LDA #&16 # Change to MODE 7 &631a 20 ee ff JSR &ffee ; OSWRCH &631d a9 07 LDA #&07 &631f 20 ee ff JSR &ffee ; OSWRCH &6322 a9 0a LDA #&0a # R10: Cursor start register &6324 8d 00 fe STA &fe00 ; video register number &6327 a9 20 LDA #&20 # Disable cursor &6329 8d 01 fe STA &fe01 ; video register value &632c a2 00 LDX #&00 ; copy_title_screen_data_loop &632e bd 00 68 LDA &6800,X ; title_screen_data &6331 9d 00 7c STA &7c00,X ; screen_memory &6334 bd 00 69 LDA &6900,X ; title_screen_data + &100 &6337 9d 00 7d STA &7d00,X ; screen_memory + &100 &633a bd 00 6a LDA &6a00,X ; title_screen_data + &200 &633d 9d 00 7e STA &7e00,X ; screen_memory + &200 &6340 bd 00 6b LDA &6b00,X ; title_screen_data + &300 &6343 9d 00 7f STA &7f00,X ; screen_memory + &300 &6346 e8 INX &6347 d0 e5 BNE &632e ; copy_title_screen_data_loop &6349 20 e0 35 JSR &35e0 ; define_character_e1 &634c a9 48 LDA #&48 &634e 8d 64 02 STA &0264 ; os_bell_envelope &6351 8a TXA ; 0 &6352 a2 09 LDX #&09 ; disable_events_loop &6354 9d bf 02 STA &02bf,X ; os_event_enable_flags &6357 ca DEX &6358 10 fa BPL &6354 ; disable_events_loop &635a a2 0f LDX #&0f ; remove_roms_loop &635c 95 50 STA &50,X ; title_screen_channel_envelopes # Also wipes title_screen_sound_block &635e 9d a1 02 STA &02a1,X ; os_paged_rom_type_table # Remove paged ROMs from ROM information table &6361 ca DEX &6362 10 f8 BPL &635c ; remove_roms_loop &6364 a8 TAY ; 0 &6365 8c 63 02 STY &0263 ; os_bell_channel &6368 8c 65 02 STY &0265 ; os_bell_frequency &636b 8c 7d 02 STY &027d ; os_cursor_editing_status &636e c8 INY ; 1 &636f 84 51 STY &51 ; title_screen_channel_envelopes + 1 &6371 84 52 STY &52 ; title_screen_channel_envelopes + 2 &6373 8c 66 02 STY &0266 ; os_bell_duration &6376 c8 INY ; 2 &6377 84 53 STY &53 ; title_screen_channel_envelopes + 3 &6379 86 2c STX &2c ; scrolltext_pixel &637b 86 64 STX &64 ; demo_mode &637d 8e 9c 02 STX &029c ; os_countdown_timer &6380 8e 9d 02 STX &029d ; os_countdown_timer + 1 &6383 8e 9e 02 STX &029e ; os_countdown_timer + 2 &6386 8e 9f 02 STX &029f ; os_countdown_timer + 3 &6389 a9 88 LDA #&88 ; &6488 = title_screen_music_data &638b 85 2e STA &2e ; music_address_low &638d a9 64 LDA #&64 &638f 85 2f STA &2f ; music_address_high &6391 a9 b6 LDA #&b6 ; &63b6 = title_screen_event_handler &6393 8d 20 02 STA &0220 ; event_vector_low &6396 a9 63 LDA #&63 &6398 8d 21 02 STA &0221 ; event_vector_high &639b a2 2f LDX #&2f ; copy_envelope_data_loop &639d bd 4e 64 LDA &644e,X ; title_screen_envelope_data &63a0 9d c0 08 STA &08c0,X ; os_envelope_storage &63a3 ca DEX &63a4 10 f7 BPL &639d ; copy_envelope_data_loop &63a6 8e a0 02 STX &02a0 ; os_countdown_timer + 4 &63a9 8e c4 02 STX &02c4 ; os_event_enable_flags + 5 # Enable interval timer events &63ac 58 CLI &63ad a9 14 LDA #&14 ; Implode user defined character font RAM &63af e8 INX ; 0 &63b0 20 f4 ff JSR &fff4 ; OSBYTE &63b3 4c 00 62 JMP &6200 ; title_screen ; title_screen_event_handler &63b6 08 PHP &63b7 48 PHA &63b8 8a TXA &63b9 48 PHA &63ba 98 TYA &63bb 48 PHA &63bc a9 ff LDA #&ff &63be 8d 9c 02 STA &029c ; os_countdown_timer &63c1 8d 9d 02 STA &029d ; os_countdown_timer + 1 &63c4 8d 9e 02 STA &029e ; os_countdown_timer + 2 &63c7 8d 9f 02 STA &029f ; os_countdown_timer + 3 &63ca a9 f6 LDA #&f6 &63cc 8d a0 02 STA &02a0 ; os_countdown_timer + 4 ; get_byte_of_music_data &63cf a0 00 LDY #&00 &63d1 b1 2e LDA (&2e),Y ; music_address &63d3 c9 ff CMP #&ff # &ff marks end of music data &63d5 d0 0a BNE &63e1 ; skip_restarting &63d7 a9 88 LDA #&88 ; &6488 = title_screen_music_data &63d9 85 2e STA &2e ; music_address_low &63db a9 64 LDA #&64 &63dd 85 2f STA &2f ; music_address_high &63df d0 ee BNE &63cf ; get_byte_of_music_data ; skip_restarting &63e1 aa TAX # 8....... ........ channel high &63e2 29 80 AND #&80 &63e4 2a ROL A &63e5 2a ROL A &63e6 2a ROL A &63e7 85 59 STA &59 ; title_screen_sound_block + 1 (channel high) &63e9 8a TXA # ...18421 ........ duration &63ea 29 1f AND #&1f &63ec 0a ASL A &63ed 0a ASL A &63ee 85 5e STA &5e ; title_screen_sound_block + 6 (duration low) &63f0 8a TXA # .42..... ........ channel low &63f1 29 60 AND #&60 &63f3 4a LSR A &63f4 4a LSR A &63f5 4a LSR A &63f6 4a LSR A &63f7 4a LSR A &63f8 85 58 STA &58 ; title_screen_sound_block (channel low) &63fa 69 04 ADC #&04 # Consider sound output buffer for channel &63fc 49 ff EOR #&ff &63fe aa TAX &63ff a0 ff LDY #&ff &6401 a9 80 LDA #&80 &6403 20 f4 ff JSR &fff4 ; OSBYTE &6406 8a TXA &6407 f0 2c BEQ &6435 ; skip_note # Don't play note if channel isn't ready &6409 a0 01 LDY #&01 &640b b1 2e LDA (&2e),Y ; music_address # ........ 84218421 pitch &640d 85 5c STA &5c ; title_screen_sound_block + 4 (pitch low) &640f a6 58 LDX &58 ; title_screen_sound_block (channel) &6411 c8 INY &6412 a5 5e LDA &5e ; title_screen_sound_block + 6 (duration low) &6414 d0 06 BNE &641c ; not_setting_envelope # If duration is zero, set envelope from pitch &6416 a5 5c LDA &5c ; title_screen_sound_block + 4 (pitch low) &6418 95 50 STA &50,X ; title_screen_channel_envelopes &641a d0 11 BNE &642d ; move_to_next_pair_of_bytes # Always branches ; not_setting_envelope &641c a5 5c LDA &5c ; title_screen_sound_block + 4 (pitch low) # &00 for silence &641e f0 02 BEQ &6422 ; is_silence &6420 b5 50 LDA &50,X ; title_screen_channel_envelopes ; is_silence &6422 85 5a STA &5a ; title_screen_sound_block + 2 (volume low) &6424 a2 58 LDX #&58 ; &0058 = title_screen_sound_block &6426 a0 00 LDY #&00 &6428 a9 07 LDA #&07 ; Generate a sound (SOUND) &642a 20 f1 ff JSR &fff1 ; OSWORD ; move_to_next_pair_of_bytes &642d e6 2e INC &2e ; music_address_low &642f e6 2e INC &2e ; music_address_low &6431 d0 02 BNE &6435 ; skip_page &6433 e6 2f INC &2f ; music_address_high ; skip_page ; skip_note &6435 a5 ec LDA &ec; os_most_recently_pressed_key &6437 c9 90 CMP #&90 ; Q &6439 d0 05 BNE &6440 ; q_not_pressed &643b a9 01 LDA #&01 # Set to non-zero to disable sound &643d 8d 62 02 STA &0262 ; os_sound_suppression ; q_not_pressed &6440 49 d1 EOR #&d1 ; S &6442 d0 03 BNE &6447 ; s_not_pressed &6444 8d 62 02 STA &0262 ; os_sound_suppression # Set to zero to enable sound ; s_not_pressed &6447 68 PLA &6448 a8 TAY &6449 68 PLA &644a aa TAX &644b 68 PLA &644c 28 PLP &644d 60 RTS ; title_screen_envelope_data &644e 01 00 00 00 00 00 00 12 f6 ff ff 7e 64 00 00 00 &645e 01 00 00 00 00 00 00 7f d6 00 ff 5a 3c 00 00 00 &646e 01 00 00 00 00 00 00 12 f6 00 ff 6e 5a 00 00 00 ; unused &647e 18 00 3c 66 60 60 60 66 3c 00 ; title_screen_music_data &6488 a4 75 c4 00 e1 45 61 61 61 6d 61 69 a2 75 c2 00 &6498 e1 59 61 61 a1 91 c1 81 e1 45 a3 91 c3 81 e1 61 &64a8 61 59 61 61 61 4d a1 91 c1 00 e1 51 a3 7d c3 00 &64b8 e1 3d 61 59 61 3d a1 81 c1 00 e1 45 a2 7d c2 00 &64c8 e1 4d 61 59 ac 75 cc 00 e1 45 61 61 61 6d 61 69 &64d8 61 59 61 61 61 45 61 61 61 59 61 61 61 4d 61 59 &64e8 61 51 61 61 a2 91 c2 81 e1 6d 61 61 a2 9d c2 91 &64f8 e1 51 61 61 a4 a5 c4 81 e1 45 61 61 61 75 61 61 &6508 a2 9d c2 81 e1 45 61 61 a2 91 c2 81 e1 51 61 6d &6518 a2 99 c2 89 e1 59 61 69 a2 89 c2 00 e1 45 61 69 &6528 b2 91 d2 81 e1 45 61 61 61 6d 61 69 61 59 61 61 &6538 61 75 61 61 61 59 61 61 61 4d 61 51 61 45 61 61 &6548 61 6d 61 69 61 59 61 61 61 45 61 61 61 59 61 61 &6558 a2 a5 c2 00 e1 4d 61 51 a4 a5 c4 81 e1 45 61 61 &6568 61 75 61 61 a2 a5 c2 81 e1 45 61 61 a2 9d c4 91 &6578 e1 51 61 61 61 6d 61 61 a2 91 c2 00 e1 6d 61 61 &6588 a2 91 c2 00 e1 51 61 61 a2 89 c2 00 e1 4d 61 59 &6598 a2 81 c2 00 e1 45 61 51 ac 7d c1 00 e1 3d 61 59 &65a8 61 6d 61 59 61 51 61 59 61 4d 61 59 61 45 61 59 &65b8 61 3d 61 59 a2 75 c2 00 e1 45 61 51 61 61 61 51 &65c8 a2 91 c2 00 e1 45 61 51 a4 89 c4 00 e1 3d 61 4d &65d8 61 59 61 4d a2 81 c2 00 e1 45 61 51 a2 7d c2 00 &65e8 e1 3d 61 4d a2 75 c2 00 e1 45 61 51 a2 6d c2 00 &65f8 e1 4d 61 59 b8 75 d8 00 e1 45 61 61 61 6d 61 69 &6608 61 59 61 61 61 45 61 61 61 59 61 61 61 4d 61 51 &6618 61 45 61 61 61 6d 61 69 61 59 61 61 61 45 61 61 &6628 61 59 61 61 61 4d 61 51 a2 75 c2 00 e1 45 61 61 &6638 a2 75 c2 00 e1 6d 61 69 a2 75 c2 00 e1 59 61 61 &6648 a2 91 c2 75 e1 45 61 61 a2 91 c2 00 e1 59 61 61 &6658 a2 91 c2 00 e1 4d 61 51 a2 7d c2 00 e1 3d 61 59 &6668 e1 3d a2 81 c2 00 61 45 a2 7d c2 00 e1 4d 61 59 &6678 ac 75 cc 00 e1 45 61 61 61 6d 61 69 61 59 61 61 &6688 61 45 61 61 61 59 61 61 61 4d 61 59 61 51 61 61 &6698 a2 91 c2 81 e1 6d 61 61 a2 9d c2 91 e1 51 61 61 &66a8 a4 a5 c4 81 e1 45 61 61 61 75 61 61 a2 9d c2 81 &66b8 e1 45 61 61 a2 91 c2 81 e1 51 61 6d a2 99 c2 89 &66c8 e1 59 61 69 a2 89 c2 00 e1 75 61 69 a2 9d c2 91 &66d8 e1 45 61 61 20 03 40 03 a2 a5 c2 00 e1 6d 61 69 &66e8 a2 9d c2 00 e1 59 61 61 a2 99 c2 00 e1 45 61 61 &66f8 a2 a5 c2 91 e1 59 61 61 a2 99 c2 00 e1 4d 61 59 &6708 a2 9d c2 00 e1 45 61 51 a2 99 c2 00 e1 59 61 61 &6718 a2 ad c2 89 e1 59 61 4d a4 a5 c2 91 e1 45 61 51 &6728 61 59 61 61 20 01 40 01 a2 a5 c2 00 e1 59 61 51 &6738 a4 a5 c4 81 e1 45 61 61 61 75 61 61 a2 a5 c2 81 &6748 e1 45 61 61 a2 9d c4 91 e1 51 61 61 61 3d 61 61 &6758 a2 91 c2 00 e1 3d 61 61 a2 91 c2 00 e1 51 61 61 &6768 a2 89 c2 00 e1 4d 61 59 a2 81 c2 00 e1 45 61 51 &6778 ac 7d c1 00 e1 3d 61 4d 61 59 61 4d 61 51 61 59 &6788 61 3d 61 59 61 45 61 59 61 3d 61 59 a2 75 c2 00 &6798 e1 45 61 51 61 61 61 51 a2 91 c2 00 e1 45 61 51 &67a8 a4 89 c4 00 e1 3d 61 4d 61 59 61 4d a2 81 c2 00 &67b8 e1 45 61 51 a2 7d c2 00 e1 3d 61 4d a2 75 c2 00 &67c8 e1 45 61 51 a2 6d c2 00 e1 4d 61 59 b2 75 d2 00 &67d8 e1 45 61 61 61 59 61 61 61 51 61 61 61 45 61 61 &67e8 61 59 61 61 61 4d 61 51 61 45 61 61 61 6d 61 69 &67f8 61 59 61 61 &67fc ff ; unused &67fd 00 00 00 ; title_screen_data &6800 84 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. " &6810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".... K I X " &6820 20 20 20 20 20 20 20 20 83 9d 81 8d 20 20 20 20 ; ".... K I X " &6830 20 20 20 20 20 20 20 20 20 4b 20 49 20 58 20 20 ; "..Written by AGA Music by RHAA " &6840 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. " &6850 83 9d 81 8d 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. .Try to fill as much as you can ! " &6860 20 4b 20 49 20 58 20 20 20 20 20 20 20 20 20 20 ; ".. .75% is enough,but not very good. " &6870 20 20 20 20 20 20 20 20 84 84 57 72 69 74 74 65 ; ".. .(See DEMO for Scorings) " &6880 6e 20 62 79 20 41 47 41 20 20 20 20 20 20 20 4d ; ".. " &6890 75 73 69 63 20 62 79 20 52 48 41 41 20 20 20 20 ; "...&&&&&&&&&&&&&&&&&&))))))))))))))))) " &68a0 84 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. .Play with Joystick or Keys : " &68b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. .LEFT: 'Z' ` RIGHT: 'X' " &68c0 20 20 20 20 20 20 20 20 84 9d 20 87 54 72 79 20 ; ".. .UP : '*' ` DOWN : '?' " &68d0 74 6f 20 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 ; ".. .DRAW: 'RETURN' " &68e0 61 73 20 79 6f 75 20 63 61 6e 20 21 20 20 20 20 ; ".. .HOLD DRAW-KEY ] SLOW " &68f0 84 9d 20 87 37 35 25 20 69 73 20 65 6e 6f 75 67 ; ".. .RELEASE DRAW-KEY ] QUICK " &6900 68 2c 62 75 74 20 6e 6f 74 20 76 65 72 79 20 67 ; ".. .>> Keys are user-definable << " &6910 6f 6f 64 2e 20 20 20 20 84 9d 20 20 20 20 87 28 ; ".. " &6920 53 65 65 20 44 45 4d 4f 20 66 6f 72 20 53 63 6f ; ".. . P =PAUSE on ; O =PAUSE off " &6930 72 69 6e 67 73 29 20 20 20 20 20 20 20 20 20 20 ; ".. . S =SOUND on ; Q =SOUND off " &6940 84 9d 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; ".. .ESCAPE=END GAME or DEMO " &6950 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ; "...ddddddddddddddddd888888888888888888 " &6960 20 20 20 20 20 20 20 20 84 9d 93 26 26 26 26 26 ; " " &6970 26 26 26 26 26 26 26 26 26 26 26 26 26 29 29 29 ; " " &6980 29 29 29 29 29 29 29 29 29 29 29 29 29 29 20 20 ; " " &6990 84 9d 20 20 82 50 6c 61 79 20 77 69 74 68 20 4a ; ".. " &69a0 6f 79 73 74 69 63 6b 20 6f 72 20 4b 65 79 73 20 &69b0 3a 20 20 20 20 20 20 20 84 9d 20 20 20 82 4c 45 &69c0 46 54 3a 20 27 5a 27 20 20 20 60 20 20 20 52 49 &69d0 47 48 54 3a 20 27 58 27 20 20 20 20 20 20 20 20 &69e0 84 9d 20 20 20 82 55 50 20 20 3a 20 27 2a 27 20 &69f0 20 20 60 20 20 20 44 4f 57 4e 20 3a 20 27 3f 27 &6a00 20 20 20 20 20 20 20 20 84 9d 20 20 20 82 44 52 &6a10 41 57 3a 20 27 52 45 54 55 52 4e 27 20 20 20 20 &6a20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6a30 84 9d 20 20 20 82 48 4f 4c 44 20 44 52 41 57 2d &6a40 4b 45 59 20 20 20 20 5d 20 53 4c 4f 57 20 20 20 &6a50 20 20 20 20 20 20 20 20 84 9d 20 20 20 82 52 45 &6a60 4c 45 41 53 45 20 44 52 41 57 2d 4b 45 59 20 5d &6a70 20 51 55 49 43 4b 20 20 20 20 20 20 20 20 20 20 &6a80 84 9d 20 20 85 3e 3e 20 4b 65 79 73 20 61 72 65 &6a90 20 75 73 65 72 2d 64 65 66 69 6e 61 62 6c 65 20 &6aa0 3c 3c 20 20 20 20 20 20 84 9d 20 20 20 20 20 20 &6ab0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6ac0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6ad0 84 9d 20 20 20 82 20 20 20 50 20 20 3d 50 41 55 &6ae0 53 45 20 6f 6e 20 3b 20 20 4f 20 20 3d 50 41 55 &6af0 53 45 20 6f 66 66 20 20 84 9d 20 20 20 20 82 20 &6b00 20 53 20 20 3d 53 4f 55 4e 44 20 6f 6e 20 3b 20 &6b10 20 51 20 20 3d 53 4f 55 4e 44 20 6f 66 66 20 20 &6b20 84 9d 20 20 20 82 45 53 43 41 50 45 3d 45 4e 44 &6b30 20 47 41 4d 45 20 6f 72 20 44 45 4d 4f 20 20 20 &6b40 20 20 20 20 20 20 20 20 84 9d 93 64 64 64 64 64 &6b50 64 64 64 64 64 64 64 64 64 64 64 64 38 38 38 38 &6b60 38 38 38 38 38 38 38 38 38 38 38 38 38 38 20 20 &6b70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6b90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6bb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6bc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 &6be0 20 20 20 20 20 20 20 20 84 9d 20 20 20 20 20 20 &6bf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20