Code
CurtainsOpening_5_advance_task_state CurtainsOpening_5_set_current_ppu_command_index_and_advance_task_state OnNMI OnReset absolute_value action_timer_gte_16_odd add_16bit_to_byte_CE add_mask_to_play_sound_0 add_play_sound_2 add_screen_status_to_unlocked_door_directions add_value_to_sub_rupees adjust_walk_state advance_lighting_room_state_and_return after_setting_some_frame_state apply_damage_from_own_fire apply_damage_to_enemy apply_damage_to_gohma apply_knockback aquamentus_shoot_fireball armos_ghini_update_sprite_and_check_hits audio_play_boss_roar audio_unknown_1 audio_unknown_2 audio_unknown_3 audio_unknown_4 audio_unknown_5 audio_unknown_6 audio_unknown_6_handle_music audio_unknown_6a audio_unknown_6b audio_unknown_6c audio_unknown_6d audio_unknown_6e audio_unknown_6f audio_unknown_6g audio_unknown_7 audio_update blue_wizzrobe_action_timer_at_1_frame blue_wizzrobe_action_timer_at_1_frame_xxx bomb_upgrade_check_link_position call_digdogger_state call_jump_table call_scrolling_1_task_thunk call_sub_164F6_with_previous_unlocked_door_directions call_update_curtain_from_rom2 cellar_increase_task_state_and_copy_ppu_data change_background_tile_at_current_object_position change_direction change_enemy_direction_based_on_flags check_attack_arrow check_attack_beam_sword_rod check_attack_bomb_or_fire check_attack_boomerang check_attack_sword check_beam_sword_or_rod check_boomerang_sound check_boss_roar check_create_zola check_door check_door_entry check_dungeon_shoot_fireball check_enemy_hits check_fire_projectile check_for_cellar_exit check_has_compass_in_current_dungeon check_has_map_in_current_dungeon check_hitbox check_hitbox_with_specified_size check_if_dark check_if_darknut check_if_item_selection_is_valid check_if_old_man_hit check_if_overworld_secret_should_exist check_if_room_cleared check_if_room_is_dark check_if_spawn_is_near_link check_if_spawn_is_near_link_or_in_solid_object check_if_stepped_onto_entrance check_if_walked_onto_screen_boundary check_if_walked_onto_screen_boundary_cellar check_invincibility_frames_palette_shift check_link_hit_by_enemy check_link_hit_by_projectile check_lost_woods_code check_object_against_screen_bounding_box_both check_object_against_screen_bounding_box_both_or_walking_state check_object_against_screen_bounding_box_x check_object_against_screen_bounding_box_y check_object_collision check_object_collision_0x13 check_old_man_hit_and_update_sprite check_overworld_bomb_or_fire_secret_hitbox check_overworld_map_history check_push_blocks check_remove_ladder check_screen_boundary_movement check_sram check_walked_to_screen_boundary_not_link check_weapon_hit check_weapon_hit_1 check_weapon_hit_2 check_zol_or_gel_hits clear_game_mode_task_and_state clear_knockback clear_knockback2 clear_ladder_and_player_projectiles clear_nametables clear_oam clear_overworld_room_object_info clear_ppu_data clear_ppumask clear_recorder_whirlwind clear_room_tiles_to_var_10 clear_screen_history_and_clear_force_beam_sword clear_some_enemy_state clear_some_oam_sprites clear_store_flag_show_rupee_icon clear_task_state clear_usually_zero clear_weapon_state collect_floor_item collect_floor_item_max collect_floor_item_not_add continue_check_attack_arrow continue_check_attack_beam_sword_rod continue_setup convert_number_to_string copy_background_column_to_ppu copy_door_or_bomb_sprite_data copy_dungeon_data copy_hearts copy_some_ppu_data copy_sprite_data_1 copy_sprite_data_2 copy_store_ppu_command_buffer create_delete_save_handle_changing_items create_delete_save_helper create_enemy create_fireball_near_object create_moblin_octorok_lynel_projectile create_object_at_another_object create_object_at_another_object_2 create_object_at_another_object_with_slot create_recorder_whirlwind_at_A create_recorder_whirlwind_at_link create_save_handle_dpad create_save_handle_dpad_helper create_save_update_sprites_1 create_save_update_sprites_1a create_save_update_sprites_2 deactivate_clock_and_walk_state decrease_enemy_speed decrease_invincibility_frames decrement_16bit_var4_by_1 decrement_projectile_count_and_delete_enemy delete_enemy despawn_object despawn_object_thunk despawn_secret_block_and_change_background_tile disable_greyscale divide_by_10 do_update_monster_over_0x6A dodongo_check_bomb_distance dodongo_check_hits_and_death dodongo_check_hits_for_one_side dodongo_check_nearby_bombs dodongo_set_killed_and_play_sound dodongo_set_state_4_to_0_and_clear_weapon_state dodongo_update_sprites dodongo_walk_state_0_walking dodongo_walk_state_1_ate_bomb dodongo_walk_state_1_state_0 dodongo_walk_state_2_stunned_by_bomb_explosion dungeon_get_item_position dungeon_get_screen_code dungeon_only_handle_secrets_and_shutters dungeon_only_update_door_background enemy_damage enemy_killed exit_dungeon_after_triforce_fanfare find_direction_with_diagonals_for_object find_last_available_object_idx finish_object_bounds_check fire_wizzrobe_beam flip_horizontally from_spawn_ghini_from_tombs ganon_1_waiting_for_action_timer ganon_set_var_0_to_ganon_x_minus_value ganon_set_var_0_to_ganon_x_plus_value ganon_set_var_0_to_ganon_y_minus_value ganon_set_var_0_to_ganon_y_plus_value get_bouncy_object_type get_dungeon_door_sprite_ptr get_dungeon_door_type get_dungeon_ppu_data_0_ptr get_dungeon_ppu_data_1_ptr get_gleeok_neck_pointers get_movement_position get_next_spawn_from_side_position get_opposite_direction_and_index get_room_status_floor_item_picked_up get_screen_status give_item gleeok_update_sprites_and_spawn_flying_heads handle_bomb_greyscale_flash handle_bomb_greyscale_flash_thunk handle_door_Bomb handle_door_Door handle_door_LockedDoor handle_door_Push handle_door_ShutterDoor handle_door_Wall handle_open_doors_in_dungeon_room handle_potion_fairy_refill handle_recorder_lake_door handle_spawning_armos_ghini_on_touch increase_enemy_speed increase_or_decrease_recorder_idx increment_16bit_var0_by_1 increment_16bit_var0_by_A increment_16bit_var2_by_1 increment_16bit_var2_by_A increment_16bit_var4_by_1 increment_16bit_var4_by_A increment_game_mode increment_task_state_and_return increment_work_value_and_return_2 init_fairy_drop init_memory init_ppuscroll init_sram_code initial_vsync_1 initial_vsync_2 intro_text_end_pause intro_text_finish intro_text_first_scroll intro_text_item_scroll intro_text_item_scroll_0 intro_text_item_scroll_1 intro_text_item_scroll_2 intro_text_item_scroll_3 intro_text_item_scroll_3a intro_text_item_scroll_3b intro_text_pause_for_big_text inverse is_health_full jump_from_update_monster_moblin jump_from_update_monster_octorok keese_set_direction_to_y link_swing_sword load_money_making_game_sign lock_movement_to_dungeon_door mark_finished_and_increase_store_state mark_map_location_visited mark_overworld_secret_opened_and_despawn_secret mark_room_item_collected mirror_horizontally no_pending_rupees_to_subtract not_game_mode_9 not_in_create_save old_man_message_1 old_man_message_2 old_man_message_3_death_mountain open_doors_and_spawn_room_item pick_up_five_rupee pick_up_ganon_triforce pick_up_ganon_triforce_thunk pick_up_heart pick_up_heart_container pick_up_item pick_up_other pick_up_per_dungeon_item pick_up_rupee pick_up_rupee_thunk pick_up_something pick_up_something_thunk play_boss_pain_sound_after_hit play_boss_sound_1 play_boss_sound_1_if_not_state_0 play_fairy_sound play_secret_sound play_shield_ting play_sound_on_channel ppu_work_after_sprite_0_hit prevent_item_and_sword_when_near_screen_edge process_movement raft_location_1 raft_location_2 randomly_rotate_movement_by_45_degrees recorder_call_whirlwind remove_like_like_or_wall_master_holding_link_sprite reset_animation_frame_update_link_sprite_and_check_ladder reset_monster_state_after_npc_action_timers reset_room_state reset_sprite_index_to_zero return_wall_unpassable reverse_direction_1 reverse_direction_2 reverse_walking_direction reverse_walking_direction_if_out_of_bounds reverse_walking_direction_if_out_of_bounds2 rom0_OnReset rom0_set_mmc_control_register rom0_set_prg_bank rom1_OnReset rom1_set_mmc_control_register rom1_set_prg_bank rom2_OnReset rom2_set_mmc_control_register rom2_set_prg_bank rom3_OnReset rom3_copy_data_to_ppu rom3_copy_data_to_ppu_with_size rom3_get_ppu_data_1_ptr_and_size rom3_set_mmc_control_register rom3_set_prg_bank rom4_OnReset rom4_set_mmc_control_register rom4_set_prg_bank rom5_OnReset rom5_set_mmc_control_register rom5_set_prg_bank rom6_OnReset rom6_set_mmc_control_register rom6_set_prg_bank room_handler_ganon_triforce_opens_doors room_handler_killing_enemies_opens_doors room_handler_master_enemy_opens_doors room_handler_master_enemy_opens_doors_and_kills_everything room_handler_push_block_opens_doors room_handler_push_block_shows_staircase rope_handle_movement_changes rotate_90_degrees_randomly run_game_mode_task0 run_game_mode_task1 save_new_monster_state_from_Y screen_status_bit_set_X screen_status_clear_bit_X select_potion send_current_ppu_command send_ppu_data send_ppu_data_after_picking_up_ganon_triforce send_ppu_data_inner send_start_menu_map_ppu_commands send_start_menu_map_ppu_commands_helper send_start_menu_ppu_commands set_0x20_in_oam_data set_copy_to_0x67F0 set_copy_to_0x687E set_copy_to_0x6B7E set_current_ppu_command_index_and_advance_task_state set_enemy_killed set_enemy_spawn_state_to_spawned set_enemy_state_4_and_6 set_enemy_state_6_to_1 set_enemy_state_6_to_A set_falling_rock_moving_down set_game_mode_finish_scroll set_game_mode_title_state_1 set_item_Y_to_A set_mmc_control_register set_next_palette_cycle_and_advance_task_state set_next_sprite_index set_next_sprite_index_after_A set_oam_sprite_0_after_hud set_object_type_and_enemy_properties set_position_for_hitbox_check set_prg_bank set_required_door_direction set_state_thunk set_tile_attributes_to_palette_3 set_tile_walking_onto_1 set_tile_walking_onto_2 set_tile_walking_onto_3 set_var0_to_current_tile_data set_var_0_to_object_position set_var_15_to_0 setup_door_or_bomb_wall_background_update setup_dungeon setup_dungeon_data setup_dungeon_only_sprites setup_dungeon_screen_attr setup_gleeok_middle_neck_sprites setup_minimap_triforce_position setup_minimap_triforce_position_if_holding_compass setup_minimap_triforce_position_unless_in_cellar_or_whirlwind setup_mugging_item_sprites setup_rom1_sprite_data setup_rom2_sprite_data setup_room_items setup_screen_bounds setup_sprite setup_sprites_ganon_moldorm_lanmola setup_store_item_sprites show_menu_1_overworld show_menu_2 show_menu_3 show_menu_4 show_menu_5 show_menu_6_7_overworld_sub show_menu_6_dungeon show_menu_6_overworld show_menu_7_dungeon show_menu_7_overworld show_menu_8 show_menu_8_1 show_menu_8_2 show_menu_8_2_1 show_menu_9 simple_update_sprite skip_walk_update snap_to_tile spawn_aquamentus spawn_armos_or_ghini spawn_blocking_npc spawn_blue_keese spawn_bubble spawn_darknut spawn_default spawn_digdogger_1 spawn_digdogger_3 spawn_dodongo spawn_event spawn_falling_rock spawn_falling_rocks_spawner spawn_ganon spawn_gel2 spawn_gel_from_zol spawn_gleeok spawn_gleeok_flying_head spawn_gohma spawn_hungry_goriya spawn_hungry_goriya_main spawn_lake_fairy spawn_lanmola spawn_leever spawn_manhandla spawn_moldorm spawn_monster_basic spawn_monster_fast_octorok spawn_monster_no_timer_no_spawn_cloud spawn_monster_octorok_or_ghini_master spawn_old_man spawn_old_man_main spawn_old_man_mugger spawn_old_man_mugger_main spawn_patra spawn_peahat spawn_projectile spawn_recorder_pond_daemon spawn_red_keese spawn_rope spawn_tektite spawn_ten_rupee spawn_unknown_0x54 spawn_wall_trap spawn_zelda start_GameMode_PrepareScroll start_opening_key_or_bomb_door start_task1 stop_audio_and_clear_nametables stop_sounds stop_walking_to_top_half_of_screen store_A_in_tile_attributes store_A_to_object_direction_and_walking_directions store_A_to_walking_directions store_animation_frame store_enemy_death store_palette_2_in_tile_attributes store_ppu_command_index_and_increase_store_state store_speed_and_update_movement store_state_0 store_state_2_can_pick_up store_state_4 store_state_5_picked_up_item store_state_disappearing_after_purchase store_state_text_scroll sub_10082 sub_106DF1 sub_10704A sub_10706F sub_1070AB sub_1070C3 sub_107116 sub_10713C sub_107570 sub_10790C sub_107C96 sub_11262 sub_118736 sub_1187F7 sub_11A200 sub_11E58 sub_11E9D sub_11F2C sub_11F4B sub_12285 sub_14130 sub_143D7 sub_14484 sub_14501 sub_14E99 sub_15029 sub_1529D sub_16434 sub_164F6 sub_167C1 sub_167F1 sub_168C4 sub_16924 sub_169F4 sub_16ABF sub_16AF1 sub_16B30 sub_16B73 sub_16BC4 sub_16C16 sub_170C3 sub_171BB sub_17560 sub_1F229 sub_1F90D sub_9D2A sub_A307 sub_A351 sub_A35D sub_A3C8 sub_A3E1 sub_A437 sub_A764 sub_A80C sub_ABB8 switch_to_exiting_cellar switch_to_rotate_90_degrees task0_CreateDeleteSave task0_CreateDeleteSave_setup_some_sprite task0_CurtainsOpening task0_CurtainsOpening_0 task0_CurtainsOpening_1 task0_CurtainsOpening_2 task0_CurtainsOpening_3 task0_CurtainsOpening_4 task0_CurtainsOpening_5 task0_CurtainsOpening_6 task0_CurtainsOpening_7 task0_CurtainsOpening_8 task0_EndCredits task0_EnteringDoor task0_ExitingCellar task0_ExitingCellar_1 task0_ExitingCellar_2 task0_ExitingCellar_4 task0_ExitingCellar_6 task0_ExitingCellar_8 task0_ExitingOverworldCellar task0_ExitingOverworldCellar_3 task0_FinishedEnteringDoor_4_increase_task_state task0_FinishingScroll task0_FinishingTransition_setup_room task0_FinishingTransition_setup_room_overworld task0_FinishingTransition_state_0 task0_FoundZelda task0_FoundZelda_0 task0_FoundZelda_1 task0_FoundZelda_2 task0_FoundZelda_2_0 task0_FoundZelda_3 task0_FoundZelda_4 task0_GameOverMenu task0_InDungeonCellar task0_InDungeonCellar_1 task0_InDungeonCellar_2 task0_InDungeonCellar_3 task0_InDungeonCellar_5 task0_InDungeonCellar_6 task0_InDungeonCellar_8 task0_InDungeonCellar_9 task0_InOverworldCellar task0_InOverworldCellar_0 task0_InOverworldCellar_1 task0_InOverworldCellar_3 task0_InOverworldCellar_4 task0_InOverworldCellar_5 task0_InOverworldCellar_6 task0_InOverworldCellar_7 task0_InOverworldCellar_8 task0_JustDied task0_LoadDungeon task0_LoadDungeon_0 task0_MainMenu task0_MainMenu_0_and_task1_Title_state_1 task0_MainMenu_1 task0_MainMenu_2 task0_MainMenu_3 task0_MainMenu_6 task0_MainMenu_main task0_Normal task0_Normal_1 task0_Normal_2 task0_Normal_3 task0_PickedUpTriforce task0_PreparingScroll task0_Scrolling task0_Scrolling_0 task0_Scrolling_1 task0_Scrolling_1_subtask task0_Scrolling_1_subtask_0 task0_Scrolling_1_subtask_no_transition task0_Scrolling_2 task0_Scrolling_3 task0_Scrolling_5 task0_Scrolling_6 task0_Scrolling_work task0_Title task0_Title_Splash_0 task0_Title_Splash_1 task0_Title_Splash_2 task0_Title_Splash_2_sub task0_intro_text_1 task0_intro_text_2 task1_CreateSave task1_CurtainsOpening task1_DeleteSave task1_EndCredits task1_EndCredits_0 task1_EndCredits_1 task1_EnteringDoor task1_FinishScroll task1_FoundZelda task1_FoundZelda_0 task1_FoundZelda_0_0 task1_FoundZelda_1 task1_FoundZelda_1_0 task1_FoundZelda_3 task1_FoundZelda_3_0 task1_FoundZelda_4 task1_GameOverMenu task1_JustDied task1_JustDied_0 task1_JustDied_1 task1_JustDied_10 task1_JustDied_11 task1_JustDied_12 task1_JustDied_2 task1_JustDied_3 task1_JustDied_4 task1_JustDied_5 task1_JustDied_6 task1_JustDied_7 task1_JustDied_8 task1_JustDied_9 task1_JustDied_store_ppu_command_ending_at_Y task1_LoadDungeon task1_LoadDungeon_main task1_MainMenu task1_MainMenu_state_0 task1_MainMenu_state_1 task1_Normal task1_PickedUpTriforce task1_PickedUpTriforce_0 task1_PickedUpTriforce_1 task1_PickedUpTriforce_2 task1_PickedUpTriforce_3 task1_PickedUpTriforce_4 task1_Scroll task1_Scroll_advance_task_by_2 task1_Scroll_run_task_state task1_Scroll_run_task_state_and_continue task1_Scroll_state_0 task1_Scroll_state_1 task1_Scroll_state_2 task1_Scroll_state_3 task1_Scroll_state_3a task1_Scroll_state_3b task1_Scroll_state_4 task1_Scroll_state_5 task1_Scroll_state_6 task1_Scroll_state_7 task1_Title task1_Title_splash task1_Title_state_0 task1_Title_state_2 tektite_set_zero_speed tektite_update_position ten_rupee_pattern_x_positions title_splash_fading title_splash_main title_splash_main_setup_decoration_sprites title_splash_next_state title_update_waterfall title_update_waterfall_piece title_update_waterfall_sprites toggle_object_animation_frame_and_set_timer unpack_enemy_health update_aquamentus_fireballs update_aquamentus_sprite update_arrow update_arrow_or_melee_rod update_bomb_cloud_sprite update_bomb_or_fire update_boomerang_or_meat update_candle_fire update_clipping_sprites_under_wall update_controllers update_currently_open_doors update_curtain update_deflected_projectile update_dungeon_screen_kill_count update_fairy_lake_spinning_hearts update_fairy_refill_rupees_and_hud update_floor_item_sprite update_from_ganon update_ganon_sprite update_gleeok_body update_gleeok_head_and_necks_1 update_gleeok_head_and_necks_2 update_hold_up_item update_hold_up_item_1 update_hold_up_item_2 update_hud_hearts update_hud_number_1 update_inventory_item_sprite update_leever_from_zola update_lighting_room update_lighting_room_0 update_lighting_room_1 update_link_movement update_link_sprite_and_check_ladder update_link_sprite_and_check_ladder_bank_1 update_link_sprite_and_check_ladder_if_overworld update_link_sprite_and_check_ladder_in_bank_4 update_link_sprite_and_door_clipping update_link_sprite_and_other_stuff update_link_sprite_return_in_bank_1 update_link_walking_speed update_lynel_sword_or_unknown update_minimap_and_link_sprite update_monster update_monster_10_rupee update_monster_45_degree_movement update_monster_aquamentus update_monster_aquamentus_0 update_monster_aquamentus_movement update_monster_armos update_monster_bubble update_monster_darknut update_monster_diagonal_movement_relative_to_seek update_monster_diagonal_movement_relative_to_seek_from_digdogger update_monster_digdogger update_monster_digdogger_0 update_monster_digdogger_1 update_monster_digdogger_2 update_monster_digdogger_4 update_monster_dodongo update_monster_dodongo_sub_1 update_monster_dungeon_secret_push_block update_monster_dungeon_secret_push_block_0 update_monster_dungeon_secret_push_block_1 update_monster_event_1 update_monster_event_1_0 update_monster_event_1_2 update_monster_event_1_main update_monster_fairy update_monster_fairy_animation update_monster_fairy_move_to_state_3 update_monster_falling_rock_daemon update_monster_flame update_monster_flame_unkillable update_monster_floor_pickup update_monster_floor_pickup_fairy update_monster_ganon update_monster_ganon_0_start_cutscene update_monster_ganon_1_wait_for_music_to_finish update_monster_ganon_2_main_combat update_monster_ganon_2a update_monster_ganon_2b update_monster_ganon_2g update_monster_ganon_2g2 update_monster_ganon_2h update_monster_ganon_2i update_monster_gel update_monster_ghini update_monster_ghini_1 update_monster_ghini_from_tombs update_monster_ghini_select_random_state_2_3_4 update_monster_gibdo update_monster_gleeok update_monster_gleeok_2a update_monster_gleeok_2a_0 update_monster_gleeok_2a_2 update_monster_gleeok_2a_6 update_monster_gleeok_2a_8 update_monster_gleeok_2a_nop update_monster_gleeok_2b update_monster_gleeok_flying_head update_monster_gleeok_flying_head_choose_random_state update_monster_gohma update_monster_gohma_0 update_monster_gohma_1 update_monster_gohma_2 update_monster_gohma_3 update_monster_goriya update_monster_homing_fireball update_monster_homing_fireball_0 update_monster_hungry_goriya update_monster_hungry_goriya_1 update_monster_hungry_goriya_3 update_monster_keese update_monster_keese_select_random_state_2_3_4 update_monster_lanmola update_monster_lanmola_0 update_monster_lanmola_1 update_monster_leever_blue update_monster_leever_red update_monster_like_like update_monster_lynel update_monster_manhandla update_monster_manhandla_1 update_monster_manhandla_2 update_monster_moblin update_monster_moblin_arrow update_monster_moldorm update_monster_moldorm_0 update_monster_moldorm_0a update_monster_moldorm_3 update_monster_octorok update_monster_old_man update_monster_old_man_0_setup update_monster_old_man_4 update_monster_old_man_main update_monster_old_man_main_0 update_monster_overworld_secret_bomb update_monster_overworld_secret_candle update_monster_overworld_secret_push_block update_monster_overworld_secret_raft update_monster_patra update_monster_patra_choose_random_state update_monster_patra_eye update_monster_peahat update_monster_peahat_select_random_state_2_3_4 update_monster_pols_voice update_monster_pols_voice_0 update_monster_pols_voice_1 update_monster_pols_voice_2 update_monster_pols_voice_3 update_monster_projectile update_monster_rope update_monster_stalfos update_monster_tektite_or_falling_rock update_monster_vire update_monster_vire_main update_monster_vire_normal update_monster_vire_zol_1 update_monster_wall_master update_monster_wall_trap update_monster_whirlwind update_monster_wizzrobe_blue update_monster_wizzrobe_blue_0 update_monster_wizzrobe_blue_1 update_monster_wizzrobe_red update_monster_wizzrobe_red_0 update_monster_wizzrobe_red_1 update_monster_wizzrobe_red_2 update_monster_wizzrobe_shared_red_blue update_monster_zelda update_monster_zol update_monster_zol_1 update_monster_zol_moving update_monster_zol_moving_main update_monster_zol_split_into_keese update_monster_zola update_movement_or_fire_projectile_if_zero_timer update_object_animation_frame update_object_knockback update_object_movement update_object_sprite update_object_sprite_horizontal update_object_sprite_vertical update_overworld_screen_kill_count update_patra_eye_sprite update_picking_up_ganon_triforce update_projectile update_projectile_movement update_push_block_sprite update_recorder_pond_daemon update_screen_kill_count update_spawn_cloud update_spawn_cloud_sprite update_spinning_hearts_patra_1 update_spinning_hearts_patra_2 update_spinning_hearts_patra_2a update_sprite_and_check_hits_for_tektite update_sprite_attributes_then_advance update_sprite_bubble_stalfos_flame_patra update_sprite_for_current_object_type update_sprite_for_current_object_type_no_increment update_sprite_from_wall_master_or_like_like update_sprite_like_like update_sprite_wall_master update_sprite_y_attributes_then_advance update_sprite_zelda_wall_trap update_start_menu update_start_menu_overworld update_sword_or_rod_melee update_timed_palette_cycle update_vire_zol_gel_movement update_walking_direction update_walking_frame_for_link update_walking_frame_for_object update_walking_repeated update_wall_master_sprite use_item use_item_bomb use_item_boomerang use_item_bow use_item_candle use_item_meat use_item_potion use_item_recorder use_item_rod walk_negative walk_positive wall_master_check_whether_to_hide_sprites
RAM
active_game_mode_task already_exited_title_screen alternate_ppu_nametable arrow_or_melee_rod_state arrow_x arrow_y audio_looping_boss_sound audio_looping_boss_sound_current audio_misc_0605 audio_misc_0606 audio_misc_0607 audio_misc_060A audio_misc_060B audio_misc_060C audio_misc_060D audio_misc_060E audio_misc_060F audio_misc_0610 audio_misc_0611 audio_misc_0612 audio_misc_0613 audio_misc_0614 audio_misc_0615 audio_misc_0616 audio_misc_0617 audio_misc_0618 audio_misc_0619 audio_misc_061A audio_misc_061B audio_misc_061C audio_misc_061D audio_misc_061E audio_misc_061F audio_misc_18 audio_misc_19 audio_misc_20 audio_misc_21 audio_misc_22 audio_misc_3 audio_misc_4 audio_misc_7 audio_pulse1_offset audio_pulse2_offset audio_rhythm_countdown audio_rhythm_offset bomb_1_x bomb_2_x bomb_flame_timer bomb_or_fire1_state bomb_or_fire2_state bombed_door_timer bombing_or_unlocking_door_direction boomerang_bait_x boomerang_or_meat_state boomerang_sound_timer boss_roar_loop_timer bubble_sword_timer candle_used_in_current_room clock_active consecutive_kill_counter consecutive_ten_kill_counter controller_1_cur controller_1_pressed controller_2_cur controller_2_pressed copied_ppu_data_0 copied_ppu_data_1 copied_ppu_data_2 copied_ppu_data_3 copied_ppu_data_4 copied_ppu_data_5 copied_ppu_data_6 copied_ppu_data_7 current_floor_item current_item current_music current_object_tile_size_neg current_object_tile_size_pos current_ppu_command_index current_ppuctrl current_ppumask current_room_floor_item_hidden current_save_slot current_screen_data_5 currently_open_doors curtains_currently_opening damage_types_with_no_knockback damage_types_with_no_knockback_1 death_cutscene_timer_1 death_cutscene_timer_2 deaths_per_save_slot desired_ppuscroll_x desired_ppuscroll_y detached_gleeok_heads disable_sprite_horizontal_offset displayed_map_location do_ppu_work_after_sprite0_next_frame drop_counter dungeon_idx dungeon_screen_data_0 dungeon_screen_data_1 dungeon_screen_data_2 dungeon_screen_data_3 dungeon_screen_data_4 dungeon_screen_data_5 dungeon_shoots_fireballs enemy_action_timers enemy_behavior_seek_x enemy_behavior_seek_y enemy_behavior_seeking_mode enemy_behavior_seeking_timer enemy_blind_projectile_timer enemy_blind_projectile_timer_1 enemy_health enemy_health_1 enemy_projectile_count enemy_projectile_speed_x enemy_projectile_speed_x_1 enemy_properties enemy_spawn_state enemy_spawn_state_1 enemy_spawn_state_1_5 enemy_state_0 enemy_state_1 enemy_state_10_2 enemy_state_11 enemy_state_11_1 enemy_state_1_1 enemy_state_2 enemy_state_2_1 enemy_state_4 enemy_state_4_1 enemy_state_4_2 enemy_state_4_3 enemy_state_4_4 enemy_state_4_5 enemy_state_4_6 enemy_state_5 enemy_state_5_1 enemy_state_6 enemy_state_6_1 enemy_state_6_4 enemy_state_6_5 enemy_state_6_6 enemy_state_9_1 enemy_stun enter_from_side_timer first_object_type first_sprite_index floor_item_x floor_item_y force_beam_sword found_zelda_cutscene_state_0 found_zelda_cutscene_state_1 found_zelda_cutscene_state_2 found_zelda_cutscene_state_3 found_zelda_cutscene_state_4 frame_counter game_mode gameplay_menu_state gleeok_body_animation_timer_or_lanmola_something gleeok_body_frame_or_lanmola_something global_room_state has_ganon_triforce have_arrow_type have_book have_boomerang have_bow have_candle_type have_compass_dungeon_9 have_compass_per_dungeon have_ladder have_letter have_magic_boomerang have_magic_key have_magic_shield have_map_dungeon_9 have_map_per_dungeon have_meat have_potion_type have_power_bracelet have_raft have_recorder have_ring_type have_rod health_refill hearts held_by_like_like held_by_recorder_whirlwind in_dungeon_door increase_enemy_speed_max invincibility_frames invincibility_frames_1 invincibility_frames_5 is_in_cellar is_zola_spawned knockback_frames ladder_object_id leever_timer lighting_room_state link_beam_x link_melee_x link_most_recent_overworld_tile_type lost_woods_counter map_location map_location_in_dungeon_cellar map_location_transitioning_to max_bombs maybe_next_projectile_idx next_game_mode next_palette_cycle next_recorder_location next_sprite_index npc_action_timer_1 npc_action_timer_2 npc_action_timer_3 npc_action_timer_4 npc_action_timer_5 npc_action_timer_6 npc_action_timer_7 npc_action_timer_8 npc_action_timer_9 num_bombs num_keys num_rupees number_of_digdogger_spawn_to_create number_of_enemies_killed_in_dungeon_room number_of_extra_directions_pressed number_of_spawned_falling_rocks number_of_spawned_red_leevers_or_gleeok_fast_step_counter object_animation_frame object_animation_frame_timer object_direction object_direction_1 object_knockback object_knockback_1 object_knockback_10 object_knockback_11 object_knockback_12 object_knockback_2 object_knockback_3 object_knockback_4 object_knockback_5 object_knockback_6 object_knockback_7 object_knockback_8 object_knockback_9 object_slot_in_use object_tile_offset_fraction object_tile_offset_fraction_1 object_tile_offset_fraction_10 object_tile_offset_fraction_11 object_tile_offset_fraction_12 object_tile_offset_fraction_2 object_tile_offset_fraction_3 object_tile_offset_fraction_4 object_tile_offset_fraction_5 object_tile_offset_fraction_6 object_tile_offset_fraction_7 object_tile_offset_fraction_8 object_tile_offset_fraction_9 object_tile_offset_whole object_tile_offset_whole_1 object_tile_offset_whole_10 object_tile_offset_whole_11 object_tile_offset_whole_12 object_tile_offset_whole_2 object_tile_offset_whole_3 object_tile_offset_whole_4 object_tile_offset_whole_5 object_tile_offset_whole_6 object_tile_offset_whole_7 object_tile_offset_whole_8 object_tile_offset_whole_9 object_type object_type_1 object_type_2 object_type_3 object_type_5 object_type_7 object_type_B object_walk_speed object_walk_speed_1 object_x object_x_1 object_x_10 object_x_11 object_x_12 object_x_2 object_x_3 object_x_4 object_x_5 object_x_6 object_x_7 object_x_8 object_x_9 object_y object_y_1 object_y_10 object_y_11 object_y_12 object_y_2 object_y_3 object_y_4 object_y_5 object_y_6 object_y_7 object_y_8 object_y_9 open_doors_in_room overworld_return_pos overworld_room_object_type overworld_room_object_x overworld_room_object_y palette_cycle_timer partial_heart paused paused_lighting_dungeon_room pending_rupees_add pending_rupees_sub picking_up_ganon_triforce picking_up_item picking_up_item_timer play_music play_sound_0 play_sound_1 play_sound_2 play_sound_3 ppu_command_buffer ppu_command_buffer_01 ppu_command_buffer_02 ppu_command_buffer_03 ppu_command_buffer_04 ppu_command_buffer_05 ppu_command_buffer_06 ppu_command_buffer_07 ppu_command_buffer_08 ppu_command_buffer_09 ppu_command_buffer_0A ppu_command_buffer_0C ppu_command_buffer_10 ppu_command_buffer_13 ppu_command_buffer_14 ppu_command_buffer_15 ppu_command_buffer_16 ppu_command_buffer_19 ppu_command_buffer_bytes_used ppu_data_for_current_dungeon ppu_unknown_0 ppu_unknown_task_returns_to_ROM4 previous_unlocked_door_directions prng_0 prng_1 prng_2 prng_3 prng_5 prng_8 prng_A prng_last processing_gleeok_head processing_object_index projectile_direction_boomerang projectile_direction_mask projectile_hit_link pushed_dungeon_push_block quest_no reached_ten_kills_with_last_bomb recorder_called_whirlwind_already recorder_lake_state recorder_lock_timer reset_room_palette_idx_to_0x44 room_clear room_data room_tiles_x_00 room_tiles_x_01 room_tiles_x_02 room_tiles_x_03 room_tiles_x_04 room_tiles_x_05 room_tiles_x_06 room_tiles_x_07 room_tiles_x_08 room_tiles_x_09 room_tiles_x_10 room_tiles_x_11 room_tiles_x_12 room_tiles_x_13 room_tiles_x_14 room_tiles_x_15 room_tiles_x_16 room_tiles_x_17 room_tiles_x_18 room_tiles_x_19 room_tiles_x_20 room_tiles_x_21 room_tiles_x_22 room_tiles_x_23 room_tiles_x_24 room_tiles_x_25 room_tiles_x_26 room_tiles_x_27 room_tiles_x_28 room_tiles_x_29 room_tiles_x_30 room_tiles_x_31 saved_hearts_slot_0 saved_hearts_slot_1 saved_hearts_slot_2 saved_partial_hearts_slot_0 saved_partial_hearts_slot_1 saved_partial_hearts_slot_2 screen_first_solid_tile_id screen_history_0 screen_history_1 screen_history_2 screen_history_3 screen_history_4 screen_history_5 screen_history_idx screen_max_x screen_max_y screen_min_x screen_min_y screen_status_0 shutter_doors_entered song_start_high song_start_low spawn_from_side_position spawn_position_counter sprite_data_1_initialized sprite_data_2_initialized sprite_oam_data sprite_oam_data_04 sprite_oam_data_07 sprite_oam_data_08 sprite_oam_data_0B sprite_oam_data_1C sprite_oam_data_1D sprite_oam_data_1E sprite_oam_data_1F sprite_oam_data_20 sprite_oam_data_21 sprite_oam_data_22 sprite_oam_data_23 sprite_oam_data_40 sprite_oam_data_44 sprite_oam_data_48 sprite_oam_data_49 sprite_oam_data_4A sprite_oam_data_4B sprite_oam_data_4C sprite_oam_data_4D sprite_oam_data_4E sprite_oam_data_4F sprite_oam_data_50 sprite_oam_data_51 sprite_oam_data_52 sprite_oam_data_53 sprite_oam_data_54 sprite_oam_data_55 sprite_oam_data_56 sprite_oam_data_57 sprite_oam_data_58 sprite_oam_data_80 sprite_oam_data_81 sprite_oam_data_82 sprite_oam_data_83 sram_check_byte sram_init_finished start_menu_scroll_drawing_map_position start_menu_scroll_progress stop_enemy_for_frames stop_enemy_for_frames_1 store_item sword_disabled_by_bubble sword_rod_beam_state sword_state sword_type task_state temp_ppu_command_buffer ten_frame_counter text_scroll_index tile_walking_onto title_screen_timer tmp_result total_enemies_spawned_in_room transitioning_direction triforce_pieces_collected unk_26810 unk_26817 unk_26825 unk_2684B unk_382 unk_383 unk_384 unk_385 unk_386 unk_38A unknown_timer_6 unlocked_door_directions updating_oam_sprite_id_1 updating_oam_sprite_id_2 used_recorder_in_dungeon usually_zero var_0 var_1 var_10 var_11 var_12 var_13 var_14 var_15 var_2 var_3 var_4 var_5 var_6 var_7 var_8 var_9 walk_state_and_weapon_state walking_direction_was_flipped walking_directions zola_state_2
Data
Joypad_1 Joypad_2 OAMADDR OAMDATA OnIRQ OnIRQVec OnNMIVec OnResetVec PPUADDR PPUCTRL PPUDATA PPUMASK PPUSCROLL PPUSTATUS SPRITE_DMAR adjacent_room_offset aquamentus_data_0 aquamentus_data_1 aquamentus_data_2 aquamentus_x_movement_speed armos_map_locations armos_x_offsets armos_x_positions armos_y_offsets audio_data_1 audio_data_2 audio_data_3 audio_data_4 audio_data_5 beam_explosion_oam_attributes blue_wizzrobe_hidden_x_movement blue_wizzrobe_hidden_y_movement bomb_cloud_offsets_1 bomb_cloud_offsets_2 bomb_sprite0_oam_sprite bombable_dungeon_positions_x bombable_dungeon_positions_y boomerang_throw_distances boss_roar_sounds cellar_keese_x_positions cellar_keese_y_positions cellar_ppu_data cellar_ppu_data_0 cellar_ppu_data_1 cellar_ppu_data_2 cellar_ppu_data_3 default_enemy_properties digdogger_spawn_tile_attributes digdogger_spawn_x_offsets digdogger_spawn_y_offsets direction_axes directions_with_diagonals dodongo_bomb_max_distance_left dodongo_bomb_max_distance_right dodongo_second_check_bomb_distances_horizontal dodongo_second_check_bomb_distances_vertical door_sprite_ptr_high door_sprite_ptr_low door_x_center door_y_bottom door_y_bottom_while_inside door_y_top door_y_top_while_inside drop_chance drop_class_starting_index dungeon_data_1 dungeon_data_2 dungeon_data_3 dungeon_data_4 dungeon_data_5 dungeon_data_6 dungeon_data_7 dungeon_data_8 dungeon_data_9 dungeon_data_overworld dungeon_data_pointers dungeon_ppu_data_0_1 dungeon_ppu_data_0_2 dungeon_ppu_data_0_3 dungeon_ppu_data_0_ptrs dungeon_ppu_data_1_1 dungeon_ppu_data_1_2 dungeon_ppu_data_1_3 dungeon_ppu_data_1_ptrs dungeon_ppu_data_ppu_addresses dungeon_screen_attr_1Q dungeon_screen_attr_1Q_1 dungeon_screen_attr_1Q_2 dungeon_screen_attr_2Q dungeon_screen_attr_2Q_1 dungeon_screen_attr_2Q_2 dungeon_screen_attr_overworld enemy_class_1_no_drops enemy_class_A enemy_class_B enemy_class_C enemy_health_table enemy_list_00 enemy_list_01 enemy_list_02 enemy_list_03 enemy_list_04 enemy_list_05 enemy_list_06 enemy_list_07 enemy_list_08 enemy_list_09 enemy_list_10 enemy_list_11 enemy_list_12 enemy_list_13 enemy_list_14 enemy_list_15 enemy_list_16 enemy_list_17 enemy_list_18 enemy_list_19 enemy_list_20 enemy_list_21 enemy_list_22 enemy_list_23 enemy_list_24 enemy_list_25 enemy_list_26 enemy_list_27 enemy_list_28 enemy_list_29 enemy_list_pointers floor_item_flags floor_item_frame_offset floor_item_to_inventory_item frames_per_dodongo_state_4 game_mode_list_from_next_work_values ganon_oam_attributes ganon_ppu_data_1 ganon_ppu_data_2 ganon_tile_set_frame_offsets ganon_tile_y_increment ganon_x_offset ganon_y_offset gleeok_body_tiles gleeok_ptr_something_high gleeok_ptr_something_low gleeok_ptr_x_high gleeok_ptr_x_low gleeok_ptr_y_high gleeok_ptr_y_low intro_text_item_scroll_ppu_command_00 intro_text_item_scroll_ppu_command_01 intro_text_item_scroll_ppu_command_02 intro_text_item_scroll_ppu_command_03 intro_text_item_scroll_ppu_command_04 intro_text_item_scroll_ppu_command_05 intro_text_item_scroll_ppu_command_06 intro_text_item_scroll_ppu_command_07 intro_text_item_scroll_ppu_command_08 intro_text_item_scroll_ppu_command_09 intro_text_item_scroll_ppu_command_0A intro_text_item_scroll_ppu_command_0B intro_text_item_scroll_ppu_command_0C intro_text_item_scroll_ppu_command_0D intro_text_item_scroll_ppu_command_0E intro_text_item_scroll_ppu_command_0F intro_text_item_scroll_ppu_command_10 intro_text_item_scroll_ppu_command_11 intro_text_item_scroll_ppu_command_12 intro_text_item_scroll_ppu_command_13 intro_text_item_scroll_ppu_command_14 intro_text_item_scroll_ppu_command_15 intro_text_item_scroll_ppu_command_16 intro_text_item_scroll_ppu_command_17 intro_text_item_scroll_ppu_command_18 intro_text_item_scroll_ppu_command_19 intro_text_item_scroll_ppu_command_1A intro_text_item_scroll_ppu_command_1B intro_text_item_scroll_ppu_command_1C intro_text_item_scroll_ppu_command_table item_and_sword_screen_limits ladder_x_offsets ladder_y_offsets leever_action_timers leever_animation_frames lost_hills_code lost_woods_code manhandla_claw_x_positions manhandla_claw_y_positions map_transition_offsets minimap_data_bits mugging_item_x mugging_item_y music_per_dungeon object_tile_set_to_tile_index object_type_to_tile_set objects_with_special_palette_mappings off_106DC7 off_90EC off_C006 old_man_message_1_text_indices old_man_message_2_text_indices old_man_message_3_text_indices old_man_ppu_command overworld_ladder_locations overworld_object_types overworld_recorder_locations pAPU_DM_AR pAPU_DM_CR pAPU_DM_DAR pAPU_DM_DLR pAPU_N_CR_1 pAPU_N_FR_1 pAPU_N_FR_2 pAPU_P_1_CR pAPU_P_1_CTR pAPU_P_1_FTR pAPU_P_1_RCR pAPU_P_2_CR pAPU_P_2_CTR pAPU_P_2_FTR pAPU_P_2_RCR pAPU_SV_CSR pAPU_T_CR_1 pAPU_T_CR_2 pAPU_T_FR_1 pAPU_T_FR_2 pointers_to_clear_for_2nd_quest powers_of_two ppu_background_door_ptr_high ppu_background_door_ptr_low ppu_cmd_02 ppu_cmd_04 ppu_cmd_0E ppu_cmd_10 ppu_cmd_14 ppu_cmd_16 ppu_cmd_1E ppu_cmd_20 ppu_cmd_22 ppu_cmd_24 ppu_cmd_26 ppu_cmd_2A ppu_cmd_2C ppu_cmd_30 ppu_cmd_32 ppu_cmd_34 ppu_cmd_38 ppu_cmd_3A ppu_cmd_3C ppu_cmd_3E ppu_cmd_40 ppu_cmd_42 ppu_cmd_46 ppu_cmd_48 ppu_cmd_4A ppu_cmd_4C ppu_cmd_4E ppu_cmd_50 ppu_cmd_5E ppu_cmd_60 ppu_cmd_62 ppu_cmd_6A ppu_cmd_6C ppu_cmd_76 ppu_cmd_78 ppu_cmd_7A ppu_cmd_palette_aquamentus ppu_cmd_palette_digdogger_dodongo ppu_cmd_palette_ganon ppu_cmd_palette_gleeok ppu_command_table ppu_create_delete_save_command ppu_create_save_command ppu_hud_update_command ppu_intro_text_command ppu_recorder_lake_palette_shift ppu_recorder_lake_palette_shift_colors ppu_title_splash_command projectile_deflection_movement_x projectile_deflection_movement_y random_drops recorder_locations_tbl recorder_locations_y_tbl rom1_sprite_data_0 rom1_sprite_data_1 rom1_sprite_data_ppu_addresses rom1_sprite_data_ptrs rom1_sprite_data_size rom2_sprite_data_0 rom2_sprite_data_1 rom2_sprite_data_2 rom2_sprite_data_ppu_addresses rom2_sprite_data_ptrs rom2_sprite_data_size rom3_ppu_data_0_0 rom3_ppu_data_0_1 rom3_ppu_data_0_ptrs rom3_ppu_data_1_0 rom3_ppu_data_1_1 rom3_ppu_data_1_ptrs rom3_ppu_data_1_sizes rom3_ppu_data_sizes room_tile_ptrs save_slot_idxs_high save_slot_idxs_lo screen_bounds screen_transition_thresholds second_quest_overworld_patch_data second_quest_overworld_patch_offsets second_quest_patch_data second_quest_patch_data_1 second_quest_patch_data_2 second_quest_patch_data_3 second_quest_patch_data_4 second_quest_patch_data_5 second_quest_patch_data_6 second_quest_patch_data_7 second_quest_patch_data_8 second_quest_patch_data_9 second_quest_patch_data_size secret_quest_numbers some_ppu_data_0 some_ppu_data_1 some_ppu_data_2 some_ppu_data_3 some_ppu_data_4 some_ppu_data_5 some_ppu_data_6 some_ppu_data_7 some_ppu_palette_pointer spawn_heart_at_first_heart_offsets spawn_position_ptr_high spawn_position_ptr_low spawn_positions_when_link_facing_down spawn_positions_when_link_facing_left spawn_positions_when_link_facing_right spawn_positions_when_link_facing_up special_palette_mapping_values spinning_hearts_tile_offset_table sprite_index_right_half sprite_index_to_left_half sprite_replacement_for_big_shield_from sprite_replacement_for_big_shield_to sram_check_byte2 sram_code_end sram_code_start start_menu_ppu_command_indices_dungeon start_menu_ppu_command_indices_overworld store_item_x_positions store_message_indices store_ppu_command_buffer sword_oam_attributes sword_or_melee_x_offsets sword_or_melee_y_offsets tektite_data_1 tektite_data_2 tektite_data_3 tektite_data_4 tektite_initial_directions ten_rupee_pattern_y_positions text_data_00 text_data_01 text_data_02 text_data_03 text_data_04 text_data_05 text_data_06 text_data_07 text_data_08 text_data_09 text_data_0A text_data_0B text_data_0C text_data_0D text_data_0E text_data_0F text_data_10 text_data_11 text_data_12 text_data_13 text_data_14 text_data_15 text_data_16 text_data_17 text_data_18 text_data_19 text_data_1A text_data_1B text_data_1C text_data_1D text_data_1E text_data_1F text_data_20 text_data_21 text_data_22 text_data_23 text_data_24 text_data_25 text_ptr_tbl tile_set_to_tile_attributes tiles_triforce_base title_screen_triforce_palette_shift_ppu_cmd title_screen_triforce_palette_values title_splash_fading_palette_data unk_119D9B unk_1416A unk_1C904 unk_201F unk_9D57 unk_9D9B unk_ADFA vertical_horizontal_sprite_offsets vire_y_movement_speed walking_bits walking_bits_2 wall_master_directions wall_master_hidden_under_wall_offset wall_trap_x_positions wall_trap_y_positions zelda_flames_x zelda_flames_y zola_fireball_speeds_x zola_fireball_speeds_y zola_leever_spawn_timers
Struct: dungeon_data
ppu_cmd_0 .BYTE
ppu_data .BYTE
ppu_end_ff .BYTE
enemy_count .BYTE
start_y_pos .BYTE
stair_or_item_pos .BYTE 0xF0 is one coordinate, 0x0F is the other
map_start_pos_x .BYTE
map_pos_x .BYTE
start_loc .BYTE
triforce_loc .BYTE
screen_status_ptr .WORD
displayed_level_number .BYTE
stairs_loc .BYTE
boss_loc .BYTE
minimap_data .BYTE
ppu_0 .BYTE
ppu_1 .BYTE
ppu_2 .BYTE
padding .BYTE
palette_enter_stairway .BYTE
palette_exit_stairway .BYTE
palette_death .BYTE
Struct: OAMSprite
y_pos .BYTE
tile .BYTE
attr .BYTE
x_pos .BYTE
enum: StoreFlags
StoreFlags_CanPickUpFloorItems 1
StoreFlags_RequiresRupeesForItem 2
StoreFlags_ShowStoreItems 4
StoreFlags_ShowRupeeIcon 8
StoreFlags_TakesRupeesNoItem $10 Stores that take money and don't give an item, like hints
StoreFlags_NoItem $20
StoreFlags_RequiresHearts $40
StoreFlags_Unknown_0x80 $80
enum: BombOrFireState
BombOrFireState_Fire_Moving 1
BombOrFireState_BombDelay 2
BombOrFireState_BombExploding 3
BombOrFireState_BombDissipating 4
BombOrFireState_Type_Bomb $10
BombOrFireState_Type_Fire $20
enum: ScreenData_Dungeon_4
ScreenData_Dungeon_4_Item $1F
ScreenData_Dungeon_4_PlayBossSound1 $20
ScreenData_Dungeon_4_PlayBossSound2 $40
ScreenData_Dungeon_4_Dark $80
enum: ScreenData_Dungeon_5
ScreenData_Dungeon_5_KillingEverythingOpensDoors 1
ScreenData_Dungeon_5_MasterEnemyOpensDoorsAndKillsEverything 2
ScreenData_Dungeon_5_GanonTriforceOpensDoors 3
ScreenData_Dungeon_5_PushBlockOpensDoors 4
ScreenData_Dungeon_5_PushBlockShowsStaircase 5
ScreenData_Dungeon_5_MasterEnemyOpensDoors 6
ScreenData_Dungeon_5_KillingEverythingOpensDoorAndSpawnsItem 7
ScreenData_Dungeon_5_ItemPosition $30 This is an index into dungeon_data.stair_or_item_pos.
enum: ScreenData_Dungeon_2
enum: ScreenData_Dungeon_3
ScreenData_Dungeon_3_ScreenCode $3F
ScreenData_Dungeon_3_PushBlock $40
ScreenData_Dungeon_3_MixedEnemies $80
enum: ScreenData_Dungeon_0
enum: ScreenData_Dungeon_1
enum: OverworldCaveDestinations
OverworldCaveDestinations_CaveEntrance_WoodSword $40
OverworldCaveDestinations_TakeAnyRoad $50
OverworldCaveDestinations_Store_0 $78
enum: Music
Music_Overworld 1
Music_FoundGanon 2
Music_Overworld_Skip_4_Measures 3
Music_PickedUpTriforcePiece 4
Music_Victory 6
Music_PickedUpItem 8
Music_Dead $10
Music_DeathMountain $20
Music_Dungeon $40
Music_Title $80
enum: PPUCTRLBits
PPUCTRLBits_BaseNametable_2400 1 If not set, the base nametable is at 0x2000
PPUCTRLBits_BaseNametable_2800 2
PPUCTRLBits_BaseNametable_2C00 3
PPUCTRLBits_WriteVertically 4 If not set, write horizontally
PPUCTRLBits_SpritePattern_1000 8 If not set, 0x0000
PPUCTRLBits_BackgroundPatternAddress_1000 $10 If not set, 0x0000
PPUCTRLBits_SpriteSize_8x16 $20 If not set, 8x8
PPUCTRLBits_MasterSlave_1 $40
PPUCTRLBits_VBlank_NMI_On $80
enum: ScreenDataOverworld_1
ScreenDataOverworld_1_Palette 3
ScreenDataOverworld_1_CaveDestination $FC
enum: InventoryItemFlags
InventoryItemFlags_Give_1 1
InventoryItemFlags_Give_2 2
InventoryItemFlags_Give_3 3
InventoryItemFlags_Give_4 4
InventoryItemFlags_Give_5 5
InventoryItemFlags_Item 0
InventoryItemFlags_Add $10
InventoryItemFlags_Max $20
enum: DungeonTiles
enum: GameMode
GameMode_Title 0
GameMode_MainMenu 1
GameMode_LoadDungeon 2
GameMode_CurtainsOpening 3
GameMode_FinishScroll 4
GameMode_Normal 5
GameMode_PrepareScroll 6
GameMode_Scroll 7
GameMode_GameOverMenu 8
GameMode_InDungeonCellar 9 If we're in a dungeon cellar.
GameMode_ExitingCellar $A Exiting a dungeon cellar, or after ExitingOverworldCellar when exiting an overworld cave.
GameMode_InOverworldCellar $B We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal. The map location doesn't change.
GameMode_ExitingOverworldCellar $C
GameMode_EndCredits $D
GameMode_CreateSave $E
GameMode_DeleteSave $F
GameMode_EnteringDoor $10
GameMode_JustDied $11
GameMode_PickedUpTriforce $12
GameMode_FoundZelda $13
GameMode_Dummy $FF
enum: ControllerBits
ControllerBits_Dpad_Right 1
ControllerBits_Dpad_Left 2
ControllerBits_Dpad_Down 4
ControllerBits_Dpad_Up 8
ControllerBits_Start $10
ControllerBits_Select $20
ControllerBits_B $40
ControllerBits_A $80
enum: WalkState
WalkState_Unknown2_10 $10
WalkState_Unknown2_20 $20
WalkState_Unknown2_30 $30
WalkState_3_MovementLocked $40 Setting this causes odd behavior when coming out of the start menu, so this is a bit more subtle than just locking movement.
enum: ArrowState
ArrowState_ArrowUnknown 8 This is set on the frame after ArrowFiring.
ArrowState_ArrowFiring $10
ArrowState_ArrowHit $20
ArrowState_Type_Unknown $30 Not sure what this is, see check_attack_arrow
enum: Sound1
Sound1_None 0
Sound1_Rupee 1
Sound1_ItemAppeared 2
Sound1_Rupee2 3
Sound1_Secret 4
Sound1_Fairy 8
Sound1_Recorder $10
Sound1_KilledEnemy $20
Sound1_EndlessDeathMusic $40
Sound1_LinkDiedMusic $80
enum: ScreenData_Overworld_5
ScreenData_Overworld_5_CaveExitY 7
ScreenData_Overworld_5_MonstersEnterFromSide 8
ScreenData_Overworld_5_PushStairsPosition $30
ScreenData_Overworld_5_Secret_FirstQuest $40
ScreenData_Overworld_5_Secret_SecondQuest $80
enum: Sound3
Sound3_ShieldTing 1
Sound3_HitEnemy 2
Sound3_WizzrobeBeam 4
Sound3_Pickup 8
Sound3_GainRupee $10
Sound3_PlaceBomb $20
Sound3_LowHealth $40 OR'd with other sounds
Sound3_Stop $80
enum: Sound2
Sound2_SwingSword 1
Sound2_FireArrow 2
Sound2_Candle 4
Sound2_EnteredDoor 8
Sound2_BombExplosion $10
Sound2_Coast $20
Sound2_StopBossRoar $80
enum: ScreenData_Overworld_0
ScreenData_Overworld_0_Palette 3
ScreenData_Overworld_0_WaterSound 4
ScreenData_Overworld_0_Zola 8
ScreenData_Overworld_0_CaveExitX $F0
enum: ScreenData_Overworld_2
ScreenData_Overworld_2_EnemyCode $3F
ScreenData_Overworld_2_CountCode $C0
enum: ScreenData_Overworld_3
ScreenData_Overworld_3_ScreenCode 0
ScreenData_Overworld_3_MixedEnemies $80
enum: DungeonDoor
DungeonDoor_Door 0
DungeonDoor_Wall 1
DungeonDoor_Push 2
DungeonDoor_PushSilent 3
DungeonDoor_BombWall 4
DungeonDoor_LockedDoor 5
DungeonDoor_LockedDoor2 6
DungeonDoor_ShutterDoor 7
enum: InventoryItem
InventoryItem_Sword 0
InventoryItem_Bomb 1
InventoryItem_Arrow 2
InventoryItem_Bow 3
InventoryItem_Candle 4
InventoryItem_Recorder 5
InventoryItem_Meat 6
InventoryItem_Potion 7
InventoryItem_Rod 8
InventoryItem_Raft 9
InventoryItem_Book $A
InventoryItem_Ring $B Passives
InventoryItem_Ladder $C
InventoryItem_MagicKey $D
InventoryItem_PowerBracelet $E
InventoryItem_Letter $F
InventoryItem_Compass $10
InventoryItem_Map $11
InventoryItem_Fairy $14
InventoryItem_Clock $15
InventoryItem_Rupee $16
InventoryItem_Key $17
InventoryItem_HeartContainer $18
InventoryItem_Heart $19
InventoryItem_TriforcePiece $1A
InventoryItem_HoldingUpTriforce $1B This is used when Link is holding a triforce piece over his head.
InventoryItem_5Rupee $1C
InventoryItem_Boomerang $1D
InventoryItem_MagicBoomerang $1E
InventoryItem_Shield $1F
enum: ScreenStatusOverworld
ScreenStatusOverworld_AllEnemiesKilled 7 The number of enemies killed, or 0x07 if all enemies on the screen have been killed.
ScreenStatusOverworld_Visited $20 Same flag in dungeons and overworld
ScreenStatusOverworld_SecretOpened $80
enum: PPUStatusBits
PPUStatusBits_SpriteOverflow $20
PPUStatusBits_Sprite0Hit $40
PPUStatusBits_VBlankStarted $80
enum: PPUMaskBits
PPUMaskBits_Greyscale 1
PPUMaskBits_BackgroundOnLeft8PX 2
PPUMaskBits_SpritesOnLeft8PX 4
PPUMaskBits_ShowBackground 8
PPUMaskBits_ShowSprites $10
PPUMaskBits_EmphasizeRed $20
PPUMaskBits_EmphasizeGreen $40
PPUMaskBits_EmphasizeBlue $80
enum: PPUCommandIndices
PPUCommandIndices_IntroTextRelated_2 2 PPUCommandIndices_Unknown_Copied_Data_0
PPUCommandIndices_GameOverMenu 4
PPUCommandIndices_Unknown_Copied_Data_1 6
PPUCommandIndices_SpecialPaletteMapping_Aquamentus 8
PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo $A
PPUCommandIndices_CurtainsOpening_7 $C PPUCommandIndices_Unknown_Copied_Data_2
PPUCommandIndices_CurtainsOpening_5 $E
PPUCommandIndices_IntroTextRelated_1 $10
PPUCommandIndices_MainMenu_1 $12
PPUCommandIndices_LevelNumber $13
PPUCommandIndices_MainMenu_2 $14
PPUCommandIndices_DeleteSave $16
PPUCommandIndices_DungeonPPUData $18 This sends ppu_data_for_current_dungeon.
PPUCommandIndices_Unknown_20 $20
PPUCommandIndices_Unknown_22 $22
PPUCommandIndices_Unknown_24 $24
PPUCommandIndices_Cellar $26
PPUCommandIndices_JustDied_SetLinkGreyscale $2C
PPUCommandIndices_Unknown_30 $30
PPUCommandIndices_Unknown_32 $32
PPUCommandIndices_Unknown_34 $34
PPUCommandIndices_SpecialPaletteMapping_Ganon $36
PPUCommandIndices_Unknown_38 $38
PPUCommandIndices_Unknown_3a $3A
PPUCommandIndices_Unknown_3C $3C
PPUCommandIndices_Unknown_40 $40
PPUCommandIndices_Unknown_42 $42
PPUCommandIndices_Unknown_44 $44
PPUCommandIndices_TextScrolling $4E
PPUCommandIndices_Unknown_50 $50
PPUCommandIndices_Unknown_Copied_Data_3 $52
PPUCommandIndices_Unknown_Copied_Data_4 $54
PPUCommandIndices_Unknown_Copied_Data_5 $56
PPUCommandIndices_Unknown_Copied_Data_6 $58
PPUCommandIndices_Unknown_5A $5A
PPUCommandIndices_Unknown_Copied_Data_7 $5C
PPUCommandIndices_JustDied_5 $5E
PPUCommandIndices_JustDied_3 $60
PPUCommandIndices_JustDied_4 $62
PPUCommandIndices_Unknown_65 $65
PPUCommandIndices_FoundZeldaPalette $6A
PPUCommandIndices_BombUpgradePrice $6C
PPUCommandIndices_PickedUpTriforce $78
PPUCommandIndices_Unknown_7A $7A
PPUCommandIndices_SpecialPaletteMapping_Gleeok $7C
enum: Sound0
Sound0_BeamSword 1
Sound0_BossPainSound 2
Sound0_Door 4
Sound0_LinkHit 8 Ow
Sound0_BossRoar1 $10
Sound0_BossRoar2 $20
Sound0_BossRoar3 $40
enum: KnockbackFlags
KnockbackFlags_Unknown_0x40 $40
KnockbackFlags_MaintainTileAlignment $80 If set, knockback guarantees that it never puts the object off-axis on both the X and Y axes.
enum: OAMAttributes
OAMAttributes_Palette_1 1
OAMAttributes_Palette_2 2
OAMAttributes_Palette_3 3
OAMAttributes_BehindBackground $20
OAMAttributes_FlipHorizontally $40
OAMAttributes_FlipVertically $80
enum: StoreState
StoreState_CanPickUp 2 Also in this state when we walk into a door repair
StoreState_PickedUpItem 5
StoreState_Finished 8
enum: BeamSwordOrRodState
BeamSwordOrRodState_Beam_Exploding 1
BeamSwordOrRodState_Type_Sword_Beam $10
BeamSwordOrRodState_Type_Rod $80
enum: MMCControl
MMCControl_SingleScreenUpperBank 1
MMCControl_VerticalMirroring 2
MMCControl_HorizontalMirroring 3
MMCControl_PRGMode_FixedBank1 $C This is the only PRG mode used.
enum: ScreenStatusDungeon
ScreenStatusDungeon_WallOpened_Right 1
ScreenStatusDungeon_WallOpened_Left 2
ScreenStatusDungeon_WallOpened_Down 4
ScreenStatusDungeon_WallOpened_Up 8
ScreenStatusDungeon_PickedUpFloorItem $10
ScreenStatusDungeon_Visited $20
ScreenStatusDungeon_AllEnemiesKilled $C0 The number of enemies killed, or 3 (0xC0) if all enemies on the screen have been killed. (This clips to 2, and the actual number of enemies killed is stored in number_of_enemies_killed_in_dungeon_room.)
enum: DamageType
DamageType_Sword 1
DamageType_Boomerang 2
DamageType_Arrow 4
DamageType_Bomb 8
DamageType_Rod $10
DamageType_Fire $20
DamageType_Unknown_40 $40
DamageType_Unknown_80 $80
enum: FloorItem
FloorItem_Bomb 0
FloorItem_WoodSword 1
FloorItem_WhiteSword 2
FloorItem_MagicalSword 3
FloorItem_Meat 4
FloorItem_Recorder 5
FloorItem_BlueCandle 6
FloorItem_RedCandle 7
FloorItem_Arrow 8
FloorItem_SilverArrow 9
FloorItem_Bow $A
FloorItem_MagicKey $B
FloorItem_Raft $C
FloorItem_Ladder $D
FloorItem_GanonTriforce $E
FloorItem_5Rupee $F
FloorItem_Rod $10
FloorItem_Book $11
FloorItem_BlueRing $12
FloorItem_RedRing $13
FloorItem_PowerBracelet $14
FloorItem_Letter $15
FloorItem_Compass $16
FloorItem_Map $17
FloorItem_Rupee $18
FloorItem_Key $19
FloorItem_HeartContainer $1A
FloorItem_TriforcePiece $1B
FloorItem_Shield $1C
FloorItem_Boomerang $1D
FloorItem_MagicBoomerang $1E
FloorItem_BluePotion $1F
FloorItem_RedPotion $20
FloorItem_Clock $21
FloorItem_Heart $22
FloorItem_Fairy $23
enum: EnemyProperties
EnemyProperties_SkipAutomaticUpdate 1 If set, the main object loop won't update the sprite for this object or check for hits. The update for the object will do it instead.
EnemyProperties_DrawHalfTile 2 If set, the enemy's sprite is half a tile (one 8x16 sprite instead of two).
EnemyProperties_SkipAutomaticSpriteUpdate 4 If set, the main object loop won't update the sprite for this object. The update for the object will do it instead. EnemyProperties_SkipAutomaticUpdate also has this effect (but also skips hit detection).
EnemyProperties_FlipHorizontal_MirrorVertical 8 Mirror the sprite when vertical, and flip it when horizontal.
EnemyProperties_ReverseDirectionAtWalls $10 If set, the enemy starts walking in the opposite direction when he hits a wall. Otherwise, it turns 90 degrees and starts walking along the wall instead. This interacts with the enemy's AI (if it's set to rotate 180 degrees, but it's trying to walk towards Link, it'll just turn back on the next tile and bump its head against the wall again).
EnemyProperties_Invincible $20
EnemyProperties_MoveHitboxRight4Pixels $40 If set, set_position_for_hitbox_check shifts the object's hitbox right 4 pixels instead of 8.
enum: AttackType
AttackType_Sword $D
AttackType_SwordBeamOrRodBeam $E The beam of either the beam sword or the rod.
AttackType_BoomerangOrMeat $F Boomerangs and meat share a slot. Firing the boomerang while meat is on the ground makes the meat disappear.
AttackType_BombOrFire1 $10 There are two slots for bombs and fire. Two fires can be shot at once, or a bomb and a fire.
AttackType_BombOrFire2 $11
AttackType_ArrowOrMeleeRod $12 An arrow in the air, or the melee part of the rod attack.
enum: ObjectType
ObjectType_None 0
ObjectType_BlueLynel 1
ObjectType_RedLynel 2
ObjectType_BlueMoblin 3
ObjectType_RedMoblin 4
ObjectType_BlueGoriya 5
ObjectType_RedGoriya 6
ObjectType_RedOctorok 7
ObjectType_RedOctorokFast 8
ObjectType_BlueOctorok 9
ObjectType_BlueOctorokFast $A
ObjectType_RedDarknut $B
ObjectType_BlueDarknut $C
ObjectType_BlueTektite $D
ObjectType_RedTektite $E
ObjectType_BlueLeever $F
ObjectType_RedLeever $10
ObjectType_Zola $11
ObjectType_Vire $12
ObjectType_Zol $13
ObjectType_Gel1 $14
ObjectType_Gel2 $15
ObjectType_PolsVoice $16
ObjectType_LikeLike $17
ObjectType_Digdogger_Spawn $18
ObjectType_Smoke $19
ObjectType_Peahat $1A
ObjectType_BlueKeese $1B
ObjectType_RedKeese $1C
ObjectType_DarkKeese $1D
ObjectType_Armos $1E
ObjectType_FallingRocks_Daemon $1F
ObjectType_FallingRock $20
ObjectType_Ghini $21
ObjectType_GhiniFromTombs $22 Created by handle_spawning_armos_ghini_on_touch
ObjectType_BlueWizzrobe $23
ObjectType_RedWizzrobe $24
ObjectType_Patra_Eye_1 $25 Eyes used by ObjectType_Patra_1.
ObjectType_Patra_Eye_2 $26 Eyes used by ObjectType_Patra_2.
ObjectType_WallMaster $27
ObjectType_Rope $28
ObjectType_Unknown_29 $29 Is this used?
ObjectType_Stalfos $2A
ObjectType_Bubble $2B
ObjectType_BlueBubble $2C
ObjectType_RedBubble $2D
ObjectType_Whirlwind $2E
ObjectType_LakeFairy $2F Drop fairies are FloorPickup objects.
ObjectType_Gibdo $30
ObjectType_DodongoMiniboss $31
ObjectType_DodongoBoss $32
ObjectType_BlueGohma $33
ObjectType_RedGohma $34
ObjectType_TenRupees $35 One rupee, spawned in a pattern of 10
ObjectType_HungryGoriya $36
ObjectType_Zelda $37
ObjectType_Digdogger_3 $38
ObjectType_Digdogger_1 $39
ObjectType_RedLanmola $3A
ObjectType_BlueLanmola $3B
ObjectType_Manhandla $3C
ObjectType_Aquamentus $3D
ObjectType_Ganon $3E
ObjectType_Flame $3F
ObjectType_Flame_Unkillable $40
ObjectType_Moldorm $41
ObjectType_Gleeok_1_Head $42
ObjectType_Gleeok_2_Heads $43
ObjectType_Gleeok_3_Heads $44
ObjectType_Gleeok_4_Heads $45
ObjectType_Gleeok_Flying_Head $46
ObjectType_Patra_1 $47
ObjectType_Patra_2 $48
ObjectType_WallTrap_Vert $49
ObjectType_WallTrap_Horiz $4A
ObjectType_OldMan_Dungeon_Hint_0 $4B DODONGO DISLIKES SMOKE.
ObjectType_OldMan_Dungeon_Hint_1 $4C EASTMOST PENNINSULA IS THE SECRET.
ObjectType_OldMan_Dungeon_Hint_2 $4D SECRET POWER IS SAID TO BE IN THE ARROW.
ObjectType_OldMan_Dungeon_Hint_3 $4E DIGDOGGER HATES CERTAIN KIND OF SOUND.
ObjectType_OldMan_BombUpgrade $4F I BET YOU'D LIKE TO HAVE MORE BOMBS.
ObjectType_OldMan_Dungeon_Hint_4 $50 THERE'S A SECRET IN THE TIP OF THE NOSE.
ObjectType_OldMan_Mugger $51 LEAVE YOUR LIFE OR MONEY.
ObjectType_OldMan_Dungeon_Hint_5 $52 IF YOU GO IN THE DIRECTION OF THE ARROW.
ObjectType_Octorok_Projectile $53
ObjectType_Unknown_Projectile_54 $54
ObjectType_Homing_Fireball_1 $55
ObjectType_Homing_Fireball_2 $56 Fireball_1 can be deflected by the shield. Fireball_2 can't.
ObjectType_Lynel_Sword $57
ObjectType_Projectile_Blue_Wizzrobe_Beam $58
ObjectType_Projectile_Red_Wizzrobe_Beam $59
ObjectType_Unknown_Projectile_5A $5A Does anything create this?
ObjectType_Moblin_Arrow $5B
ObjectType_Goriya_Boomerang $5C
ObjectType_EnemyDeath $5D
ObjectType_RecorderPondDaemon $5E
ObjectType_Ladder $5F
ObjectType_FloorPickup $60 All dead enemies turn into this, whether they actually have a floor pickup or not. If they have no item, this is invisible.
ObjectType_OverworldSecret_Raft $61 An overworld raft spot.
ObjectType_OverworldSecret_Push_Rock $62 An overworld push block (rock sprite).
ObjectType_OverworldSecret_Bomb $63 An overworld bomb spot.
ObjectType_OverworldSecret_Candle $64 An overworld candle spot.
ObjectType_OverworldSecret_Push_Tomb $65 An overworld push block (tomb sprite).
ObjectType_OverworldSecret_Push_Armos $66 An overworld push block (Armos sprite).
ObjectType_OverworldSecret_Bomb_2 $67 An overworld bomb spot. I'm not sure how this differs from ObjectType_OverworldSecret_Bomb.
ObjectType_DungeonSecret_Push_Block $68 An overworld push block.
ObjectType_OldMan_WoodSword $6A
ObjectType_OldMan_TakeAnyOneYouWant $6B
ObjectType_OldMan_SilverSword $6C
ObjectType_OldMan_MasterSword $6D
ObjectType_OldMan_TakeAnyRoad $6E
ObjectType_OldMan_Overworld_Hint $6F Secret is in the tree at the dead-end.
ObjectType_OldMan_MoneyMakingGame $70
ObjectType_OldMan_DoorRepair $71
ObjectType_OldMan_Letter $72
ObjectType_OldWoman_Hint $73 MEET THE OLD MAN AT THE GRAVE.
ObjectType_OldWoman_PotionShop $74
ObjectType_OldWoman_HintShop1 $75
ObjectType_OldWoman_HintShop2 $76
ObjectType_Store_1 $77
ObjectType_Store_2 $78
ObjectType_Store_3 $79
ObjectType_Store_4 $7A
ObjectType_RupeeSecret_Big $7B
ObjectType_RupeeSecret_Middle $7C
ObjectType_RupeeSecret_Small $7D
enum: OverworldTiles
OverworldTiles_CaveOrDungeonEntrance $24
OverworldTiles_Cellar_OldMan $26
OverworldTiles_Ladder1 $74
OverworldTiles_Ladder2 $75
Segment: RAM
RAM:0000 var_0: ; These are all scratch variables, used either as local
  ; variables or as globals local to some piece of logic.
  ; They don't hold long-term state.
RAM:0001 var_1:
RAM:0002 var_2:
RAM:0003 var_3:
RAM:0004 var_4:
RAM:0005 var_5:
RAM:0006 var_6:
RAM:0007 var_7:
RAM:0008 var_8:
RAM:0009 var_9:
RAM:000A var_10:
RAM:000B var_11:
RAM:000C var_12:
RAM:000D var_13:
RAM:000E var_14:
RAM:000F var_15:
RAM:0010 dungeon_idx:
RAM:0011 active_game_mode_task: ; If 0, we run task0 for the current game_mode. If 1, we run task1.
RAM:0012 game_mode:
RAM:0013 task_state: ; The state for the current task. This usually corresponds
  ; with jump tables in functions like task0_Scrolling_work,
  ; and usually gets reset to 0 when changing tasks to start
  ; the new task at the beginning.
RAM:0014 current_ppu_command_index:
RAM:0015 frame_counter:
RAM:0016 current_save_slot: ; The current save slot when in gameplay, or the menu item when on the title menu (which may be register or delete).
RAM:0017 curtains_currently_opening:
  ; Each PRNG byte is shifted into the next one bit per frame, with new bits being generated into prng_0.
RAM:0018 prng_0:
RAM:0019 prng_1:
RAM:001A prng_2:
RAM:001B prng_3:
RAM:001C  
RAM:001D prng_5:
RAM:001E  
RAM:001F  
RAM:0020 prng_8:
RAM:0021  
RAM:0022 prng_A:
RAM:0023  
RAM:0024  
RAM:0025 prng_last:
RAM:0026 ten_frame_counter: ; This counts down one per frame from 9-0, then loops back to 9.
  ; This is only used to know when to update other timers that
  ; update every ten frames.
  ; Timers are from here to 0x004E. The following timers decrement each frame.
  ; All timers clamp to 0 and don't loop. These are all updated at the start of
  ; the frame by OnNMI:update_timers.
RAM:0027 bombed_door_timer: ; This timer is set after bombing a wall in a dungeon. The
  ; hole won't appear until this reaches 0.
RAM:0028 enemy_action_timers: ; A timer for each object. The use of this depends on the
  ; object type, but it's usually a timer until the next action
  ; or state change.
RAM:0029 npc_action_timer_1: ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
RAM:002A npc_action_timer_2:
RAM:002B npc_action_timer_3:
RAM:002C npc_action_timer_4:
RAM:002D npc_action_timer_5:
RAM:002E npc_action_timer_6:
RAM:002F npc_action_timer_7:
RAM:0030 npc_action_timer_8:
RAM:0031 npc_action_timer_9:
RAM:0032 death_cutscene_timer_1: ; This timer is set during the death cutscene, but doesn't seem to be used.
RAM:0033 death_cutscene_timer_2:
RAM:0034 palette_cycle_timer: ; Last NPC action timer.
RAM:0035   ; Unknown timer (are these used by weapon timers, like AttackType_13?)
RAM:0036   ; Unknown timer (unused?)
RAM:0037   ; Unknown timer (unused?)
RAM:0038 bomb_flame_timer:
RAM:0039   ; Unknown timer (unused?)
RAM:003A   ; Unknown timer (unused?)
RAM:003B boomerang_sound_timer:
RAM:003C recorder_lock_timer:
  ; Timers from here down decrement every 10 frames instead
  ; of every frame. This happens when ten_frame_counter cycles.
 
RAM:003D enemy_stun: ; A timer for stun for each object slot (12)
RAM:003E  
RAM:003F  
RAM:0040  
RAM:0041  
RAM:0042  
RAM:0043  
RAM:0044  
RAM:0045  
RAM:0046  
RAM:0047  
RAM:0048  
RAM:0049   ; Last enemy stun timer
RAM:004A enemy_behavior_seeking_timer:
RAM:004B enter_from_side_timer: ; Timer before the next enemy enters from the side.
RAM:004C bubble_sword_timer: ; A timer to disable the sword temporarily when hit by a regular bubble.
  ; See also sword_disabled_by_bubble, which is set when the sword is disabled
  ; permanently by a red (2nd quest) bubble.
RAM:004D leever_timer:
RAM:004E unknown_timer_6:
RAM:004F  
RAM:0050 consecutive_ten_kill_counter:
RAM:0051 reached_ten_kills_with_last_bomb: ; This is set to 1 after killing the 10th enemy with a bomb.
RAM:0052 byte_52:
RAM:0053 in_dungeon_door: ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
RAM:0054 byte_54:
RAM:0055 bombing_or_unlocking_door_direction:
RAM:0056 walking_direction_was_flipped:
RAM:0057 number_of_extra_directions_pressed: ; If two directions are pressed at once, this is set to 1.
RAM:0058 byte_58:
RAM:0059 tmp_result:
RAM:005A is_in_cellar:
RAM:005B next_game_mode:
RAM:005C alternate_ppu_nametable: ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
RAM:005D start_menu_scroll_drawing_map_position: ; The map location of the start menu map that's currently
  ; being drawn.
RAM:005E start_menu_scroll_progress:
RAM:005F byte_5F:
RAM:0060 enemy_behavior_seeking_mode:
RAM:0061 enemy_behavior_seek_x:
RAM:0062 enemy_behavior_seek_y:
RAM:0063 health_refill: ; 0x01 = potion refill, 0x02 = triforce refill, 0x40 = fairy refill
RAM:0064 ladder_object_id:
RAM:0065 link_most_recent_overworld_tile_type:
RAM:0066 song_start_low:
RAM:0067 song_start_high:
RAM:0068 audio_misc_4:
RAM:0069 audio_misc_7:
RAM:006A audio_pulse1_offset:
RAM:006B audio_pulse2_offset:
RAM:006C byte_6C:
RAM:006D audio_misc_3:
RAM:006E audio_rhythm_offset:
RAM:006F audio_rhythm_countdown:
RAM:0070 object_x:
RAM:0071 object_x_1:
RAM:0072 object_x_2:
RAM:0073 object_x_3:
RAM:0074 object_x_4:
RAM:0075 object_x_5:
RAM:0076 object_x_6:
RAM:0077 object_x_7:
RAM:0078 object_x_8:
RAM:0079 object_x_9:
RAM:007A object_x_10:
RAM:007B object_x_11:
RAM:007C object_x_12:
RAM:007D link_melee_x:
RAM:007E link_beam_x:
RAM:007F boomerang_bait_x:
RAM:0080 bomb_1_x:
RAM:0081 bomb_2_x:
RAM:0082 arrow_x:
RAM:0083 floor_item_x:
RAM:0084 object_y:
RAM:0085 object_y_1:
RAM:0086 object_y_2:
RAM:0087 object_y_3:
RAM:0088 object_y_4:
RAM:0089 object_y_5:
RAM:008A object_y_6:
RAM:008B object_y_7:
RAM:008C object_y_8:
RAM:008D object_y_9:
RAM:008E object_y_10:
RAM:008F object_y_11:
RAM:0090 object_y_12:
RAM:0091  
RAM:0092  
RAM:0093  
RAM:0094  
RAM:0095  
RAM:0096 arrow_y:
RAM:0097 floor_item_y:
RAM:0098 object_direction:
RAM:0099 object_direction_1:
RAM:009A  
RAM:009B  
RAM:009C  
RAM:009D  
RAM:009E  
RAM:009F projectile_direction_mask:
RAM:00A0  
RAM:00A1  
RAM:00A2  
RAM:00A3 byte_A3: ; related to push blocks
RAM:00A4  
RAM:00A5  
RAM:00A6  
RAM:00A7 projectile_direction_boomerang:
RAM:00A8  
RAM:00A9  
RAM:00AA  
RAM:00AB current_floor_item:
RAM:00AC walk_state_and_weapon_state: ; This value is Link's walk state. AttackType values indexed from here are the state of Link's weapons.
  ; For example, walk_state_and_weapon_state[AttackType_Sword] is the state of the sword.
RAM:00AD global_room_state: ; Global room state. This is used by the fairy lake, stores, etc.
RAM:00AE enemy_state_10_2:
RAM:00AF  
RAM:00B0  
RAM:00B1  
RAM:00B2  
RAM:00B3  
RAM:00B4  
RAM:00B5 maybe_next_projectile_idx:
RAM:00B6 zola_state_2:
RAM:00B7 byte_B7:
RAM:00B8  
RAM:00B9 sword_state:
RAM:00BA sword_rod_beam_state: ; The state of either the rod beam or the sword beam. Only
  ; one of these can be active at a time. This value is referenced
  ; indirectly through walk_state_and_weapon_state[AttackType_BeamSwordOrRod].
 
  ; 0x10: beam sword in the air
  ; 0x11: beam sword exploding
  ; 0x80: rod beam in the air
RAM:00BB boomerang_or_meat_state: ; 0x80: meat placed
RAM:00BC bomb_or_fire1_state: ; State for AttackType_BombOrFire1 (indexed relative to walk_state_and_weapon_state)
RAM:00BD bomb_or_fire2_state: ; State for AttackType_BombOrFire2 (indexed relative to walk_state_and_weapon_state)
RAM:00BE arrow_or_melee_rod_state: ; The state of an arrow flying, or the melee portion of the rod attack.
 
  ; 0x10: arrow
  ; 0x30: rod melee
RAM:00BF current_room_floor_item_hidden: ; This is 0xFF if the room drop in the current room isn't
  ; visible, eg. because enemies need to be killed or a push
  ; block pushed first.
RAM:00C0 object_knockback:
RAM:00C1 object_knockback_1:
RAM:00C2 object_knockback_2:
RAM:00C3 object_knockback_3:
RAM:00C4 object_knockback_4:
RAM:00C5 object_knockback_5:
RAM:00C6 object_knockback_6:
RAM:00C7 object_knockback_7:
RAM:00C8 object_knockback_8:
RAM:00C9 object_knockback_9:
RAM:00CA object_knockback_10:
RAM:00CB object_knockback_11:
RAM:00CC object_knockback_12:
RAM:00CD  
RAM:00CE byte_CE: ; This is a 16-bit pointer used by ROM2:A3C8, which makes
  ; dynamic code modifications to the SRAM CODE block.
RAM:00CF byte_CF:
RAM:00D0  
RAM:00D1  
RAM:00D2  
RAM:00D3 knockback_frames: ; The number of knockback frames for each object.
RAM:00D4  
RAM:00D5  
RAM:00D6  
RAM:00D7  
RAM:00D8  
RAM:00D9  
RAM:00DA  
RAM:00DB  
RAM:00DC  
RAM:00DD  
RAM:00DE  
RAM:00DF  
RAM:00E0 paused:
RAM:00E1 gameplay_menu_state:
RAM:00E2 byte_E2:
RAM:00E3 do_ppu_work_after_sprite0_next_frame: ; If set, OnNMI does some PPU manipulation after a sprite 0
  ; hit. This is related to set_oam_sprite_0 and is used during
  ; scrolling and overworld cellar transitions.
RAM:00E4  
RAM:00E5 byte_E5:
RAM:00E6 byte_E6:
RAM:00E7 transitioning_direction: ; The mask for the direction we're about to transition.
RAM:00E8 byte_E8:
RAM:00E9 byte_E9:
RAM:00EA displayed_map_location: ; This is only different from map_location during scrolling.
RAM:00EB map_location:
RAM:00EC map_location_transitioning_to:
RAM:00ED byte_ED:
RAM:00EE unlocked_door_directions: ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
RAM:00EF byte_EF:
RAM:00F0  
RAM:00F1  
RAM:00F2  
RAM:00F3 byte_F3:
RAM:00F4 sram_init_finished: ; If 0, run_game_mode_task0 will copy the code block to SRAM.
RAM:00F5 sprite_data_1_initialized:
RAM:00F6 sprite_data_2_initialized:
RAM:00F7 ppu_unknown_task_returns_to_ROM4:
RAM:00F8 controller_1_pressed: ; P1 buttons pressed on this frame
RAM:00F9 controller_2_pressed: ; P2 buttons pressed on this frame
RAM:00FA controller_1_cur: ; P1 buttons being held
RAM:00FB controller_2_cur: ; P2 buttons being held
RAM:00FC desired_ppuscroll_y: ; PPUSCROLL X and Y are set to these at the start of each frame.
RAM:00FD desired_ppuscroll_x:
RAM:00FE current_ppumask:
RAM:00FF current_ppuctrl:
RAM:0100  
RAM:0101  
RAM:0102  
RAM:0103  
RAM:0104  
RAM:0105  
RAM:0106  
RAM:0107  
RAM:0108  
RAM:0109  
RAM:010A  
RAM:010B  
RAM:010C byte_10C:
RAM:010D  
RAM:010E current_object_tile_size_pos:
RAM:010F current_object_tile_size_neg:
RAM:0110  
RAM:0111  
RAM:0112  
RAM:0113  
RAM:0114  
RAM:0115  
RAM:0116  
RAM:0117  
RAM:0118  
RAM:0119  
RAM:011A  
RAM:011B  
RAM:011C  
RAM:011D  
RAM:011E  
RAM:011F  
RAM:0120  
RAM:0121  
RAM:0122  
RAM:0123  
RAM:0124  
RAM:0125  
RAM:0126  
RAM:0127  
RAM:0128  
RAM:0129  
RAM:012A  
RAM:012B  
RAM:012C  
RAM:012D  
RAM:012E  
RAM:012F  
RAM:0130  
RAM:0131  
RAM:0132  
RAM:0133  
RAM:0134  
RAM:0135  
RAM:0136  
RAM:0137  
RAM:0138  
RAM:0139  
RAM:013A  
RAM:013B  
RAM:013C  
RAM:013D  
RAM:013E  
RAM:013F  
RAM:0140  
RAM:0141  
RAM:0142  
RAM:0143  
RAM:0144  
RAM:0145  
RAM:0146  
RAM:0147  
RAM:0148  
RAM:0149  
RAM:014A  
RAM:014B  
RAM:014C  
RAM:014D  
RAM:014E  
RAM:014F  
RAM:0150  
RAM:0151  
RAM:0152  
RAM:0153  
RAM:0154  
RAM:0155  
RAM:0156  
RAM:0157  
RAM:0158  
RAM:0159  
RAM:015A  
RAM:015B  
RAM:015C  
RAM:015D  
RAM:015E  
RAM:015F  
RAM:0160  
RAM:0161  
RAM:0162  
RAM:0163  
RAM:0164  
RAM:0165  
RAM:0166  
RAM:0167  
RAM:0168  
RAM:0169  
RAM:016A  
RAM:016B  
RAM:016C  
RAM:016D  
RAM:016E  
RAM:016F  
RAM:0170  
RAM:0171  
RAM:0172  
RAM:0173  
RAM:0174  
RAM:0175  
RAM:0176  
RAM:0177  
RAM:0178  
RAM:0179  
RAM:017A  
RAM:017B  
RAM:017C  
RAM:017D  
RAM:017E  
RAM:017F  
RAM:0180  
RAM:0181  
RAM:0182  
RAM:0183  
RAM:0184  
RAM:0185  
RAM:0186  
RAM:0187  
RAM:0188  
RAM:0189  
RAM:018A  
RAM:018B  
RAM:018C  
RAM:018D  
RAM:018E  
RAM:018F  
RAM:0190  
RAM:0191  
RAM:0192  
RAM:0193  
RAM:0194  
RAM:0195  
RAM:0196  
RAM:0197  
RAM:0198  
RAM:0199  
RAM:019A  
RAM:019B  
RAM:019C  
RAM:019D  
RAM:019E  
RAM:019F  
RAM:01A0  
RAM:01A1  
RAM:01A2  
RAM:01A3  
RAM:01A4  
RAM:01A5  
RAM:01A6  
RAM:01A7  
RAM:01A8  
RAM:01A9  
RAM:01AA  
RAM:01AB  
RAM:01AC  
RAM:01AD  
RAM:01AE  
RAM:01AF  
RAM:01B0  
RAM:01B1  
RAM:01B2  
RAM:01B3  
RAM:01B4  
RAM:01B5  
RAM:01B6  
RAM:01B7  
RAM:01B8  
RAM:01B9  
RAM:01BA  
RAM:01BB  
RAM:01BC  
RAM:01BD  
RAM:01BE  
RAM:01BF  
RAM:01C0  
RAM:01C1  
RAM:01C2  
RAM:01C3  
RAM:01C4  
RAM:01C5  
RAM:01C6  
RAM:01C7  
RAM:01C8  
RAM:01C9  
RAM:01CA  
RAM:01CB  
RAM:01CC  
RAM:01CD  
RAM:01CE  
RAM:01CF  
RAM:01D0  
RAM:01D1  
RAM:01D2  
RAM:01D3  
RAM:01D4  
RAM:01D5  
RAM:01D6  
RAM:01D7  
RAM:01D8  
RAM:01D9  
RAM:01DA  
RAM:01DB  
RAM:01DC  
RAM:01DD  
RAM:01DE  
RAM:01DF  
RAM:01E0  
RAM:01E1  
RAM:01E2  
RAM:01E3  
RAM:01E4  
RAM:01E5  
RAM:01E6  
RAM:01E7  
RAM:01E8  
RAM:01E9  
RAM:01EA  
RAM:01EB  
RAM:01EC  
RAM:01ED  
RAM:01EE  
RAM:01EF  
RAM:01F0  
RAM:01F1  
RAM:01F2  
RAM:01F3  
RAM:01F4  
RAM:01F5  
RAM:01F6  
RAM:01F7  
RAM:01F8  
RAM:01F9  
RAM:01FA  
RAM:01FB  
RAM:01FC  
RAM:01FD  
RAM:01FE  
RAM:01FF byte_1FF:
RAM:0200 sprite_oam_data: ; This is a 256-byte array of 64 OAMSprites.
RAM:0204 sprite_oam_data_04:
RAM:0205  
RAM:0206  
RAM:0207 sprite_oam_data_07:
RAM:0208 sprite_oam_data_08:
RAM:0209  
RAM:020A  
RAM:020B sprite_oam_data_0B:
RAM:020C  
RAM:020D  
RAM:020E  
RAM:020F  
RAM:0210  
RAM:0211  
RAM:0212  
RAM:0213  
RAM:0214  
RAM:0215  
RAM:0216  
RAM:0217  
RAM:0218  
RAM:0219  
RAM:021A  
RAM:021B  
RAM:021C sprite_oam_data_1C:
RAM:021D sprite_oam_data_1D:
RAM:021E sprite_oam_data_1E:
RAM:021F sprite_oam_data_1F:
RAM:0220 sprite_oam_data_20:
RAM:0221 sprite_oam_data_21:
RAM:0222 sprite_oam_data_22:
RAM:0223 sprite_oam_data_23:
RAM:0224  
RAM:0225  
RAM:0226  
RAM:0227  
RAM:0228  
RAM:0229  
RAM:022A  
RAM:022B  
RAM:022C  
RAM:022D  
RAM:022E  
RAM:022F  
RAM:0230  
RAM:0231  
RAM:0232  
RAM:0233  
RAM:0234  
RAM:0235  
RAM:0236  
RAM:0237  
RAM:0238  
RAM:0239  
RAM:023A  
RAM:023B  
RAM:023C  
RAM:023D  
RAM:023E  
RAM:023F  
RAM:0240 sprite_oam_data_40:
RAM:0241  
RAM:0242  
RAM:0243  
RAM:0244 sprite_oam_data_44:
RAM:0245  
RAM:0246  
RAM:0247  
RAM:0248 sprite_oam_data_48:
RAM:0249 sprite_oam_data_49:
RAM:024A sprite_oam_data_4A:
RAM:024B sprite_oam_data_4B:
RAM:024C sprite_oam_data_4C:
RAM:024D sprite_oam_data_4D:
RAM:024E sprite_oam_data_4E:
RAM:024F sprite_oam_data_4F:
RAM:0250 sprite_oam_data_50:
RAM:0251 sprite_oam_data_51:
RAM:0252 sprite_oam_data_52:
RAM:0253 sprite_oam_data_53:
RAM:0254 sprite_oam_data_54:
RAM:0255 sprite_oam_data_55:
RAM:0256 sprite_oam_data_56:
RAM:0257 sprite_oam_data_57:
RAM:0258 sprite_oam_data_58:
RAM:0259  
RAM:025A  
RAM:025B  
RAM:025C  
RAM:025D  
RAM:025E  
RAM:025F  
RAM:0260  
RAM:0261  
RAM:0262  
RAM:0263  
RAM:0264  
RAM:0265  
RAM:0266  
RAM:0267  
RAM:0268  
RAM:0269  
RAM:026A  
RAM:026B  
RAM:026C  
RAM:026D  
RAM:026E  
RAM:026F  
RAM:0270  
RAM:0271  
RAM:0272  
RAM:0273  
RAM:0274  
RAM:0275  
RAM:0276  
RAM:0277  
RAM:0278  
RAM:0279  
RAM:027A  
RAM:027B  
RAM:027C  
RAM:027D  
RAM:027E  
RAM:027F  
RAM:0280 sprite_oam_data_80:
RAM:0281 sprite_oam_data_81:
RAM:0282 sprite_oam_data_82:
RAM:0283 sprite_oam_data_83:
RAM:0284  
RAM:0285  
RAM:0286  
RAM:0287  
RAM:0288  
RAM:0289  
RAM:028A  
RAM:028B  
RAM:028C  
RAM:028D  
RAM:028E  
RAM:028F  
RAM:0290  
RAM:0291  
RAM:0292  
RAM:0293  
RAM:0294  
RAM:0295  
RAM:0296  
RAM:0297  
RAM:0298  
RAM:0299  
RAM:029A  
RAM:029B  
RAM:029C  
RAM:029D  
RAM:029E  
RAM:029F  
RAM:02A0  
RAM:02A1  
RAM:02A2  
RAM:02A3  
RAM:02A4  
RAM:02A5  
RAM:02A6  
RAM:02A7  
RAM:02A8  
RAM:02A9  
RAM:02AA  
RAM:02AB  
RAM:02AC  
RAM:02AD  
RAM:02AE  
RAM:02AF  
RAM:02B0  
RAM:02B1  
RAM:02B2  
RAM:02B3  
RAM:02B4  
RAM:02B5  
RAM:02B6  
RAM:02B7  
RAM:02B8  
RAM:02B9  
RAM:02BA  
RAM:02BB  
RAM:02BC  
RAM:02BD  
RAM:02BE  
RAM:02BF  
RAM:02C0  
RAM:02C1  
RAM:02C2  
RAM:02C3  
RAM:02C4  
RAM:02C5  
RAM:02C6  
RAM:02C7  
RAM:02C8  
RAM:02C9  
RAM:02CA  
RAM:02CB  
RAM:02CC  
RAM:02CD  
RAM:02CE  
RAM:02CF  
RAM:02D0  
RAM:02D1  
RAM:02D2  
RAM:02D3  
RAM:02D4  
RAM:02D5  
RAM:02D6  
RAM:02D7  
RAM:02D8  
RAM:02D9  
RAM:02DA  
RAM:02DB  
RAM:02DC  
RAM:02DD  
RAM:02DE  
RAM:02DF  
RAM:02E0  
RAM:02E1  
RAM:02E2  
RAM:02E3  
RAM:02E4  
RAM:02E5  
RAM:02E6  
RAM:02E7  
RAM:02E8  
RAM:02E9  
RAM:02EA  
RAM:02EB  
RAM:02EC  
RAM:02ED  
RAM:02EE  
RAM:02EF  
RAM:02F0  
RAM:02F1  
RAM:02F2  
RAM:02F3  
RAM:02F4  
RAM:02F5  
RAM:02F6  
RAM:02F7  
RAM:02F8  
RAM:02F9  
RAM:02FA  
RAM:02FB  
RAM:02FC  
RAM:02FD  
RAM:02FE  
RAM:02FF   ; End of sprite_oam_data array
RAM:0300 ppu_unknown_0:
RAM:0301 ppu_command_buffer_bytes_used: ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
RAM:0302 ppu_command_buffer:
RAM:0303 ppu_command_buffer_01:
RAM:0304 ppu_command_buffer_02:
RAM:0305 ppu_command_buffer_03:
RAM:0306 ppu_command_buffer_04:
RAM:0307 ppu_command_buffer_05:
RAM:0308 ppu_command_buffer_06:
RAM:0309 ppu_command_buffer_07:
RAM:030A ppu_command_buffer_08:
RAM:030B ppu_command_buffer_09:
RAM:030C ppu_command_buffer_0A:
RAM:030D  
RAM:030E ppu_command_buffer_0C:
RAM:030F  
RAM:0310  
RAM:0311  
RAM:0312 ppu_command_buffer_10:
RAM:0313  
RAM:0314 byte_314:
RAM:0315 ppu_command_buffer_13:
RAM:0316 ppu_command_buffer_14:
RAM:0317 ppu_command_buffer_15:
RAM:0318 ppu_command_buffer_16:
RAM:0319  
RAM:031A  
RAM:031B ppu_command_buffer_19:
RAM:031C  
RAM:031D  
RAM:031E  
RAM:031F  
RAM:0320  
RAM:0321 byte_321:
RAM:0322  
RAM:0323  
RAM:0324  
RAM:0325 byte_325:
RAM:0326 byte_326:
RAM:0327 byte_327:
RAM:0328 byte_328:
RAM:0329 byte_329:
RAM:032A  
RAM:032B  
RAM:032C  
RAM:032D  
RAM:032E  
RAM:032F byte_32F:
RAM:0330 byte_330:
RAM:0331  
RAM:0332  
RAM:0333  
RAM:0334  
RAM:0335  
RAM:0336  
RAM:0337  
RAM:0338  
RAM:0339  
RAM:033A  
RAM:033B  
RAM:033C  
RAM:033D  
RAM:033E  
RAM:033F currently_open_doors:
RAM:0340 processing_object_index:
RAM:0341 next_sprite_index:
RAM:0342 first_sprite_index:
RAM:0343 updating_oam_sprite_id_1:
RAM:0344 updating_oam_sprite_id_2:
RAM:0345  
RAM:0346 screen_min_x: ; This is copied from ROM5:B054 byte_17054 on the overworld, and ROM5:B059 in dungeons. See ROM5:B05E setup_byte_346.
RAM:0347 screen_max_x:
RAM:0348 screen_min_y:
RAM:0349 screen_max_y:
RAM:034A screen_first_solid_tile_id: ; Tile IDs >= this value can't be walked through.
RAM:034B projectile_hit_link: ; This is set to 1 by check_link_hit_by_enemy if a projectile
  ; hits Link even if it's deflected by the shield, so it can
  ; be despawned.
RAM:034C enemy_projectile_count:
RAM:034D room_clear: ; All enemies on the room are dead (or there weren't any to begin with)
RAM:034E total_enemies_spawned_in_room:
RAM:034F object_type: ; 5 = blue goriya
  ; 6 = red goriya
  ; 55 = zola fireball
RAM:0350 object_type_1:
RAM:0351 object_type_2:
RAM:0352 object_type_3:
RAM:0353  
RAM:0354 object_type_5:
RAM:0355  
RAM:0356 object_type_7:
RAM:0357  
RAM:0358  
RAM:0359  
RAM:035A object_type_B:
RAM:035B  
RAM:035C  
RAM:035D  
RAM:035E  
RAM:035F first_object_type: ; The first object type on the screen at screen load time. This is only set in dungeons.
RAM:0360  
RAM:0361  
RAM:0362  
RAM:0363  
RAM:0364  
RAM:0365  
RAM:0366  
RAM:0367  
RAM:0368  
RAM:0369  
RAM:036A  
RAM:036B  
RAM:036C  
RAM:036D  
RAM:036E  
RAM:036F  
RAM:0370  
RAM:0371  
RAM:0372  
RAM:0373  
RAM:0374  
RAM:0375  
RAM:0376  
RAM:0377  
RAM:0378  
RAM:0379  
RAM:037A  
RAM:037B  
RAM:037C  
RAM:037D  
RAM:037E  
RAM:037F  
RAM:0380 enemy_state_11:
RAM:0381 enemy_state_11_1:
RAM:0382 unk_382:
RAM:0383 unk_383:
RAM:0384 unk_384:
RAM:0385 unk_385:
RAM:0386 unk_386:
RAM:0387  
RAM:0388  
RAM:0389  
RAM:038A unk_38A:
RAM:038B  
RAM:038C  
RAM:038D  
RAM:038E  
RAM:038F  
RAM:0390  
RAM:0391  
RAM:0392  
RAM:0393  
RAM:0394 object_tile_offset_whole:
RAM:0395 object_tile_offset_whole_1:
RAM:0396 object_tile_offset_whole_2:
RAM:0397 object_tile_offset_whole_3:
RAM:0398 object_tile_offset_whole_4:
RAM:0399 object_tile_offset_whole_5:
RAM:039A object_tile_offset_whole_6:
RAM:039B object_tile_offset_whole_7:
RAM:039C object_tile_offset_whole_8:
RAM:039D object_tile_offset_whole_9:
RAM:039E object_tile_offset_whole_10:
RAM:039F object_tile_offset_whole_11:
RAM:03A0 object_tile_offset_whole_12:
RAM:03A1  
RAM:03A2  
RAM:03A3  
RAM:03A4  
RAM:03A5  
RAM:03A6  
RAM:03A7  
RAM:03A8 object_tile_offset_fraction:
RAM:03A9 object_tile_offset_fraction_1: ; Lots of code refers to this through object_tile_offset_fraction, since object IDs start at 1.
RAM:03AA object_tile_offset_fraction_2:
RAM:03AB object_tile_offset_fraction_3:
RAM:03AC object_tile_offset_fraction_4:
RAM:03AD object_tile_offset_fraction_5:
RAM:03AE object_tile_offset_fraction_6:
RAM:03AF object_tile_offset_fraction_7:
RAM:03B0 object_tile_offset_fraction_8:
RAM:03B1 object_tile_offset_fraction_9:
RAM:03B2 object_tile_offset_fraction_10:
RAM:03B3 object_tile_offset_fraction_11:
RAM:03B4 object_tile_offset_fraction_12:
RAM:03B5  
RAM:03B6  
RAM:03B7  
RAM:03B8  
RAM:03B9  
RAM:03BA  
RAM:03BB  
RAM:03BC object_walk_speed:
RAM:03BD object_walk_speed_1:
RAM:03BE  
RAM:03BF  
RAM:03C0  
RAM:03C1  
RAM:03C2  
RAM:03C3  
RAM:03C4  
RAM:03C5  
RAM:03C6  
RAM:03C7  
RAM:03C8  
RAM:03C9  
RAM:03CA  
RAM:03CB  
RAM:03CC  
RAM:03CD  
RAM:03CE  
RAM:03CF  
RAM:03D0 object_animation_frame_timer: ; This holds animation frame timers for both objects and weapons.
RAM:03D1  
RAM:03D2  
RAM:03D3  
RAM:03D4  
RAM:03D5  
RAM:03D6  
RAM:03D7  
RAM:03D8  
RAM:03D9  
RAM:03DA  
RAM:03DB  
RAM:03DC  
RAM:03DD   ; Weapon timers start here.
RAM:03DE  
RAM:03DF  
RAM:03E0  
RAM:03E1  
RAM:03E2  
RAM:03E3  
RAM:03E4 object_animation_frame:
RAM:03E5  
RAM:03E6  
RAM:03E7  
RAM:03E8  
RAM:03E9  
RAM:03EA  
RAM:03EB  
RAM:03EC  
RAM:03ED  
RAM:03EE  
RAM:03EF  
RAM:03F0  
RAM:03F1  
RAM:03F2  
RAM:03F3  
RAM:03F4  
RAM:03F5  
RAM:03F6  
RAM:03F7  
RAM:03F8 walking_directions:
RAM:03F9  
RAM:03FA  
RAM:03FB  
RAM:03FC  
RAM:03FD  
RAM:03FE  
RAM:03FF  
RAM:0400  
RAM:0401  
RAM:0402  
RAM:0403  
RAM:0404  
RAM:0405 enemy_spawn_state: ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
RAM:0406 enemy_spawn_state_1:
RAM:0407  
RAM:0408  
RAM:0409  
RAM:040A enemy_spawn_state_1_5:
RAM:040B  
RAM:040C  
RAM:040D  
RAM:040E  
RAM:040F  
RAM:0410  
RAM:0411  
RAM:0412 enemy_state_0:
RAM:0413 byte_413:
RAM:0414 byte_414:
RAM:0415 text_scroll_index: ; The index of an old man message to display
RAM:0416 byte_416:
RAM:0417 byte_417:
RAM:0418 byte_418:
RAM:0419 byte_419:
RAM:041A title_screen_timer:
RAM:041B byte_41B:
RAM:041C byte_41C:
RAM:041D byte_41D:
RAM:041E  
RAM:041F enemy_projectile_speed_x:
RAM:0420 enemy_projectile_speed_x_1:
RAM:0421 byte_421:
RAM:0422 store_item:
RAM:0423 byte_423:
RAM:0424 byte_424:
RAM:0425 byte_425:
RAM:0426 byte_426:
RAM:0427 byte_427:
RAM:0428 byte_428:
RAM:0429 byte_429:
RAM:042A byte_42A:
RAM:042B  
RAM:042C enemy_state_4:
RAM:042D enemy_state_4_1:
RAM:042E enemy_state_4_2:
RAM:042F enemy_state_4_3:
RAM:0430 enemy_state_4_4:
RAM:0431 enemy_state_4_5:
RAM:0432 enemy_state_4_6:
RAM:0433  
RAM:0434  
RAM:0435  
RAM:0436 byte_436:
RAM:0437 enemy_state_5:
RAM:0438 enemy_state_5_1:
RAM:0439  
RAM:043A  
RAM:043B  
RAM:043C  
RAM:043D  
RAM:043E  
RAM:043F  
RAM:0440  
RAM:0441  
RAM:0442  
RAM:0443  
RAM:0444 enemy_state_6:
RAM:0445 enemy_state_6_1:
RAM:0446  
RAM:0447  
RAM:0448 enemy_state_6_4:
RAM:0449 enemy_state_6_5:
RAM:044A enemy_state_6_6:
RAM:044B  
RAM:044C  
RAM:044D  
RAM:044E  
RAM:044F  
RAM:0450  
RAM:0451 stop_enemy_for_frames:
RAM:0452 stop_enemy_for_frames_1:
RAM:0453  
RAM:0454  
RAM:0455  
RAM:0456  
RAM:0457  
RAM:0458  
RAM:0459  
RAM:045A  
RAM:045B  
RAM:045C  
RAM:045D  
RAM:045E enemy_state_2:
RAM:045F enemy_state_2_1:
RAM:0460  
RAM:0461  
RAM:0462  
RAM:0463  
RAM:0464  
RAM:0465  
RAM:0466  
RAM:0467  
RAM:0468  
RAM:0469  
RAM:046A  
RAM:046B enemy_state_1:
RAM:046C enemy_state_1_1:
RAM:046D  
RAM:046E  
RAM:046F byte_46F:
RAM:0470 byte_470:
RAM:0471 byte_471:
RAM:0472  
RAM:0473  
RAM:0474  
RAM:0475  
RAM:0476  
RAM:0477  
RAM:0478 enemy_blind_projectile_timer:
RAM:0479 enemy_blind_projectile_timer_1:
RAM:047A  
RAM:047B  
RAM:047C  
RAM:047D  
RAM:047E  
RAM:047F  
RAM:0480  
RAM:0481  
RAM:0482  
RAM:0483  
RAM:0484  
RAM:0485 enemy_health: ; 0xF0 = Enemy health (regular sword = 0x10 damage)
RAM:0486 enemy_health_1:
RAM:0487  
RAM:0488  
RAM:0489  
RAM:048A  
RAM:048B  
RAM:048C  
RAM:048D  
RAM:048E  
RAM:048F  
RAM:0490  
RAM:0491  
RAM:0492 object_slot_in_use: ; I'm not entirely sure how this is used. It's 0xFF when
  ; that object ID doesn't have an enemy in it and 0x00 when
  ; it does, but I'm not sure how that's different from checking
  ; if the object ID isn't 0. Maybe it's only set if that slot
  ; holds an enemy and not a drop or other item?
RAM:0493 byte_493:
RAM:0494 byte_494:
RAM:0495  
RAM:0496  
RAM:0497  
RAM:0498  
RAM:0499  
RAM:049A  
RAM:049B  
RAM:049C  
RAM:049D  
RAM:049E tile_walking_onto: ; 0x74, 0x75: halved movement speed
  ; 0x24: door
RAM:049F  
RAM:04A0  
RAM:04A1  
RAM:04A2  
RAM:04A3  
RAM:04A4  
RAM:04A5  
RAM:04A6  
RAM:04A7  
RAM:04A8  
RAM:04A9  
RAM:04AA  
RAM:04AB  
RAM:04AC  
RAM:04AD  
RAM:04AE  
RAM:04AF  
RAM:04B0  
RAM:04B1  
RAM:04B2 damage_types_with_no_knockback: ; This is a DamageType mask for damage types that don't apply
  ; knockback to this enemy.
RAM:04B3 damage_types_with_no_knockback_1:
RAM:04B4  
RAM:04B5  
RAM:04B6  
RAM:04B7  
RAM:04B8  
RAM:04B9  
RAM:04BA  
RAM:04BB  
RAM:04BC  
RAM:04BD  
RAM:04BE  
RAM:04BF enemy_properties:
RAM:04C0 enemy_state_9_1:
RAM:04C1  
RAM:04C2  
RAM:04C3  
RAM:04C4  
RAM:04C5  
RAM:04C6  
RAM:04C7  
RAM:04C8  
RAM:04C9  
RAM:04CA  
RAM:04CB  
RAM:04CC dungeon_shoots_fireballs:
RAM:04CD current_screen_data_5: ; This is the dungeon_screen_data_5 value for the
  ; current room. This has different interpretations
  ; for the overworld and dungeons.
RAM:04CE open_doors_in_room:
RAM:04CF pushed_dungeon_push_block:
RAM:04D0  
RAM:04D1 increase_enemy_speed_max: ; The max speed that increase_enemy_speed will increase to.
RAM:04D2  
RAM:04D3  
RAM:04D4  
RAM:04D5  
RAM:04D6  
RAM:04D7 processing_gleeok_head: ; The Gleeok head that update_monster_gleeok is currently updating.
RAM:04D8 byte_4D8:
RAM:04D9 byte_4D9:
RAM:04DA byte_4DA:
RAM:04DB byte_4DB:
RAM:04DC byte_4DC:
RAM:04DD byte_4DD:
RAM:04DE byte_4DE:
RAM:04DF  
RAM:04E0  
RAM:04E1  
RAM:04E2  
RAM:04E3  
RAM:04E4 byte_4E4:
RAM:04E5 reset_room_palette_idx_to_0x44:
RAM:04E6 gleeok_body_animation_timer_or_lanmola_something:
RAM:04E7 gleeok_body_frame_or_lanmola_something:
RAM:04E8 byte_4E8:
RAM:04E9  
RAM:04EA  
RAM:04EB  
RAM:04EC  
RAM:04ED  
RAM:04EE  
RAM:04EF  
RAM:04F0 invincibility_frames: ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
RAM:04F1 invincibility_frames_1:
RAM:04F2  
RAM:04F3  
RAM:04F4  
RAM:04F5 invincibility_frames_5:
RAM:04F6  
RAM:04F7  
RAM:04F8  
RAM:04F9  
RAM:04FA  
RAM:04FB  
RAM:04FC  
RAM:04FD  
RAM:04FE  
RAM:04FF  
RAM:0500  
RAM:0501  
RAM:0502  
RAM:0503  
RAM:0504 disable_sprite_horizontal_offset: ; If set, sprites will be placed 4 pixels left of where
  ; they normally are. This is only used by update_hold_up_item_2
  ; while Link is holding an item over his head.
RAM:0505 picking_up_item: ; If Link is holding an item above his head, this is the InventoryItem being held up.
RAM:0506 picking_up_item_timer: ; This timer is set while Link is holding an item over his head.
RAM:0507 number_of_digdogger_spawn_to_create: ; The number of Digdogger spawn that this screen's Digdogger
  ; will break into.
RAM:0508 recorder_called_whirlwind_already: ; If true, the whistle whirlwind has already been called on this
  ; screen, and the player needs to exit the screen to call it
  ; again.
RAM:0509 picking_up_ganon_triforce:
RAM:050A found_zelda_cutscene_state_0:
RAM:050B found_zelda_cutscene_state_1:
RAM:050C found_zelda_cutscene_state_2:
RAM:050D found_zelda_cutscene_state_3:
RAM:050E found_zelda_cutscene_state_4:
RAM:050F byte_50F:
RAM:0510 number_of_spawned_red_leevers_or_gleeok_fast_step_counter: ; On the overworld, this is the number of Gleeoks currently spawned.
  ; For Gleeok, this is set after hit to speed up the body animations temporarily.
RAM:0511 detached_gleeok_heads: ; A mask of Gleeok heads that are detached and flying around the room
RAM:0512 held_by_like_like:
RAM:0513 candle_used_in_current_room:
RAM:0514 is_zola_spawned:
RAM:0515 number_of_spawned_falling_rocks:
RAM:0516  
RAM:0517  
RAM:0518  
RAM:0519 shutter_doors_entered: ; A mask of shutter doors on the current screen that Link has walked into since he entered the screen.
RAM:051A recorder_lake_state: ; 0 = closed, 0x01-0x0B=lake palette shift, 0x0C=open
RAM:051B used_recorder_in_dungeon:
RAM:051C next_palette_cycle:
RAM:051D usually_zero:
RAM:051E paused_lighting_dungeon_room: ; This is 1 while the candle palette shift is happening to
  ; light a dungeon room. The game doesn't update until this
  ; is set back to 0.
RAM:051F lighting_room_state:
RAM:0520  
RAM:0521 previous_unlocked_door_directions:
RAM:0522 held_by_recorder_whirlwind: ; If 1, Link is outbound on the whirlwind.
  ; If 2, Link is inbound on the whirlwind.
RAM:0523 next_recorder_location:
RAM:0524 spawn_position_counter: ; This tracks the next spawn position for enemies.
RAM:0525 spawn_from_side_position:
RAM:0526 overworld_return_pos:
RAM:0527 map_location_in_dungeon_cellar:
RAM:0528 already_exited_title_screen: ; If true, we've exited from the title screen to the main menu
  ; at least once. Once this is true, the title menu will auto-
  ; advance to the main menu in the future if we end up back in
  ; that state (eg. after exiting the create save menu) instead
  ; of showing the title screen again.
RAM:0529 force_beam_sword:
RAM:052A drop_counter:
RAM:052B overworld_room_object_type:
RAM:052C overworld_room_object_x:
RAM:052D overworld_room_object_y:
RAM:052E sword_disabled_by_bubble: ; If true, the sword is disabled permanently by a red (2nd quest)
  ; bubble. See also bubble_sword_timer for regular bubbles.
RAM:052F lost_woods_counter:
RAM:0530 temp_ppu_command_buffer:
RAM:0531  
RAM:0532  
RAM:0533  
RAM:0534  
RAM:0535  
RAM:0536  
RAM:0537  
RAM:0538  
RAM:0539  
RAM:053A  
RAM:053B  
RAM:053C  
RAM:053D  
RAM:053E  
RAM:053F  
RAM:0540  
RAM:0541  
RAM:0542  
RAM:0543  
RAM:0544  
RAM:0545  
RAM:0546  
RAM:0547  
RAM:0548  
RAM:0549  
RAM:054A  
RAM:054B  
RAM:054C  
RAM:054D  
RAM:054E  
RAM:054F  
RAM:0550  
RAM:0551  
RAM:0552  
RAM:0553  
RAM:0554  
RAM:0555  
RAM:0556  
RAM:0557  
RAM:0558  
RAM:0559  
RAM:055A  
RAM:055B  
RAM:055C  
RAM:055D  
RAM:055E  
RAM:055F  
RAM:0560 number_of_enemies_killed_in_dungeon_room:
RAM:0561  
RAM:0562  
RAM:0563  
RAM:0564  
RAM:0565  
RAM:0566  
RAM:0567  
RAM:0568  
RAM:0569  
RAM:056A  
RAM:056B  
RAM:056C  
RAM:056D  
RAM:056E  
RAM:056F  
RAM:0570  
RAM:0571  
RAM:0572  
RAM:0573  
RAM:0574  
RAM:0575  
RAM:0576  
RAM:0577  
RAM:0578  
RAM:0579  
RAM:057A  
RAM:057B  
RAM:057C  
RAM:057D  
RAM:057E  
RAM:057F  
RAM:0580  
RAM:0581  
RAM:0582  
RAM:0583  
RAM:0584  
RAM:0585  
RAM:0586  
RAM:0587  
RAM:0588  
RAM:0589  
RAM:058A  
RAM:058B  
RAM:058C  
RAM:058D  
RAM:058E  
RAM:058F  
RAM:0590  
RAM:0591  
RAM:0592  
RAM:0593  
RAM:0594  
RAM:0595  
RAM:0596  
RAM:0597  
RAM:0598  
RAM:0599  
RAM:059A  
RAM:059B  
RAM:059C  
RAM:059D  
RAM:059E  
RAM:059F  
RAM:05A0  
RAM:05A1  
RAM:05A2  
RAM:05A3  
RAM:05A4  
RAM:05A5  
RAM:05A6  
RAM:05A7  
RAM:05A8  
RAM:05A9  
RAM:05AA  
RAM:05AB  
RAM:05AC  
RAM:05AD  
RAM:05AE  
RAM:05AF  
RAM:05B0  
RAM:05B1  
RAM:05B2  
RAM:05B3  
RAM:05B4  
RAM:05B5  
RAM:05B6  
RAM:05B7  
RAM:05B8  
RAM:05B9  
RAM:05BA  
RAM:05BB  
RAM:05BC  
RAM:05BD  
RAM:05BE  
RAM:05BF  
RAM:05C0  
RAM:05C1  
RAM:05C2  
RAM:05C3  
RAM:05C4  
RAM:05C5  
RAM:05C6  
RAM:05C7  
RAM:05C8  
RAM:05C9  
RAM:05CA  
RAM:05CB  
RAM:05CC  
RAM:05CD  
RAM:05CE  
RAM:05CF  
RAM:05D0  
RAM:05D1  
RAM:05D2  
RAM:05D3  
RAM:05D4  
RAM:05D5  
RAM:05D6  
RAM:05D7  
RAM:05D8  
RAM:05D9  
RAM:05DA  
RAM:05DB  
RAM:05DC  
RAM:05DD  
RAM:05DE  
RAM:05DF  
RAM:05E0  
RAM:05E1  
RAM:05E2  
RAM:05E3  
RAM:05E4  
RAM:05E5  
RAM:05E6  
RAM:05E7  
RAM:05E8  
RAM:05E9  
RAM:05EA  
RAM:05EB  
RAM:05EC  
RAM:05ED  
RAM:05EE  
RAM:05EF  
RAM:05F0 audio_misc_18:
RAM:05F1 audio_misc_19:
RAM:05F2 boss_roar_loop_timer: ; Timer to play audio_looping_boss_sound periodically
RAM:05F3 audio_misc_20:
RAM:05F4 audio_misc_21:
RAM:05F5 audio_misc_22:
RAM:05F6 audio_looping_boss_sound:
RAM:05F7  
RAM:05F8  
RAM:05F9  
RAM:05FA  
RAM:05FB  
RAM:05FC  
RAM:05FD  
RAM:05FE  
RAM:05FF  
 
  ; $600-$61F is audio state.
 
RAM:0600 play_music: ; Set to a nonzero value to start playing music. This is set
  ; back to 0 once the song has started.
RAM:0601 play_sound_0: ; Set to a nonzero value to play a one-off sound effect (this can also start the boss roar loop)
RAM:0602 play_sound_1: ; Set to a nonzero value to play a one-off sound effect
RAM:0603 play_sound_2: ; Set to a nonzero value to play a one-off sound effect
RAM:0604 play_sound_3:
RAM:0605 audio_misc_0605:
RAM:0606 audio_misc_0606:
RAM:0607 audio_misc_0607:
RAM:0608 audio_looping_boss_sound_current:
RAM:0609 current_music: ; Setting to 0 stops the music in place, leaving any note that was playing running
RAM:060A audio_misc_060A:
RAM:060B audio_misc_060B:
RAM:060C audio_misc_060C:
RAM:060D audio_misc_060D:
RAM:060E audio_misc_060E:
RAM:060F audio_misc_060F:
RAM:0610 audio_misc_0610:
RAM:0611 audio_misc_0611:
RAM:0612 audio_misc_0612:
RAM:0613 audio_misc_0613:
RAM:0614 audio_misc_0614:
RAM:0615 audio_misc_0615:
RAM:0616 audio_misc_0616:
RAM:0617 audio_misc_0617:
RAM:0618 audio_misc_0618:
RAM:0619 audio_misc_0619:
RAM:061A audio_misc_061A:
RAM:061B audio_misc_061B:
RAM:061C audio_misc_061C:
RAM:061D audio_misc_061D:
RAM:061E audio_misc_061E:
RAM:061F audio_misc_061F:
RAM:0620 screen_history_idx: ; The next entry in screen_history_0[] to store visited screens.
RAM:0621 screen_history_0:
RAM:0622 screen_history_1:
RAM:0623 screen_history_2:
RAM:0624 screen_history_3:
RAM:0625 screen_history_4:
RAM:0626 screen_history_5:
RAM:0627 consecutive_kill_counter: ; The number of consecutive kills without getting hit.
  ; This isn't reset on drops or forced drops, only when hit.
  ; This wraps past 0xFF.
RAM:0628  
RAM:0629  
RAM:062A  
RAM:062B  
RAM:062C  
RAM:062D quest_no:
RAM:062E  
RAM:062F  
RAM:0630 deaths_per_save_slot:
RAM:0631  
RAM:0632  
RAM:0633 byte_633:
RAM:0634  
RAM:0635  
RAM:0636 byte_636:
RAM:0637 byte_637:
RAM:0638 byte_638:
RAM:0639  
RAM:063A  
RAM:063B  
RAM:063C  
RAM:063D  
RAM:063E  
RAM:063F  
RAM:0640  
RAM:0641  
RAM:0642  
RAM:0643  
RAM:0644  
RAM:0645  
RAM:0646  
RAM:0647  
RAM:0648  
RAM:0649  
RAM:064A  
RAM:064B  
RAM:064C  
RAM:064D  
RAM:064E  
RAM:064F  
RAM:0650 saved_hearts_slot_0:
RAM:0651 saved_partial_hearts_slot_0:
RAM:0652 saved_hearts_slot_1:
RAM:0653 saved_partial_hearts_slot_1:
RAM:0654 saved_hearts_slot_2:
RAM:0655 saved_partial_hearts_slot_2:
RAM:0656 current_item:
RAM:0657 sword_type:
RAM:0658 num_bombs:
RAM:0659 have_arrow_type:
RAM:065A have_bow:
RAM:065B have_candle_type:
RAM:065C have_recorder:
RAM:065D have_meat:
RAM:065E have_potion_type:
RAM:065F have_rod:
RAM:0660 have_raft:
RAM:0661 have_book:
RAM:0662 have_ring_type:
RAM:0663 have_ladder:
RAM:0664 have_magic_key:
RAM:0665 have_power_bracelet:
RAM:0666 have_letter: ; 0 = no letter, 1 = have letter, 2 = showed letter to old woman already
RAM:0667 have_compass_per_dungeon: ; See check_has_compass_in_current_dungeon.
RAM:0668 have_map_per_dungeon:
RAM:0669 have_compass_dungeon_9:
RAM:066A have_map_dungeon_9:
RAM:066B  
RAM:066C clock_active:
RAM:066D num_rupees:
RAM:066E num_keys:
RAM:066F hearts: ; 0xF0 = max hearts, 0x0F = current hearts
RAM:0670 partial_heart: ; Half heart if < 0x80, and a timer for potion refills
RAM:0671 triforce_pieces_collected:
RAM:0672 has_ganon_triforce:
RAM:0673  
RAM:0674 have_boomerang:
RAM:0675 have_magic_boomerang:
RAM:0676 have_magic_shield:
RAM:0677  
RAM:0678  
RAM:0679  
RAM:067A  
RAM:067B  
RAM:067C max_bombs:
RAM:067D pending_rupees_add:
RAM:067E pending_rupees_sub:
RAM:067F screen_status_0:
RAM:0680  
RAM:0681  
RAM:0682  
RAM:0683  
RAM:0684  
RAM:0685  
RAM:0686  
RAM:0687  
RAM:0688  
RAM:0689  
RAM:068A  
RAM:068B  
RAM:068C  
RAM:068D  
RAM:068E  
RAM:068F  
RAM:0690  
RAM:0691  
RAM:0692  
RAM:0693  
RAM:0694  
RAM:0695  
RAM:0696  
RAM:0697  
RAM:0698  
RAM:0699  
RAM:069A  
RAM:069B  
RAM:069C  
RAM:069D  
RAM:069E  
RAM:069F  
RAM:06A0  
RAM:06A1  
RAM:06A2  
RAM:06A3  
RAM:06A4  
RAM:06A5  
RAM:06A6  
RAM:06A7  
RAM:06A8  
RAM:06A9  
RAM:06AA  
RAM:06AB  
RAM:06AC  
RAM:06AD  
RAM:06AE  
RAM:06AF  
RAM:06B0  
RAM:06B1  
RAM:06B2  
RAM:06B3  
RAM:06B4  
RAM:06B5  
RAM:06B6  
RAM:06B7  
RAM:06B8  
RAM:06B9  
RAM:06BA  
RAM:06BB  
RAM:06BC  
RAM:06BD  
RAM:06BE  
RAM:06BF  
RAM:06C0  
RAM:06C1  
RAM:06C2  
RAM:06C3  
RAM:06C4  
RAM:06C5  
RAM:06C6  
RAM:06C7  
RAM:06C8  
RAM:06C9  
RAM:06CA  
RAM:06CB  
RAM:06CC  
RAM:06CD  
RAM:06CE  
RAM:06CF  
RAM:06D0  
RAM:06D1  
RAM:06D2  
RAM:06D3  
RAM:06D4  
RAM:06D5  
RAM:06D6  
RAM:06D7  
RAM:06D8  
RAM:06D9  
RAM:06DA  
RAM:06DB  
RAM:06DC  
RAM:06DD  
RAM:06DE  
RAM:06DF  
RAM:06E0  
RAM:06E1  
RAM:06E2  
RAM:06E3  
RAM:06E4  
RAM:06E5  
RAM:06E6  
RAM:06E7  
RAM:06E8  
RAM:06E9  
RAM:06EA  
RAM:06EB  
RAM:06EC  
RAM:06ED  
RAM:06EE  
RAM:06EF  
RAM:06F0  
RAM:06F1  
RAM:06F2  
RAM:06F3  
RAM:06F4  
RAM:06F5  
RAM:06F6  
RAM:06F7  
RAM:06F8  
RAM:06F9  
RAM:06FA  
RAM:06FB  
RAM:06FC  
RAM:06FD  
RAM:06FE  
RAM:06FF room_data: ; 0x10 got item
  ; 0x20 visited (shown on map)
RAM:0700  
RAM:0701  
RAM:0702  
RAM:0703  
RAM:0704  
RAM:0705  
RAM:0706  
RAM:0707  
RAM:0708  
RAM:0709  
RAM:070A  
RAM:070B  
RAM:070C  
RAM:070D  
RAM:070E  
RAM:070F  
RAM:0710  
RAM:0711  
RAM:0712  
RAM:0713  
RAM:0714  
RAM:0715  
RAM:0716  
RAM:0717  
RAM:0718  
RAM:0719  
RAM:071A  
RAM:071B  
RAM:071C  
RAM:071D  
RAM:071E  
RAM:071F  
RAM:0720  
RAM:0721  
RAM:0722  
RAM:0723  
RAM:0724  
RAM:0725  
RAM:0726  
RAM:0727  
RAM:0728  
RAM:0729  
RAM:072A  
RAM:072B  
RAM:072C  
RAM:072D  
RAM:072E  
RAM:072F  
RAM:0730  
RAM:0731  
RAM:0732  
RAM:0733  
RAM:0734  
RAM:0735  
RAM:0736  
RAM:0737  
RAM:0738  
RAM:0739  
RAM:073A  
RAM:073B  
RAM:073C  
RAM:073D  
RAM:073E  
RAM:073F  
RAM:0740  
RAM:0741  
RAM:0742  
RAM:0743  
RAM:0744  
RAM:0745  
RAM:0746  
RAM:0747  
RAM:0748  
RAM:0749  
RAM:074A  
RAM:074B  
RAM:074C  
RAM:074D  
RAM:074E  
RAM:074F  
RAM:0750  
RAM:0751  
RAM:0752  
RAM:0753  
RAM:0754  
RAM:0755  
RAM:0756  
RAM:0757  
RAM:0758  
RAM:0759  
RAM:075A  
RAM:075B  
RAM:075C  
RAM:075D  
RAM:075E  
RAM:075F  
RAM:0760  
RAM:0761  
RAM:0762  
RAM:0763  
RAM:0764  
RAM:0765  
RAM:0766  
RAM:0767  
RAM:0768  
RAM:0769  
RAM:076A  
RAM:076B  
RAM:076C  
RAM:076D  
RAM:076E  
RAM:076F  
RAM:0770  
RAM:0771  
RAM:0772  
RAM:0773  
RAM:0774  
RAM:0775  
RAM:0776  
RAM:0777  
RAM:0778  
RAM:0779  
RAM:077A  
RAM:077B  
RAM:077C  
RAM:077D  
RAM:077E  
RAM:077F byte_77F:
RAM:0780  
RAM:0781  
RAM:0782  
RAM:0783  
RAM:0784  
RAM:0785  
RAM:0786  
RAM:0787  
RAM:0788  
RAM:0789  
RAM:078A  
RAM:078B  
RAM:078C  
RAM:078D  
RAM:078E  
RAM:078F  
RAM:0790  
RAM:0791  
RAM:0792  
RAM:0793  
RAM:0794  
RAM:0795  
RAM:0796  
RAM:0797  
RAM:0798  
RAM:0799  
RAM:079A  
RAM:079B  
RAM:079C  
RAM:079D  
RAM:079E  
RAM:079F  
RAM:07A0  
RAM:07A1  
RAM:07A2  
RAM:07A3  
RAM:07A4  
RAM:07A5  
RAM:07A6  
RAM:07A7  
RAM:07A8  
RAM:07A9  
RAM:07AA  
RAM:07AB  
RAM:07AC  
RAM:07AD  
RAM:07AE  
RAM:07AF  
RAM:07B0  
RAM:07B1  
RAM:07B2  
RAM:07B3  
RAM:07B4  
RAM:07B5  
RAM:07B6  
RAM:07B7  
RAM:07B8  
RAM:07B9  
RAM:07BA  
RAM:07BB  
RAM:07BC  
RAM:07BD  
RAM:07BE  
RAM:07BF  
RAM:07C0  
RAM:07C1  
RAM:07C2  
RAM:07C3  
RAM:07C4  
RAM:07C5  
RAM:07C6  
RAM:07C7  
RAM:07C8  
RAM:07C9  
RAM:07CA  
RAM:07CB  
RAM:07CC  
RAM:07CD  
RAM:07CE  
RAM:07CF  
RAM:07D0  
RAM:07D1  
RAM:07D2  
RAM:07D3  
RAM:07D4  
RAM:07D5  
RAM:07D6  
RAM:07D7  
RAM:07D8  
RAM:07D9  
RAM:07DA  
RAM:07DB  
RAM:07DC  
RAM:07DD  
RAM:07DE  
RAM:07DF  
RAM:07E0  
RAM:07E1  
RAM:07E2  
RAM:07E3  
RAM:07E4  
RAM:07E5  
RAM:07E6  
RAM:07E7  
RAM:07E8  
RAM:07E9  
RAM:07EA  
RAM:07EB  
RAM:07EC  
RAM:07ED  
RAM:07EE  
RAM:07EF  
RAM:07F0  
RAM:07F1  
RAM:07F2  
RAM:07F3  
RAM:07F4  
RAM:07F5  
RAM:07F6  
RAM:07F7  
RAM:07F8  
RAM:07F9  
RAM:07FA  
RAM:07FB  
RAM:07FC  
RAM:07FD  
RAM:07FE  
RAM:07FF  
 
Segment: IOREGS
IOREGS:2000 PPUCTRL: .BYTE $FF
IOREGS:2001 PPUMASK: .BYTE $FF
IOREGS:2002 PPUSTATUS: .BYTE $FF
IOREGS:2003 OAMADDR: .BYTE $FF
IOREGS:2004 OAMDATA: .BYTE $FF
IOREGS:2005 PPUSCROLL: .BYTE $FF
IOREGS:2006 PPUADDR: .BYTE $FF
IOREGS:2007 PPUDATA: .BYTE $FF
IOREGS:2008   .BYTE $FF
IOREGS:2009   .BYTE $FF
IOREGS:200A   .BYTE $FF
IOREGS:200B   .BYTE $FF
IOREGS:200C   .BYTE $FF
IOREGS:200D   .BYTE $FF
IOREGS:200E   .BYTE $FF
IOREGS:200F   .BYTE $FF
IOREGS:2010   .BYTE $FF
IOREGS:2011   .BYTE $FF
IOREGS:2012   .BYTE $FF
IOREGS:2013   .BYTE $FF
IOREGS:2014   .BYTE $FF
IOREGS:2015   .BYTE $FF
IOREGS:2016   .BYTE $FF
IOREGS:2017   .BYTE $FF
IOREGS:2018   .BYTE $FF
IOREGS:2019   .BYTE $FF
IOREGS:201A   .BYTE $FF
IOREGS:201B   .BYTE $FF
IOREGS:201C   .BYTE $FF
IOREGS:201D   .BYTE $FF
IOREGS:201E   .BYTE $FF
IOREGS:201F unk_201F: .BYTE $FF
 
Segment: ROM0
ROM0:8000 Skipped empty chunk
ROM0:8D5F byte_208D5F:
 
Subroutine audio_update
; This is the main audio update.
ROM0:9825 audio_update:
ROM0:9825 LDA paused
ROM0:9826 BEQ skip_if_not_paused
ROM0:9827 LDA #0
ROM0:9828 STA pAPU_SV_CSR
ROM0:9829 LDA #$F
ROM0:982A STA pAPU_SV_CSR
ROM0:982B BNE silence_sound
 
ROM0:982C skip_if_not_paused:
ROM0:982C LDA #$FF
ROM0:982D STA Joypad_2
ROM0:982E JSR audio_unknown_1
ROM0:982F JSR audio_unknown_4
ROM0:9830 JSR audio_play_boss_roar
ROM0:9831 JSR audio_unknown_6_handle_music
 
ROM0:9832 silence_sound:
ROM0:9832 JSR audio_unknown_6
ROM0:9833 LDA #0
ROM0:9834 STA play_sound_3 ; Set to 0
ROM0:9835 STA play_sound_2 ; Set to 0
ROM0:9836 STA play_sound_1 ; Set to 0
ROM0:9837 STA play_sound_0 ; Set to 0
ROM0:9838 STA play_music ; Set to 0
 
ROM0:985A locret_20985A:
ROM0:985A RTS
 
ROM0:985B byte_20985B: .BYTE $1C
ROM0:985C   .BYTE $4C
ROM0:985D   .BYTE $27
ROM0:985E   .BYTE $5C
ROM0:985F   .BYTE $46
ROM0:9860   .BYTE $67
ROM0:9861   .BYTE 7
ROM0:9862   .BYTE $95
ROM0:9863   .BYTE $50
ROM0:9864   .BYTE 8
ROM0:9865   .BYTE 8
ROM0:9866   .BYTE 8
ROM0:9867   .BYTE 8
ROM0:9868   .BYTE 8
ROM0:9869   .BYTE $90
ROM0:986A   .BYTE 8
ROM0:986B   .BYTE 8
ROM0:986C   .BYTE 8
ROM0:986D   .BYTE 8
ROM0:986E   .BYTE 8
ROM0:986F   .BYTE 8
ROM0:9870   .BYTE 8
ROM0:9871   .BYTE 8
ROM0:9872   .BYTE 8
ROM0:9873   .BYTE 8
ROM0:9874   .BYTE 8
ROM0:9875   .BYTE 8
ROM0:9876   .BYTE 0
ROM0:9877   .BYTE $82
ROM0:9878   .BYTE $4A
ROM0:9879   .BYTE $48
ROM0:987A   .BYTE $4A
ROM0:987B   .BYTE 8
ROM0:987C   .BYTE 8
ROM0:987D   .BYTE 8
ROM0:987E   .BYTE 8
ROM0:987F   .BYTE 8
ROM0:9880   .BYTE 8
ROM0:9881   .BYTE 0
ROM0:9882   .BYTE $9F
ROM0:9883   .BYTE $1E
ROM0:9884   .BYTE $22
ROM0:9885   .BYTE $24
ROM0:9886   .BYTE $26
ROM0:9887   .BYTE $9F
ROM0:9888   .BYTE $28
ROM0:9889   .BYTE $2A
ROM0:988A   .BYTE $2C
ROM0:988B   .BYTE $2E
ROM0:988C   .BYTE $9A
ROM0:988D   .BYTE $28
ROM0:988E   .BYTE $2A
ROM0:988F   .BYTE $2C
ROM0:9890   .BYTE $2E
ROM0:9891   .BYTE $9C
ROM0:9892   .BYTE $28
ROM0:9893   .BYTE $2A
ROM0:9894   .BYTE $2C
ROM0:9895   .BYTE $2E
ROM0:9896   .BYTE $96
ROM0:9897   .BYTE $28
ROM0:9898   .BYTE $2A
ROM0:9899   .BYTE $2C
ROM0:989A   .BYTE $2E
ROM0:989B   .BYTE $98
ROM0:989C   .BYTE $28
ROM0:989D   .BYTE $2A
ROM0:989E   .BYTE $2C
ROM0:989F   .BYTE $2E
ROM0:98A0   .BYTE 0
ROM0:98A1   .BYTE $99
ROM0:98A2   .BYTE $42
ROM0:98A3   .BYTE $4A
ROM0:98A4   .BYTE $50
ROM0:98A5   .BYTE $54
ROM0:98A6   .BYTE 0
ROM0:98A7   .BYTE $99
ROM0:98A8   .BYTE $70
ROM0:98A9   .BYTE $A
ROM0:98AA   .BYTE $70
ROM0:98AB   .BYTE $E
ROM0:98AC   .BYTE $70
ROM0:98AD   .BYTE $10
ROM0:98AE   .BYTE $9F
ROM0:98AF   .BYTE $70
ROM0:98B0   .BYTE $2A
ROM0:98B1   .BYTE $12
ROM0:98B2   .BYTE $1E
ROM0:98B3   .BYTE $2A
ROM0:98B4   .BYTE $70
ROM0:98B5   .BYTE $1E
ROM0:98B6   .BYTE 0
ROM0:98B7   .BYTE $9A
ROM0:98B8   .BYTE $42
ROM0:98B9   .BYTE 8
ROM0:98BA   .BYTE 8
ROM0:98BB   .BYTE $56
ROM0:98BC   .BYTE 8
ROM0:98BD   .BYTE 8
ROM0:98BE   .BYTE 0
ROM0:98BF   .BYTE 8
ROM0:98C0   .BYTE 8
ROM0:98C1   .BYTE 0
ROM0:98C2   .BYTE $9F
ROM0:98C3   .BYTE $40
ROM0:98C4   .BYTE $30
ROM0:98C5   .BYTE $40
ROM0:98C6   .BYTE $3A
ROM0:98C7   .BYTE $28
ROM0:98C8   .BYTE 0
 
Function chunk for audio_unknown_6
ROM0:98C9 audio_unknown_5_thunk:
ROM0:98C9 JMP audio_unknown_5
 
Subroutine audio_unknown_6
ROM0:98CC audio_unknown_6:
 
ROM0:98CC LDA play_sound_3
ROM0:98CD BMI audio_unknown_5_thunk
ROM0:98CE BEQ loc_2098DC
ROM0:98CF CMP #$40
ROM0:98D0 BNE loc_2098E2
ROM0:98D1 LDX audio_misc_0605
ROM0:98D2 BEQ loc_2098E2
 
ROM0:98DC loc_2098DC:
ROM0:98DC LDA audio_misc_0605
ROM0:98DD BNE loc_2098F1
ROM0:98DE RTS
 
ROM0:98E2 loc_2098E2:
ROM0:98E2 STA audio_misc_0605
ROM0:98E3 LDY #0
 
ROM0:98E7 loc_2098E7:
ROM0:98E7 INY
ROM0:98E8 LSR A
ROM0:98E9 BCC loc_2098E7
ROM0:98EA LDA locret_20985A,Y
ROM0:98EB STA audio_misc_060E
 
ROM0:98F1 loc_2098F1:
ROM0:98F1 LDY audio_misc_060E
ROM0:98F2 INC audio_misc_060E
ROM0:98F3 LDA byte_20985B,Y
ROM0:98F4 BMI loc_209911
ROM0:98F5 BNE loc_20991D
ROM0:98F6 LDX #$90
ROM0:98F7 STX pAPU_P_1_CR
ROM0:98F8 LDX #$18
ROM0:98F9 STX pAPU_P_1_CTR
ROM0:98FA LDX #0
ROM0:98FB STX pAPU_P_1_FTR
ROM0:98FC STX audio_misc_0605
ROM0:98FD RTS
 
ROM0:9911 loc_209911:
ROM0:9911 STA pAPU_P_1_CR
ROM0:9912 LDY audio_misc_060E
ROM0:9913 INC audio_misc_060E
ROM0:9914 LDA $985B,Y
 
ROM0:991D loc_20991D:
ROM0:991D JSR audio_unknown_6b
ROM0:991E LDA #$7F
ROM0:991F STA $4001
ROM0:9920 RTS
 
Function chunk for audio_unknown_4
ROM0:9926 loc_209926:
ROM0:9926 LDA #$F
ROM0:9927 STA pAPU_SV_CSR
ROM0:9928 LDA #0
ROM0:9929 STA audio_looping_boss_sound_current
ROM0:992A STA audio_misc_0607
ROM0:992B STA audio_misc_061A
ROM0:992C STA audio_looping_boss_sound
ROM0:992D RTS
 
ROM0:993A loc_20993A:
ROM0:993A STY audio_misc_0606
ROM0:993B LDA #5
ROM0:993C STA audio_misc_7
ROM0:993D LDA play_sound_3
ROM0:993E AND #$EF
ROM0:993F BNE loc_20994B
ROM0:9940 STA play_sound_3
 
ROM0:994B loc_20994B:
ROM0:994B LDY audio_misc_7
ROM0:994C LDA byte_209FBB,Y
ROM0:994D BNE loc_20996E
 
ROM0:9952 loc_209952:
ROM0:9952 STY audio_misc_0606
ROM0:9953 LDA #$38
ROM0:9954 STA audio_misc_7
 
ROM0:9959 loc_209959:
ROM0:9959 LDA #$D
ROM0:995A STA audio_misc_4
 
ROM0:995D loc_20995D:
ROM0:995D DEC audio_misc_4
ROM0:995E LDY audio_misc_4
ROM0:995F BEQ loc_209959
ROM0:9960 CPY #7
ROM0:9961 BCC loc_20996B
ROM0:9962 LDA #$10
ROM0:9963 BNE loc_20997B
 
ROM0:996B loc_20996B:
ROM0:996B LDA byte_209EF4,Y
 
ROM0:996E loc_20996E:
ROM0:996E TAX
ROM0:996F AND #$F
ROM0:9970 STA pAPU_N_FR_1
ROM0:9971 TXA
ROM0:9972 LSR A
ROM0:9973 LSR A
ROM0:9974 LSR A
ROM0:9975 LSR A
ROM0:9976 ORA #$10
 
ROM0:997B loc_20997B:
ROM0:997B STA pAPU_N_CR_1
ROM0:997C LDA #8
ROM0:997D STA pAPU_N_FR_2
ROM0:997E DEC audio_misc_7
 
ROM0:9985 loc_209985:
ROM0:9985 BNE locret_209991
ROM0:9986 LDA #$F0
ROM0:9987 STA pAPU_N_CR_1
ROM0:9988 LDA #0
ROM0:9989 STA audio_misc_0606
 
ROM0:9991 locret_209991:
ROM0:9991 RTS
 
ROM0:9992 loc_209992:
ROM0:9992 STY audio_misc_0606
ROM0:9993 LDA #$A
ROM0:9994 STA audio_misc_7
 
ROM0:9999 loc_209999:
ROM0:9999 LDY audio_misc_7
ROM0:999A LDA audio_data_5,Y
ROM0:999B BNE loc_20996E
 
Subroutine audio_unknown_4
ROM0:99A0 audio_unknown_4:
 
ROM0:99A0 LDY play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99A1 BMI loc_209926
ROM0:99A2 LDA audio_misc_0606
ROM0:99A3 LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99A4 BCS loc_209992
ROM0:99A5 LSR A
ROM0:99A6 BCS loc_209999
ROM0:99A7 LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99A8 BCS loc_20993A
ROM0:99A9 LSR A
ROM0:99AA BCS loc_20994B
ROM0:99AB LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99AC BCS loc_2099E7
ROM0:99AD LSR A
ROM0:99AE BCS loc_2099EE
ROM0:99AF LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99B0 BCS loc_209952
ROM0:99B1 LSR A
ROM0:99B2 BCS loc_20995D
ROM0:99B3 LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99B4 BCS loc_2099D9
ROM0:99B5 LSR A
ROM0:99B6 BCS loc_2099E0
ROM0:99B7 LSR A
ROM0:99B8 BCS loc_209A09
ROM0:99B9 LSR play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM0:99BA BCS loc_2099FD
ROM0:99BB RTS
 
ROM0:99D9 loc_2099D9:
ROM0:99D9 STY audio_misc_0606
ROM0:99DA LDA #$18
ROM0:99DB STA audio_misc_7
 
ROM0:99E0 loc_2099E0:
ROM0:99E0 LDY audio_misc_7
ROM0:99E1 LDA loc_209A3A+2,Y
ROM0:99E2 BNE loc_20996E
 
ROM0:99E7 loc_2099E7:
ROM0:99E7 STY audio_misc_0606
ROM0:99E8 LDA #$20
ROM0:99E9 STA audio_misc_7
 
ROM0:99EE loc_2099EE:
ROM0:99EE LDA audio_misc_7
ROM0:99EF LSR A
ROM0:99F0 TAY
ROM0:99F1 LDX #$E
ROM0:99F2 STX pAPU_N_FR_1
ROM0:99F3 LDA audio_data_4,Y
ROM0:99F4 JMP loc_20997B
 
ROM0:99FD loc_2099FD:
ROM0:99FD STY audio_misc_0606
ROM0:99FE LDA #$D0
ROM0:99FF STA audio_misc_20
ROM0:9A00 LDA #$10
ROM0:9A01 STA audio_misc_4
 
ROM0:9A09 loc_209A09:
ROM0:9A09 LDA audio_misc_20
ROM0:9A0A CMP #$BF
ROM0:9A0B BCC loc_209A14
ROM0:9A0C INC audio_misc_4
ROM0:9A0D BNE loc_209A28
 
ROM0:9A14 loc_209A14:
ROM0:9A14 LDA audio_misc_20
ROM0:9A15 LSR A
ROM0:9A16 BCC loc_209A28
ROM0:9A17 LSR A
ROM0:9A18 BCC loc_209A28
ROM0:9A19 LSR A
ROM0:9A1A BCC loc_209A28
ROM0:9A1B LDA audio_misc_4
ROM0:9A1C CMP #$10
ROM0:9A1D BEQ loc_209A28
ROM0:9A1E DEC audio_misc_4
 
ROM0:9A28 loc_209A28:
ROM0:9A28 LDA audio_misc_4
ROM0:9A29 STA pAPU_N_CR_1
ROM0:9A2A LDX #3
ROM0:9A2B STX pAPU_N_FR_1
ROM0:9A2C LDA #8
ROM0:9A2D STA pAPU_N_FR_2
ROM0:9A2E DEC audio_misc_20
 
ROM0:9A3A loc_209A3A:
ROM0:9A3A JMP loc_209985
 
ROM0:9A3B   .BYTE $1F
ROM0:9A3C   .BYTE $2F
ROM0:9A3D   .BYTE $2E
ROM0:9A3E   .BYTE $3F
ROM0:9A3F   .BYTE $3F
ROM0:9A40   .BYTE $4C
ROM0:9A41   .BYTE $4E
ROM0:9A42   .BYTE $5F
ROM0:9A43   .BYTE $6F
ROM0:9A44   .BYTE $6F
ROM0:9A45   .BYTE $7E
ROM0:9A46   .BYTE $8F
ROM0:9A47   .BYTE $9E
ROM0:9A48   .BYTE $AF
ROM0:9A49   .BYTE $BE
ROM0:9A4A   .BYTE $CF
ROM0:9A4B   .BYTE $DE
ROM0:9A4C   .BYTE $EF
ROM0:9A4D   .BYTE $FE
ROM0:9A4E   .BYTE $FD
ROM0:9A4F   .BYTE $FE
ROM0:9A50   .BYTE $FF
ROM0:9A51   .BYTE $FF
ROM0:9A54 audio_data_1: .BYTE $FE
ROM0:9A55 audio_data_2: .BYTE $C
ROM0:9A56   .BYTE 8
ROM0:9A57   .BYTE $11
ROM0:9A58   .BYTE $1C
ROM0:9A59   .BYTE $28
ROM0:9A5A   .BYTE $33
ROM0:9A5B   .BYTE $40
ROM0:9A5C   .BYTE $62
ROM0:9A5D   .BYTE $8A
ROM0:9A5E   .BYTE $4E
ROM0:9A5F   .BYTE $58
ROM0:9A60   .BYTE $60
ROM0:9A61   .BYTE $8A
ROM0:9A62   .BYTE $5E
ROM0:9A63   .BYTE $94
ROM0:9A64   .BYTE $60
ROM0:9A65   .BYTE 0
ROM0:9A66   .BYTE $8A
ROM0:9A67   .BYTE $42
ROM0:9A68   .BYTE 6
ROM0:9A69   .BYTE $3C
ROM0:9A6A   .BYTE $30
ROM0:9A6B   .BYTE $2E
ROM0:9A6C   .BYTE $3E
ROM0:9A6D   .BYTE $44
ROM0:9A6E   .BYTE $CC
ROM0:9A6F   .BYTE 2
ROM0:9A70   .BYTE 0
ROM0:9A71   .BYTE $83
ROM0:9A72   .BYTE $40
ROM0:9A73   .BYTE $42
ROM0:9A74   .BYTE $48
ROM0:9A75   .BYTE $4A
ROM0:9A76   .BYTE 2
ROM0:9A77   .BYTE $50
ROM0:9A78   .BYTE $4C
ROM0:9A79   .BYTE $54
ROM0:9A7A   .BYTE $94
ROM0:9A7B   .BYTE $56
ROM0:9A7C   .BYTE 0
ROM0:9A7D   .BYTE $94
ROM0:9A7E   .BYTE $3A
ROM0:9A7F   .BYTE $3E
ROM0:9A80   .BYTE $A8
ROM0:9A81   .BYTE $50
ROM0:9A82   .BYTE $8A
ROM0:9A83   .BYTE $4E
ROM0:9A84   .BYTE 2
ROM0:9A85   .BYTE $CC
ROM0:9A86   .BYTE $4A
ROM0:9A87   .BYTE 0
ROM0:9A88   .BYTE $81
ROM0:9A89   .BYTE $28
ROM0:9A8A   .BYTE $3E
ROM0:9A8B   .BYTE $24
ROM0:9A8C   .BYTE $82
ROM0:9A8D   .BYTE $3A
ROM0:9A8E   .BYTE $81
ROM0:9A8F   .BYTE $16
ROM0:9A90   .BYTE $30
ROM0:9A91   .BYTE $1A
ROM0:9A92   .BYTE $82
ROM0:9A93   .BYTE $34
ROM0:9A94   .BYTE 0
ROM0:9A95   .BYTE $94
ROM0:9A96   .BYTE $56
ROM0:9A97   .BYTE $42
ROM0:9A98   .BYTE 2
ROM0:9A99   .BYTE $4C
ROM0:9A9A   .BYTE $52
ROM0:9A9B   .BYTE $42
ROM0:9A9C   .BYTE $5C
ROM0:9A9D   .BYTE $4A
ROM0:9A9E   .BYTE $5A
ROM0:9A9F   .BYTE 2
ROM0:9AA0   .BYTE $4C
ROM0:9AA1   .BYTE $5A
ROM0:9AA2   .BYTE $56
ROM0:9AA3   .BYTE 2
ROM0:9AA4   .BYTE $50
ROM0:9AA5   .BYTE $4C
ROM0:9AA6   .BYTE $5A
ROM0:9AA7   .BYTE 2
ROM0:9AA8   .BYTE $54
ROM0:9AA9   .BYTE $5A
ROM0:9AAA   .BYTE $58
ROM0:9AAB   .BYTE 2
ROM0:9AAC   .BYTE $50
ROM0:9AAD   .BYTE $54
ROM0:9AAE   .BYTE $4C
ROM0:9AAF   .BYTE $42
ROM0:9AB0   .BYTE 2
ROM0:9AB1   .BYTE $4C
ROM0:9AB2   .BYTE $50
ROM0:9AB3   .BYTE $48
ROM0:9AB4   .BYTE $4A
ROM0:9AB5   .BYTE $50
ROM0:9AB6   .BYTE 0
ROM0:9AB7   .BYTE $9E
ROM0:9AB8   .BYTE 8
ROM0:9AB9   .BYTE $85
ROM0:9ABA   .BYTE $3C
ROM0:9ABB   .BYTE $3A
ROM0:9ABC   .BYTE $38
ROM0:9ABD   .BYTE $36
ROM0:9ABE   .BYTE $3A
ROM0:9ABF   .BYTE $38
ROM0:9AC0   .BYTE $36
ROM0:9AC1   .BYTE $34
ROM0:9AC2   .BYTE $38
ROM0:9AC3   .BYTE $36
ROM0:9AC4   .BYTE $34
ROM0:9AC5   .BYTE $32
ROM0:9AC6   .BYTE $36
ROM0:9AC7   .BYTE $34
ROM0:9AC8   .BYTE $32
ROM0:9AC9   .BYTE $30
ROM0:9ACA   .BYTE $34
ROM0:9ACB   .BYTE $32
ROM0:9ACC   .BYTE $30
ROM0:9ACD   .BYTE $2E
ROM0:9ACE   .BYTE $2A
ROM0:9ACF   .BYTE $28
ROM0:9AD0   .BYTE $A8
ROM0:9AD1   .BYTE $26
ROM0:9AD2   .BYTE 0
 
Subroutine audio_unknown_1
ROM0:9AD3 audio_unknown_1:
ROM0:9AD3 LDA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
ROM0:9AD4 BMI loc_209AE0
ROM0:9AD5 BNE loc_209AE5
ROM0:9AD6 LDA audio_misc_0607
ROM0:9AD7 BNE loc_209AF8
ROM0:9AD8 RTS
 
ROM0:9AE0 loc_209AE0:
ROM0:9AE0 JSR audio_unknown_5
ROM0:9AE1 LDA #$80
 
ROM0:9AE5 loc_209AE5:
ROM0:9AE5 STA audio_misc_0607
ROM0:9AE6 LDY #0
 
ROM0:9AEA loc_209AEA:
ROM0:9AEA INY
ROM0:9AEB LSR A
ROM0:9AEC BCC loc_209AEA
ROM0:9AED LDA audio_data_1,Y
ROM0:9AEE STA audio_misc_0618
ROM0:9AEF LDA #1
ROM0:9AF0 STA audio_rhythm_countdown
 
ROM0:9AF8 loc_209AF8:
ROM0:9AF8 DEC audio_rhythm_countdown
ROM0:9AF9 BNE loc_209B45
ROM0:9AFA LDY audio_misc_0618
ROM0:9AFB INC audio_misc_0618
ROM0:9AFC LDA audio_data_2,Y
ROM0:9AFD BMI loc_209B23
ROM0:9AFE BNE loc_209B30
ROM0:9AFF LDA audio_misc_0607
ROM0:9B00 CMP #$40
ROM0:9B01 BEQ loc_209AE5
ROM0:9B02 LDX #$90
ROM0:9B03 STX pAPU_P_2_CR
ROM0:9B04 LDX #$18
ROM0:9B05 STX pAPU_P_2_CTR
ROM0:9B06 LDX #0
ROM0:9B07 STX audio_misc_0607
ROM0:9B08 STX pAPU_P_2_FTR
ROM0:9B09 RTS
 
ROM0:9B23 loc_209B23:
ROM0:9B23 AND #$7F
ROM0:9B24 STA audio_rhythm_offset
ROM0:9B25 LDY audio_misc_0618
ROM0:9B26 INC audio_misc_0618
ROM0:9B27 LDA audio_data_2,Y
 
ROM0:9B30 loc_209B30:
ROM0:9B30 JSR audio_unknown_2
ROM0:9B31 LDA #$7F
ROM0:9B32 STA pAPU_P_2_RCR
ROM0:9B33 LDA #$86
ROM0:9B34 STA pAPU_P_2_CR
ROM0:9B35 LDA audio_rhythm_offset
ROM0:9B36 STA audio_rhythm_countdown
ROM0:9B37 LDA #$1F
ROM0:9B38 STA audio_misc_3
 
ROM0:9B45 loc_209B45:
ROM0:9B45 LDA audio_misc_0607
ROM0:9B46 AND #$90
ROM0:9B47 BEQ locret_209B62
ROM0:9B48 LDY audio_misc_3
ROM0:9B49 BEQ loc_209B52
ROM0:9B4A DEC audio_misc_3
 
ROM0:9B52 loc_209B52:
ROM0:9B52 LDA audio_data_3,Y
ROM0:9B53 STA pAPU_P_2_CR
ROM0:9B54 LDA audio_rhythm_countdown
ROM0:9B55 LDX audio_pulse2_offset
ROM0:9B56 JSR audio_unknown_7
ROM0:9B57 STX pAPU_P_2_FTR
 
ROM0:9B62 locret_209B62:
ROM0:9B62 RTS
 
ROM0:9B63 audio_data_3: .BYTE $95
ROM0:9B64   .BYTE $96
ROM0:9B65   .BYTE $97
ROM0:9B66   .BYTE $98
ROM0:9B67   .BYTE $99
ROM0:9B68   .BYTE $9A
ROM0:9B69   .BYTE $9B
ROM0:9B6A   .BYTE $9C
ROM0:9B6B   .BYTE $9D
ROM0:9B6C   .BYTE $9E
ROM0:9B6D   .BYTE $9F
ROM0:9B6E   .BYTE $9F
ROM0:9B6F   .BYTE $9F
ROM0:9B70   .BYTE $9F
ROM0:9B71   .BYTE $9F
ROM0:9B72   .BYTE $9F
ROM0:9B73   .BYTE $9F
ROM0:9B74   .BYTE $9F
ROM0:9B75   .BYTE $9F
ROM0:9B76   .BYTE $9F
ROM0:9B77   .BYTE $9F
ROM0:9B78   .BYTE $9F
ROM0:9B79   .BYTE $9F
ROM0:9B7A   .BYTE $9E
ROM0:9B7B   .BYTE $9D
ROM0:9B7C   .BYTE $9C
ROM0:9B7D   .BYTE $9B
ROM0:9B7E   .BYTE $9A
ROM0:9B7F   .BYTE $99
ROM0:9B80   .BYTE $98
ROM0:9B81   .BYTE $97
ROM0:9B82   .BYTE $96
 
Subroutine audio_play_boss_roar
ROM0:9B83 audio_play_boss_roar:
ROM0:9B83 LDA play_sound_0 ; Set to a nonzero value to play a one-off sound effect (this can also start the boss roar loop)
ROM0:9B84 BMI loc_209BAF
ROM0:9B85 BNE loc_209BAB
ROM0:9B86 LDA audio_looping_boss_sound_current
ROM0:9B87 BEQ loc_209BA5 ; If the boss sound isn't already going
ROM0:9B88 DEC boss_roar_loop_timer ; Timer to play audio_looping_boss_sound periodically
ROM0:9B89 BNE locret_209BAA ; Wait for the timer to expire
ROM0:9B8A LDA audio_looping_boss_sound_current
ROM0:9B8B AND #$70
ROM0:9B8C BNE loc_209BB3 ; Branch if we've already started playing this boss sound
  ; loop, and just keep playing that one.
ROM0:9B8D LDA #0
ROM0:9B8E STA audio_looping_boss_sound_current ; Clear the current boss sound, and fall through to see
  ; if we should be playing a different one.
ROM0:9B8F LDA #$F
ROM0:9B90 STA pAPU_SV_CSR
 
ROM0:9BA5 loc_209BA5:
ROM0:9BA5 LDA audio_looping_boss_sound
ROM0:9BA6 BNE loc_209BB3
 
ROM0:9BAA locret_209BAA:
ROM0:9BAA RTS
 
ROM0:9BAB loc_209BAB:
ROM0:9BAB LDX #0
ROM0:9BAC BEQ loc_209BB3
 
ROM0:9BAF loc_209BAF:
ROM0:9BAF LDX #$40
ROM0:9BB0 AND #$70
 
ROM0:9BB3 loc_209BB3:
ROM0:9BB3 STX pAPU_DM_DAR
ROM0:9BB4 STA audio_looping_boss_sound_current
ROM0:9BB5 TAX
ROM0:9BB6 AND #$F0
ROM0:9BB7 BEQ loc_209BC1
ROM0:9BB8 STA audio_looping_boss_sound
 
ROM0:9BC1 loc_209BC1:
ROM0:9BC1 TXA
ROM0:9BC2 LDY #0
 
ROM0:9BC4 loc_209BC4:
ROM0:9BC4 INY
ROM0:9BC5 LSR A
ROM0:9BC6 BCC loc_209BC4
ROM0:9BC7 LDA byte_209BF7,Y
ROM0:9BC8 STA pAPU_DM_CR
ROM0:9BC9 LDA locret_209BE9,Y
ROM0:9BCA STA pAPU_DM_AR
ROM0:9BCB LDA byte_209BF0,Y
ROM0:9BCC STA pAPU_DM_DLR
ROM0:9BCD LDA #$A0
ROM0:9BCE STA boss_roar_loop_timer ; Timer to play audio_looping_boss_sound periodically
ROM0:9BCF LDA #$F
ROM0:9BD0 STA pAPU_SV_CSR
ROM0:9BD1 LDA #$1F
ROM0:9BD2 STA pAPU_SV_CSR
 
ROM0:9BE9 locret_209BE9:
ROM0:9BE9 RTS
 
ROM0:9BEA   .BYTE 0
ROM0:9BEB   .BYTE $4C
ROM0:9BEC   .BYTE $80
ROM0:9BED   .BYTE $1D
ROM0:9BEE   .BYTE $20
ROM0:9BEF   .BYTE $28
ROM0:9BF0 byte_209BF0: .BYTE $4C
ROM0:9BF1   .BYTE $75
ROM0:9BF2   .BYTE $C0
ROM0:9BF3   .BYTE $40
ROM0:9BF4   .BYTE $A
ROM0:9BF5   .BYTE $B0
ROM0:9BF6   .BYTE $90
ROM0:9BF7 byte_209BF7: .BYTE $D0
ROM0:9BF8   .BYTE $F
ROM0:9BF9   .BYTE $F
ROM0:9BFA   .BYTE $D
ROM0:9BFB   .BYTE $F
ROM0:9BFC   .BYTE $E
ROM0:9BFD   .BYTE $F
ROM0:9BFE   .BYTE $E
 
Subroutine audio_unknown_6a
ROM0:9BFF audio_unknown_6a:
ROM0:9BFF STY pAPU_P_1_RCR
ROM0:9C00 STX pAPU_P_1_CR
ROM0:9C01 RTS
 
ROM0:9C02   .BYTE $20
ROM0:9C03   .BYTE $FF
ROM0:9C04   .BYTE $9B
 
Subroutine audio_unknown_6b
ROM0:9C09 audio_unknown_6b:
ROM0:9C09 TAY
ROM0:9C0A LDA byte_209F01,Y
ROM0:9C0B BEQ locret_209C1C
ROM0:9C0C STA audio_pulse1_offset
ROM0:9C0D STA pAPU_P_1_FTR
ROM0:9C0E LDA byte_209F00,Y
ROM0:9C0F ORA #8
ROM0:9C10 STA pAPU_P_1_CTR
 
ROM0:9C1C locret_209C1C:
ROM0:9C1C RTS
 
Subroutine audio_unknown_6c
ROM0:9C1D audio_unknown_6c:
ROM0:9C1D STX pAPU_P_2_CR
ROM0:9C1E STY pAPU_P_2_RCR
ROM0:9C1F RTS
 
ROM0:9C20   .BYTE $20
ROM0:9C21   .BYTE $1D
ROM0:9C22   .BYTE $9C
 
Subroutine audio_unknown_2
ROM0:9C27 audio_unknown_2:
ROM0:9C27 TAY
ROM0:9C28 LDA byte_209F01,Y
ROM0:9C29 BEQ locret_209C1C
ROM0:9C2A STA audio_pulse2_offset
ROM0:9C2B STA pAPU_P_2_FTR
ROM0:9C2C LDA byte_209F00,Y
ROM0:9C2D ORA #8
ROM0:9C2E STA pAPU_P_2_CTR
ROM0:9C2F RTS
 
Subroutine audio_unknown_3
ROM0:9C3B audio_unknown_3:
ROM0:9C3B TAY
ROM0:9C3C LDA byte_209F01,Y
ROM0:9C3D BEQ locret_209C1C
ROM0:9C3E STA audio_misc_18
ROM0:9C3F STA pAPU_T_FR_1
ROM0:9C40 LDA byte_209F00,Y
ROM0:9C41 ORA #8
ROM0:9C42 STA pAPU_T_FR_2
ROM0:9C43 RTS
 
Subroutine audio_unknown_7
ROM0:9C50 audio_unknown_7:
ROM0:9C50 CMP #$10
ROM0:9C51 BCC ret
ROM0:9C52 LSR A
ROM0:9C53 LSR A
ROM0:9C54 LSR A
ROM0:9C55 BCS loc_209C5E
ROM0:9C56 TXA
ROM0:9C57 ADC #1
ROM0:9C58 BNE loc_209C62
 
ROM0:9C5E loc_209C5E:
ROM0:9C5E TXA
ROM0:9C5F CLC
ROM0:9C60 ADC #$FF
 
ROM0:9C62 loc_209C62:
ROM0:9C62 TAX
 
ROM0:9C63 ret:
ROM0:9C63 RTS
 
Function chunk for audio_unknown_6_handle_music
ROM0:9C64 loc_209C64:
ROM0:9C64 JMP loc_209D28
 
Subroutine audio_unknown_6_handle_music
ROM0:9C67 audio_unknown_6_handle_music:
 
ROM0:9C67 LDA play_music ; Set to a nonzero value to start playing music. This is set
  ; back to 0 once the song has started.
ROM0:9C68 BNE start_playing_song
ROM0:9C69 LDA current_music ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9C6A BNE loc_209C64
ROM0:9C6B RTS
 
ROM0:9C6C start_playing_song: ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9C6C STA current_music
ROM0:9C6D BMI loc_209C8F
ROM0:9C6E CMP #6
ROM0:9C6F BNE loc_209C7F
ROM0:9C70 LDY #$24
ROM0:9C71 BNE loc_209CE1
 
ROM0:9C7F loc_209C7F:
ROM0:9C7F CMP #1
ROM0:9C80 BEQ loc_209C97
ROM0:9C81 CMP #$40
ROM0:9C82 BEQ loc_209C93
ROM0:9C83 CMP #$10
ROM0:9C84 BNE loc_209C9B
ROM0:9C85 LDY #$11
ROM0:9C86 BNE loc_209C99
 
ROM0:9C8F loc_209C8F:
ROM0:9C8F LDY #$19
ROM0:9C90 BNE loc_209C99
 
ROM0:9C93 loc_209C93:
ROM0:9C93 LDY #$F
ROM0:9C94 BNE loc_209C99
 
ROM0:9C97 loc_209C97:
ROM0:9C97 LDY #8
 
ROM0:9C99 loc_209C99:
ROM0:9C99 STY byte_6C
 
ROM0:9C9B loc_209C9B:
ROM0:9C9B TAX
ROM0:9C9C BMI loc_209CCE
ROM0:9C9D CMP #1
ROM0:9C9E BEQ loc_209CC2
ROM0:9C9F CMP #$40
ROM0:9CA0 BEQ loc_209CB6
ROM0:9CA1 CMP #$10
ROM0:9CA2 BNE loc_209CDA
ROM0:9CA3 INC byte_6C
ROM0:9CA4 LDY byte_6C
ROM0:9CA5 CPY #$1A
ROM0:9CA6 BNE loc_209CE1
ROM0:9CA7 LDY #$14
ROM0:9CA8 BNE loc_209C99
 
ROM0:9CB6 loc_209CB6:
ROM0:9CB6 INC byte_6C
ROM0:9CB7 LDY byte_6C
ROM0:9CB8 CPY #$12
ROM0:9CB9 BNE loc_209CE1
ROM0:9CBA LDY #$F
ROM0:9CBB BNE loc_209C99
 
ROM0:9CC2 loc_209CC2:
ROM0:9CC2 INC byte_6C
ROM0:9CC3 LDY byte_6C
ROM0:9CC4 CPY #$10
ROM0:9CC5 BNE loc_209CE1
ROM0:9CC6 LDY #9
ROM0:9CC7 BNE loc_209C99
 
ROM0:9CCE loc_209CCE:
ROM0:9CCE INC byte_6C
ROM0:9CCF LDY byte_6C
ROM0:9CD0 CPY #$24
ROM0:9CD1 BNE loc_209CE1
ROM0:9CD2 LDY #$19
ROM0:9CD3 BNE loc_209C99
 
ROM0:9CDA loc_209CDA:
ROM0:9CDA TXA
ROM0:9CDB LDY #0
 
ROM0:9CDD loc_209CDD:
ROM0:9CDD INY
ROM0:9CDE LSR A
ROM0:9CDF BCC loc_209CDD
 
ROM0:9CE1 loc_209CE1:
ROM0:9CE1 LDA byte_208D5F,Y
ROM0:9CE2 TAY
ROM0:9CE3 LDA byte_208D60,Y
ROM0:9CE4 STA audio_misc_21
ROM0:9CE5 LDA byte_208D61,Y
ROM0:9CE6 STA song_start_low
ROM0:9CE7 LDA byte_208D62,Y
ROM0:9CE8 STA song_start_high
ROM0:9CE9 LDA byte_208D63,Y
ROM0:9CEA STA audio_misc_060C
ROM0:9CEB LDA byte_208D64,Y
ROM0:9CEC STA audio_misc_060B
ROM0:9CED LDA byte_208D65,Y
ROM0:9CEE STA audio_misc_060D
ROM0:9CEF STA audio_misc_22
ROM0:9CF0 LDA byte_208D66,Y
ROM0:9CF1 STA audio_misc_0619
ROM0:9CF2 LDA byte_208D67,Y
ROM0:9CF3 STA audio_misc_19
ROM0:9CF4 LDA #1
ROM0:9CF5 STA audio_misc_0611
ROM0:9CF6 STA audio_misc_0613
ROM0:9CF7 STA audio_misc_0616
ROM0:9CF8 STA audio_misc_0617
ROM0:9CF9 LSR A
ROM0:9CFA STA audio_misc_060A
 
ROM0:9D28 loc_209D28:
ROM0:9D28 DEC audio_misc_0611
ROM0:9D29 BNE loc_209D7F
ROM0:9D2A LDY audio_misc_060A
ROM0:9D2B INC audio_misc_060A
ROM0:9D2C LDA (song_start_low),Y
ROM0:9D2D BEQ loc_209D3B
ROM0:9D2E BPL loc_209D61
ROM0:9D2F BNE loc_209D53
 
ROM0:9D3B loc_209D3B: ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9D3B LDA current_music
ROM0:9D3C AND #$F1
ROM0:9D3D BNE loc_209D50
 
Subroutine audio_unknown_5
ROM0:9D42 audio_unknown_5:
ROM0:9D42 LDA #0
ROM0:9D43 STA current_music ; Set to 0
ROM0:9D44 STA pAPU_SV_CSR
ROM0:9D45 LDA #$F
ROM0:9D46 STA pAPU_SV_CSR
ROM0:9D47 RTS
 
Function chunk for audio_unknown_6_handle_music
ROM0:9D50 loc_209D50:
ROM0:9D50 JMP loc_209C9B
 
ROM0:9D53 loc_209D53:
ROM0:9D53 JSR audio_unknown_6e
ROM0:9D54 STA audio_misc_0610
ROM0:9D55 LDY audio_misc_060A
ROM0:9D56 INC audio_misc_060A
ROM0:9D57 LDA (song_start_low),Y
 
ROM0:9D61 loc_209D61:
ROM0:9D61 LDX audio_misc_0607
ROM0:9D62 BNE loc_209D79
ROM0:9D63 JSR audio_unknown_2
ROM0:9D64 BEQ loc_209D6E
ROM0:9D65 JSR audio_unknown_6f
 
ROM0:9D6E loc_209D6E:
ROM0:9D6E STA audio_misc_0612
ROM0:9D6F JSR audio_unknown_6c
ROM0:9D70 LDA #0
ROM0:9D71 STA audio_misc_061B
 
ROM0:9D79 loc_209D79:
ROM0:9D79 LDA audio_misc_0610
ROM0:9D7A STA audio_misc_0611
 
ROM0:9D7F loc_209D7F:
ROM0:9D7F LDY audio_misc_0607
ROM0:9D80 BNE loc_209DAA
ROM0:9D81 INC audio_misc_061B
ROM0:9D82 LDY audio_misc_0612
ROM0:9D83 BEQ loc_209D8F
ROM0:9D84 DEC audio_misc_0612
 
ROM0:9D8F loc_209D8F:
ROM0:9D8F JSR audio_unknown_6g
ROM0:9D90 STA pAPU_P_2_CR
ROM0:9D91 LDX #$7F
ROM0:9D92 STX pAPU_P_2_RCR
ROM0:9D93 LDA current_music ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9D94 BPL loc_209DAA
ROM0:9D95 LDA audio_misc_061B
ROM0:9D96 LDX audio_pulse2_offset
ROM0:9D97 JSR audio_unknown_7
ROM0:9D98 STX pAPU_P_2_FTR
 
ROM0:9DAA loc_209DAA:
ROM0:9DAA LDY audio_misc_060B
ROM0:9DAB BEQ loc_209E15
ROM0:9DAC DEC audio_misc_0613
ROM0:9DAD BNE loc_209DEA
ROM0:9DAE LDY audio_misc_060B
ROM0:9DAF INC audio_misc_060B
ROM0:9DB0 LDA (song_start_low),Y
ROM0:9DB1 BPL loc_209DCC
ROM0:9DB2 JSR audio_unknown_6e
ROM0:9DB3 STA audio_misc_060F
ROM0:9DB4 LDY audio_misc_060B
ROM0:9DB5 INC audio_misc_060B
ROM0:9DB6 LDA (song_start_low),Y
 
ROM0:9DCC loc_209DCC:
ROM0:9DCC LDX audio_misc_0605
ROM0:9DCD BNE loc_209DE4
ROM0:9DCE JSR audio_unknown_6b
ROM0:9DCF BEQ loc_209DD9
ROM0:9DD0 JSR audio_unknown_6f
 
ROM0:9DD9 loc_209DD9:
ROM0:9DD9 STA audio_misc_0614
ROM0:9DDA JSR audio_unknown_6a
ROM0:9DDB LDA #0
ROM0:9DDC STA audio_misc_061C
 
ROM0:9DE4 loc_209DE4:
ROM0:9DE4 LDA audio_misc_060F
ROM0:9DE5 STA audio_misc_0613
 
ROM0:9DEA loc_209DEA:
ROM0:9DEA LDX audio_misc_0605
ROM0:9DEB BNE loc_209E15
ROM0:9DEC INC audio_misc_061C
ROM0:9DED LDY audio_misc_0614
ROM0:9DEE BEQ loc_209DFA
ROM0:9DEF DEC audio_misc_0614
 
ROM0:9DFA loc_209DFA:
ROM0:9DFA JSR audio_unknown_6g
ROM0:9DFB STA pAPU_P_1_CR
ROM0:9DFC LDA current_music ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9DFD BPL loc_209E10
ROM0:9DFE LDA audio_misc_061C
ROM0:9DFF LDX audio_pulse1_offset
ROM0:9E00 JSR audio_unknown_7
ROM0:9E01 STX pAPU_P_1_FTR
 
ROM0:9E10 loc_209E10:
ROM0:9E10 LDA #$7F
ROM0:9E11 STA pAPU_P_1_RCR
 
ROM0:9E15 loc_209E15:
ROM0:9E15 LDA audio_misc_060C
ROM0:9E16 BNE loc_209E1D
ROM0:9E17 JMP loc_209E91
 
ROM0:9E1D loc_209E1D:
ROM0:9E1D DEC audio_misc_0616
ROM0:9E1E BNE loc_209E74
 
ROM0:9E22 loc_209E22:
ROM0:9E22 LDY audio_misc_060C
ROM0:9E23 INC audio_misc_060C
ROM0:9E24 LDA (song_start_low),Y
ROM0:9E25 BEQ loc_209E8E
ROM0:9E26 BPL loc_209E66
ROM0:9E27 CMP #$F0
ROM0:9E28 BEQ loc_209E43
ROM0:9E29 BCC loc_209E51
ROM0:9E2A SEC
ROM0:9E2B SBC #$F0
ROM0:9E2C STA audio_misc_061E
ROM0:9E2D LDA audio_misc_060C
ROM0:9E2E STA audio_misc_061F
ROM0:9E2F JMP loc_209E22
 
ROM0:9E43 loc_209E43:
ROM0:9E43 DEC audio_misc_061E
ROM0:9E44 BEQ loc_209E4E
ROM0:9E45 LDA audio_misc_061F
ROM0:9E46 STA audio_misc_060C
 
ROM0:9E4E loc_209E4E:
ROM0:9E4E JMP loc_209E22
 
ROM0:9E51 loc_209E51:
ROM0:9E51 JSR audio_unknown_6e
ROM0:9E52 STA audio_misc_0615
ROM0:9E53 LDA #$1F
ROM0:9E54 STA pAPU_T_CR_1
ROM0:9E55 LDY audio_misc_060C
ROM0:9E56 INC audio_misc_060C
ROM0:9E57 LDA (song_start_low),Y
ROM0:9E58 BEQ loc_209E8E
 
ROM0:9E66 loc_209E66:
ROM0:9E66 JSR audio_unknown_3
ROM0:9E67 LDA #0
ROM0:9E68 STA audio_misc_061D
ROM0:9E69 LDX audio_misc_0615
ROM0:9E6A STX audio_misc_0616
 
ROM0:9E74 loc_209E74:
ROM0:9E74 INC audio_misc_061D
ROM0:9E75 LDA audio_misc_061D
ROM0:9E76 LDX audio_misc_18
ROM0:9E77 JSR audio_unknown_7
ROM0:9E78 STX pAPU_T_FR_1
ROM0:9E79 LDA audio_misc_19
ROM0:9E7A BPL loc_209E8C
ROM0:9E7B LDA #$1F
ROM0:9E7C BNE loc_209E8E
 
ROM0:9E8C loc_209E8C:
ROM0:9E8C LDA #$FF
 
ROM0:9E8E loc_209E8E:
ROM0:9E8E STA pAPU_T_CR_1
 
ROM0:9E91 loc_209E91: ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM0:9E91 LDA current_music
ROM0:9E92 AND #$91
ROM0:9E93 BEQ locret_209ECF
ROM0:9E94 DEC audio_misc_0617
ROM0:9E95 BNE locret_209ECF
 
ROM0:9E9D loc_209E9D:
ROM0:9E9D LDY audio_misc_060D
ROM0:9E9E INC audio_misc_060D
ROM0:9E9F LDA (song_start_low),Y
ROM0:9EA0 BNE loc_209EAF
ROM0:9EA1 LDA audio_misc_22
ROM0:9EA2 STA audio_misc_060D
ROM0:9EA3 BNE loc_209E9D
 
ROM0:9EAF loc_209EAF:
ROM0:9EAF JSR audio_unknown_6d
ROM0:9EB0 STA audio_misc_0617
ROM0:9EB1 TXA
ROM0:9EB2 AND #$3E
ROM0:9EB3 LSR A
ROM0:9EB4 LSR A
ROM0:9EB5 LSR A
ROM0:9EB6 LSR A
ROM0:9EB7 TAY
ROM0:9EB8 LDA $9ED0,Y
ROM0:9EB9 STA $400C
ROM0:9EBA LDA $9ED4,Y
ROM0:9EBB STA $400E
ROM0:9EBC LDA $9ED8,Y
ROM0:9EBD STA $400F
 
ROM0:9ECF locret_209ECF:
ROM0:9ECF RTS
 
ROM0:9ED0   .BYTE $10
ROM0:9ED1   .BYTE $1C
ROM0:9ED2   .BYTE $1C
ROM0:9ED3   .BYTE $1C
ROM0:9ED4   .BYTE 0
ROM0:9ED5   .BYTE 3
ROM0:9ED6   .BYTE $A
ROM0:9ED7   .BYTE 3
ROM0:9ED8   .BYTE 0
ROM0:9ED9   .BYTE $18
ROM0:9EDA   .BYTE $18
ROM0:9EDB   .BYTE $58
 
Subroutine audio_unknown_6d
ROM0:9EDC audio_unknown_6d:
ROM0:9EDC TAX
ROM0:9EDD ROR A
ROM0:9EDE TXA
ROM0:9EDF ROL A
ROM0:9EE0 ROL A
ROM0:9EE1 ROL A
 
Subroutine audio_unknown_6e
ROM0:9EE2 audio_unknown_6e:
ROM0:9EE2 AND #7
ROM0:9EE3 CLC
ROM0:9EE4 ADC audio_misc_21
ROM0:9EE5 TAY
ROM0:9EE6 LDA byte_209FD1,Y
ROM0:9EE7 RTS
 
ROM0:9EE8   .BYTE $29
ROM0:9EE9   .BYTE 7
ROM0:9EEA   .BYTE $A8
ROM0:9EEB   .BYTE $B9
ROM0:9EEC   .BYTE $D1
ROM0:9EED   .BYTE $9F
ROM0:9EEE   .BYTE $60
ROM0:9EF4 byte_209EF4: .BYTE $CB
ROM0:9EF5   .BYTE $E
ROM0:9EF6   .BYTE $E
ROM0:9EF7   .BYTE $4C
ROM0:9EF8   .BYTE $6D
ROM0:9EF9   .BYTE $8C
ROM0:9EFA   .BYTE $CD
ROM0:9EFB   .BYTE $FF
ROM0:9EFC   .BYTE $FF
ROM0:9EFD   .BYTE $FF
ROM0:9EFE   .BYTE $FF
ROM0:9EFF   .BYTE $FF
ROM0:9F00 byte_209F00: .BYTE 0
ROM0:9F01 byte_209F01: .BYTE $23
ROM0:9F02   .BYTE 0
ROM0:9F03   .BYTE $6A
ROM0:9F04   .BYTE 3
ROM0:9F05   .BYTE $27
ROM0:9F06   .BYTE 0
ROM0:9F07   .BYTE $97
ROM0:9F08   .BYTE 0
ROM0:9F09   .BYTE 0
ROM0:9F0A   .BYTE 2
ROM0:9F0B   .BYTE $F9
ROM0:9F0C   .BYTE 2
ROM0:9F0D   .BYTE $CF
ROM0:9F0E   .BYTE 2
ROM0:9F0F   .BYTE $A6
ROM0:9F10   .BYTE 2
ROM0:9F11   .BYTE $80
ROM0:9F12   .BYTE 2
ROM0:9F13   .BYTE $5C
ROM0:9F14   .BYTE 2
ROM0:9F15   .BYTE $3A
ROM0:9F16   .BYTE 2
ROM0:9F17   .BYTE $1A
ROM0:9F18   .BYTE 1
ROM0:9F19   .BYTE $FC
ROM0:9F1A   .BYTE 1
ROM0:9F1B   .BYTE $DF
ROM0:9F1C   .BYTE 1
ROM0:9F1D   .BYTE $C4
ROM0:9F1E   .BYTE 1
ROM0:9F1F   .BYTE $AB
ROM0:9F20   .BYTE 1
ROM0:9F21   .BYTE $93
ROM0:9F22   .BYTE 1
ROM0:9F23   .BYTE $7C
ROM0:9F24   .BYTE 1
ROM0:9F25   .BYTE $67
ROM0:9F26   .BYTE 1
ROM0:9F27   .BYTE $53
ROM0:9F28   .BYTE 1
ROM0:9F29   .BYTE $40
ROM0:9F2A   .BYTE 1
ROM0:9F2B   .BYTE $2E
ROM0:9F2C   .BYTE 1
ROM0:9F2D   .BYTE $1D
ROM0:9F2E   .BYTE 1
ROM0:9F2F   .BYTE $D
ROM0:9F30   .BYTE 0
ROM0:9F31   .BYTE $FE
ROM0:9F32   .BYTE 0
ROM0:9F33   .BYTE $EF
ROM0:9F34   .BYTE 0
ROM0:9F35   .BYTE $E2
ROM0:9F36   .BYTE 0
ROM0:9F37   .BYTE $D5
ROM0:9F38   .BYTE 0
ROM0:9F39   .BYTE $C9
ROM0:9F3A   .BYTE 0
ROM0:9F3B   .BYTE $BE
ROM0:9F3C   .BYTE 0
ROM0:9F3D   .BYTE $B3
ROM0:9F3E   .BYTE 0
ROM0:9F3F   .BYTE $A9
ROM0:9F40   .BYTE 0
ROM0:9F41   .BYTE $A0
ROM0:9F42   .BYTE 0
ROM0:9F43   .BYTE $8E
ROM0:9F44   .BYTE 0
ROM0:9F45   .BYTE $86
ROM0:9F46   .BYTE 0
ROM0:9F47   .BYTE $77
ROM0:9F48   .BYTE 0
ROM0:9F49   .BYTE $7E
ROM0:9F4A   .BYTE 0
ROM0:9F4B   .BYTE $71
ROM0:9F4C   .BYTE 0
ROM0:9F4D   .BYTE $54
ROM0:9F4E   .BYTE 0
ROM0:9F4F   .BYTE $64
ROM0:9F50   .BYTE 0
ROM0:9F51   .BYTE $5F
ROM0:9F52   .BYTE 0
ROM0:9F53   .BYTE $59
ROM0:9F54   .BYTE 0
ROM0:9F55   .BYTE $50
ROM0:9F56   .BYTE 0
ROM0:9F57   .BYTE $47
ROM0:9F58   .BYTE 0
ROM0:9F59   .BYTE $43
ROM0:9F5A   .BYTE 0
ROM0:9F5B   .BYTE $3F
ROM0:9F5C   .BYTE 0
ROM0:9F5D   .BYTE $38
ROM0:9F5E   .BYTE 0
ROM0:9F5F   .BYTE $32
ROM0:9F60   .BYTE 0
ROM0:9F61   .BYTE $21
ROM0:9F62   .BYTE 5
ROM0:9F63   .BYTE $4D
ROM0:9F64   .BYTE 5
ROM0:9F65   .BYTE 1
ROM0:9F66   .BYTE 4
ROM0:9F67   .BYTE $B9
ROM0:9F68   .BYTE 4
ROM0:9F69   .BYTE $35
ROM0:9F6A   .BYTE 3
ROM0:9F6B   .BYTE $F8
ROM0:9F6C   .BYTE 3
ROM0:9F6D   .BYTE $BF
ROM0:9F6E   .BYTE 3
ROM0:9F6F   .BYTE $89
ROM0:9F70   .BYTE 3
ROM0:9F71   .BYTE $57
 
Subroutine audio_unknown_6f
ROM0:9F72 audio_unknown_6f:
ROM0:9F72 LDA audio_misc_0619
ROM0:9F73 LDA #$20
ROM0:9F74 LDX #$82
ROM0:9F75 LDY #$7F
ROM0:9F76 RTS
 
Subroutine audio_unknown_6g
ROM0:9F7C audio_unknown_6g:
ROM0:9F7C LDA audio_misc_0619
ROM0:9F7D BPL loc_209F88
ROM0:9F7E LDA byte_209F92,Y
ROM0:9F7F AND #$F
ROM0:9F80 BNE loc_209F8F
 
ROM0:9F88 loc_209F88:
ROM0:9F88 LDA byte_209F92,Y
ROM0:9F89 LSR A
ROM0:9F8A LSR A
ROM0:9F8B LSR A
ROM0:9F8C LSR A
 
ROM0:9F8F loc_209F8F:
ROM0:9F8F ORA #$90
ROM0:9F90 RTS
 
ROM0:9F92 byte_209F92: .BYTE 4
ROM0:9F93   .BYTE $24
ROM0:9F94   .BYTE $24
ROM0:9F95   .BYTE $34
ROM0:9F96   .BYTE $34
ROM0:9F97   .BYTE $35
ROM0:9F98   .BYTE $35
ROM0:9F99   .BYTE $35
ROM0:9F9A   .BYTE $45
ROM0:9F9B   .BYTE $45
ROM0:9F9C   .BYTE $46
ROM0:9F9D   .BYTE $46
ROM0:9F9E   .BYTE $46
ROM0:9F9F   .BYTE $46
ROM0:9FA0   .BYTE $46
ROM0:9FA1   .BYTE $46
ROM0:9FA2   .BYTE $46
ROM0:9FA3   .BYTE $46
ROM0:9FA4   .BYTE $57
ROM0:9FA5   .BYTE $57
ROM0:9FA6   .BYTE $57
ROM0:9FA7   .BYTE $57
ROM0:9FA8   .BYTE $68
ROM0:9FA9   .BYTE $68
ROM0:9FAA   .BYTE $68
ROM0:9FAB   .BYTE $68
ROM0:9FAC   .BYTE $79
ROM0:9FAD   .BYTE $79
ROM0:9FAE   .BYTE $79
ROM0:9FAF   .BYTE $68
ROM0:9FB0   .BYTE $68
ROM0:9FB1 audio_data_5: .BYTE $57
ROM0:9FB2   .BYTE $47
ROM0:9FB3   .BYTE $67
ROM0:9FB4   .BYTE $87
ROM0:9FB5   .BYTE $A8
ROM0:9FB6   .BYTE $B9
ROM0:9FB7   .BYTE $9A
ROM0:9FB8   .BYTE $8A
ROM0:9FB9   .BYTE $5A
ROM0:9FBA   .BYTE $9B
ROM0:9FBB byte_209FBB: .BYTE $8B
ROM0:9FBC   .BYTE $FB
ROM0:9FBD   .BYTE $F9
ROM0:9FBE   .BYTE $9D
ROM0:9FBF   .BYTE $6E
ROM0:9FC0 audio_data_4: .BYTE $3F
ROM0:9FC1   .BYTE $1A
ROM0:9FC2   .BYTE $1A
ROM0:9FC3   .BYTE $1C
ROM0:9FC4   .BYTE $1D
ROM0:9FC5   .BYTE $1D
ROM0:9FC6   .BYTE $1E
ROM0:9FC7   .BYTE $1E
ROM0:9FC8   .BYTE $1F
ROM0:9FC9   .BYTE $1F
ROM0:9FCA   .BYTE $1E
ROM0:9FCB   .BYTE $1A
ROM0:9FCC   .BYTE $19
ROM0:9FCD   .BYTE $16
ROM0:9FCE   .BYTE $13
ROM0:9FCF   .BYTE $11
ROM0:9FD0   .BYTE $11
ROM0:9FD1 byte_209FD1: .BYTE 3
ROM0:9FD2   .BYTE $A
ROM0:9FD3   .BYTE 1
ROM0:9FD4   .BYTE $14
ROM0:9FD5   .BYTE 5
ROM0:9FD6   .BYTE $28
ROM0:9FD7   .BYTE $3C
ROM0:9FD8   .BYTE $70
ROM0:9FD9   .BYTE 7
ROM0:9FDA   .BYTE $1B
ROM0:9FDB   .BYTE $35
ROM0:9FDC   .BYTE $14
ROM0:9FDD   .BYTE $D
ROM0:9FDE   .BYTE $28
ROM0:9FDF   .BYTE $3C
ROM0:9FE0   .BYTE $50
ROM0:9FE1   .BYTE 6
ROM0:9FE2   .BYTE $C
ROM0:9FE3   .BYTE 8
ROM0:9FE4   .BYTE $18
ROM0:9FE5   .BYTE $24
ROM0:9FE6   .BYTE $30
ROM0:9FE7   .BYTE $48
ROM0:9FE8   .BYTE $10
ROM0:9FE9   .BYTE 7
ROM0:9FEA   .BYTE $D
ROM0:9FEB   .BYTE 9
ROM0:9FEC   .BYTE $1B
ROM0:9FED   .BYTE $24
ROM0:9FEE   .BYTE $36
ROM0:9FEF   .BYTE $48
ROM0:9FF0   .BYTE $10
ROM0:9FF1   .BYTE $3C
ROM0:9FF2   .BYTE $50
ROM0:9FF3   .BYTE $A
ROM0:9FF4   .BYTE 5
ROM0:9FF5   .BYTE $14
ROM0:9FF6   .BYTE $D
ROM0:9FF7   .BYTE $28
ROM0:9FF8   .BYTE $E
ROM0:9FF9   .BYTE $FF
ROM0:9FFA   .BYTE $FF
ROM0:9FFB   .BYTE $FF
ROM0:9FFC   .BYTE $FF
ROM0:9FFD   .BYTE $FF
ROM0:9FFE   .BYTE $FF
ROM0:9FFF   .BYTE $FF
ROM0:A000 Skipped empty chunk
 
Subroutine rom0_OnReset
ROM0:BF50 rom0_OnReset:
ROM0:BF50 SEI
ROM0:BF51 CLD
ROM0:BF52 LDA #0
ROM0:BF53 STA PPUCTRL
ROM0:BF54 LDX #$FF
ROM0:BF55 TXS
 
ROM0:BF56 loop1:
ROM0:BF56 LDA PPUSTATUS
ROM0:BF57 AND #$80
ROM0:BF58 BEQ loop1
 
ROM0:BF59 loop2:
ROM0:BF59 LDA PPUSTATUS
ROM0:BF5A AND #$80
ROM0:BF5B BEQ loop2
ROM0:BF5C ORA #$FF
ROM0:BF5D STA byte_208000
ROM0:BF5E STA byte_20A000
ROM0:BF5F STA $C000
ROM0:BF60 STA $E000
ROM0:BF61 LDA #$F
ROM0:BF62 JSR rom0_set_mmc_control_register
ROM0:BF63 LDA #0
ROM0:BF64 STA byte_20A000
ROM0:BF65 LSR A
ROM0:BF66 STA byte_20A000
ROM0:BF67 LSR A
ROM0:BF68 STA byte_20A000
ROM0:BF69 LSR A
ROM0:BF6A STA byte_20A000
ROM0:BF6B LSR A
ROM0:BF6C STA byte_20A000
ROM0:BF6D LDA #7
ROM0:BF6E JSR rom0_set_prg_bank
ROM0:BF6F JMP continue_setup
 
Subroutine rom0_set_mmc_control_register
ROM0:BF98 rom0_set_mmc_control_register:
ROM0:BF98 STA byte_208000
ROM0:BF99 LSR A
ROM0:BF9A STA byte_208000
ROM0:BF9B LSR A
ROM0:BF9C STA byte_208000
ROM0:BF9D LSR A
ROM0:BF9E STA byte_208000
ROM0:BF9F LSR A
ROM0:BFA0 STA byte_208000
ROM0:BFA1 RTS
 
Subroutine rom0_set_prg_bank
ROM0:BFAC rom0_set_prg_bank:
ROM0:BFAC STA $E000
ROM0:BFAD LSR A
ROM0:BFAE STA $E000
ROM0:BFAF LSR A
ROM0:BFB0 STA $E000
ROM0:BFB1 LSR A
ROM0:BFB2 STA $E000
ROM0:BFB3 LSR A
ROM0:BFB4 STA $E000
ROM0:BFB5 RTS
 
ROM0:BFB6 Skipped empty chunk
ROM0:BFB6 .END
 
 
Segment: ROM1
ROM1:8000 text_ptr_tbl: .WORD text_data_00
ROM1:8002   .WORD text_data_01
ROM1:8004   .WORD text_data_02
ROM1:8006   .WORD text_data_03
ROM1:8008   .WORD text_data_04
ROM1:800A   .WORD text_data_05
ROM1:800C   .WORD text_data_06
ROM1:800E   .WORD text_data_07
ROM1:8010   .WORD text_data_08
ROM1:8012   .WORD text_data_09
ROM1:8014   .WORD text_data_0A
ROM1:8016   .WORD text_data_0B
ROM1:8018   .WORD text_data_0C
ROM1:801A   .WORD text_data_0D
ROM1:801C   .WORD text_data_0E
ROM1:801E   .WORD text_data_0F
ROM1:8020   .WORD text_data_10
ROM1:8022   .WORD text_data_11
ROM1:8024   .WORD text_data_12
ROM1:8026   .WORD text_data_13
ROM1:8028   .WORD text_data_14
ROM1:802A   .WORD text_data_15
ROM1:802C   .WORD text_data_16
ROM1:802E   .WORD text_data_17
ROM1:8030   .WORD text_data_18
ROM1:8032   .WORD text_data_19
ROM1:8034   .WORD text_data_1A
ROM1:8036   .WORD text_data_1B
ROM1:8038   .WORD text_data_1C
ROM1:803A   .WORD text_data_1D
ROM1:803C   .WORD text_data_1E
ROM1:803E   .WORD text_data_1F
ROM1:8040   .WORD text_data_20
ROM1:8042   .WORD text_data_21
ROM1:8044   .WORD text_data_22
ROM1:8046   .WORD text_data_23
ROM1:8048   .WORD text_data_24
ROM1:804A   .WORD text_data_25
ROM1:804C text_data_00:
ROM1:8077 text_data_01:
ROM1:80A1 text_data_02:
ROM1:80B9 text_data_03:
ROM1:80E3 text_data_04:
ROM1:8105 text_data_05:
ROM1:812D text_data_06:
ROM1:8152 text_data_07:
ROM1:8179 text_data_08:
ROM1:8197 text_data_09:
ROM1:81AE text_data_0A:
ROM1:81D2 text_data_0B:
ROM1:81F8 text_data_0C:
ROM1:822C text_data_0D:
ROM1:8241 text_data_0E:
ROM1:8258 text_data_0F:
ROM1:827D text_data_10:
ROM1:8294 text_data_11:
ROM1:82B8 text_data_12:
ROM1:82CD text_data_13:
ROM1:82F5 text_data_14:
ROM1:830D text_data_15:
ROM1:834D text_data_16:
ROM1:8370 text_data_17:
ROM1:839C text_data_18:
ROM1:83C6 text_data_19:
ROM1:83F0 text_data_1A:
ROM1:841C text_data_1B:
ROM1:843F text_data_1C:
ROM1:846D text_data_1D:
ROM1:8490 text_data_1E:
ROM1:84B8 text_data_1F:
ROM1:84E3 text_data_20:
ROM1:850E text_data_21:
ROM1:8526 text_data_22:
ROM1:8553 text_data_23:
ROM1:8568 text_data_24:
ROM1:857E text_data_25:
ROM1:85A2 byte_1185A2: .BYTE $40
ROM1:85A3   .BYTE $60
ROM1:85A4   .BYTE $42
ROM1:85A5   .BYTE $42
ROM1:85A6   .BYTE 4
ROM1:85A7   .BYTE 6
ROM1:85A8   .BYTE $48
ROM1:85A9   .BYTE $A
ROM1:85AA   .BYTE $4C
ROM1:85AB   .BYTE $E
ROM1:85AC   .BYTE $D0
ROM1:85AD   .BYTE $D2
ROM1:85AE   .BYTE $D2
ROM1:85AF   .BYTE $DC
ROM1:85B0   .BYTE $DC
ROM1:85B1   .BYTE $DE
ROM1:85B2   .BYTE $DE
ROM1:85B3   .BYTE $62
ROM1:85B4   .BYTE $62
ROM1:85B5   .BYTE $62
ROM1:85B6 byte_1185B6: .BYTE $A
ROM1:85B7   .BYTE $28
ROM1:85B8 byte_1185B8: .BYTE 0
ROM1:85B9   .BYTE 1
ROM1:85BA   .BYTE 2
ROM1:85BB   .BYTE 1
ROM1:85BC   .BYTE 2
ROM1:85BD   .BYTE 0
ROM1:85BE   .BYTE 2
ROM1:85BF   .BYTE 0
ROM1:85C0   .BYTE 1
ROM1:85C1   .BYTE 0
ROM1:85C2   .BYTE 2
ROM1:85C3   .BYTE 1
ROM1:85C4   .BYTE 2
ROM1:85C5   .BYTE 1
ROM1:85C6   .BYTE 0
ROM1:85C7   .BYTE 1
ROM1:85C8   .BYTE 0
ROM1:85C9   .BYTE 2
ROM1:85CA byte_1185CA: .BYTE 2
ROM1:85CB   .BYTE 5
ROM1:85CC   .BYTE 8
ROM1:85CD   .BYTE $B
ROM1:85CE   .BYTE $E
ROM1:85CF   .BYTE $11
 
Function chunk for adjust_walk_state
ROM1:85D0 spawn_event: ; Spawn the shopkeeper/old woman/mugger.
ROM1:85D0 LDA #$78
ROM1:85D1 LDY #$80
ROM1:85D2 JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:85D3 LDA object_type_1
ROM1:85D4 CMP #ObjectType_OldMan_Letter
ROM1:85D5 BEQ loc_1185EA
ROM1:85D6 CMP #ObjectType_OldMan_DoorRepair
ROM1:85D7 BEQ loc_1185EA
ROM1:85D8 CMP #ObjectType_RupeeSecret_Big
ROM1:85D9 BCS loc_1185EA
ROM1:85DA CMP #ObjectType_OldMan_TakeAnyRoad
ROM1:85DB BCS loc_1185F9
 
ROM1:85EA loc_1185EA:
ROM1:85EA JSR get_room_status_floor_item_picked_up
ROM1:85EB BEQ loc_1185F9
ROM1:85EC LDA #0
ROM1:85ED STA object_type_1 ; set to 0
 
ROM1:85F4 loc_1185F4:
ROM1:85F4 LDA #0
ROM1:85F5 STA walk_state_and_weapon_state
ROM1:85F6 RTS
 
ROM1:85F9 loc_1185F9:
ROM1:85F9 LDA object_type_1
ROM1:85FA SEC
ROM1:85FB SBC #$6A
ROM1:85FC TAY
ROM1:85FD LDA byte_1185A2,Y
ROM1:85FE PHA
ROM1:85FF AND #$3F
ROM1:8600 STA text_scroll_index ; The index of an old man message to display
ROM1:8601 PLA
ROM1:8602 AND #$C0
ROM1:8603 STA 3
ROM1:8604 LDA #$FD
 
ROM1:8610 loc_118610:
ROM1:8610 CLC
ROM1:8611 ADC #3
ROM1:8612 DEY
ROM1:8613 BPL loc_118610
ROM1:8614 TAY
ROM1:8615 LDX #0
 
ROM1:8619 loc_118619: ; Get store item
ROM1:8619 LDA dungeon_screen_data_4,Y
ROM1:861A STA store_item,X
ROM1:861B AND #$C0
ROM1:861C STA var_0,X
ROM1:861D LDA dungeon_screen_data_4+$3C,Y ; Get store item price
ROM1:861E STA enemy_state_4_4,X
ROM1:861F INY
ROM1:8620 INX
ROM1:8621 CPX #3
ROM1:8622 BNE loc_118619
ROM1:8623 LDA var_3
ROM1:8624 ASL A
ROM1:8625 ROL A
ROM1:8626 ROL A
ROM1:8627 ORA var_0
ROM1:8628 STA var_0
ROM1:8629 LDA var_2
ROM1:862A LSR A
ROM1:862B LSR A
ROM1:862C LSR A
ROM1:862D LSR A
ROM1:862E ORA var_0
ROM1:862F STA var_0
ROM1:8630 LDA var_1
ROM1:8631 LSR A
ROM1:8632 LSR A
ROM1:8633 ORA var_0
ROM1:8634 STA byte_413
ROM1:8635 AND #$20
ROM1:8636 BEQ loc_118697
ROM1:8637 LDA #$FF
ROM1:8638 LDY #6
 
ROM1:8653 loc_118653:
ROM1:8653 CMP prng_1
ROM1:8654 BCC loc_11865D
ROM1:8655 SEC
ROM1:8656 SBC #$2B
ROM1:8657 DEY
ROM1:8658 BNE loc_118653
 
ROM1:865D loc_11865D:
ROM1:865D LDX byte_1185CA,Y
ROM1:865E LDY #2
 
ROM1:8662 loc_118662:
ROM1:8662 LDA byte_1185B8,X
ROM1:8663 STA enemy_state_1_1,Y
ROM1:8664 DEX
ROM1:8665 DEY
ROM1:8666 BPL loc_118662
ROM1:8667 LDA $1A
ROM1:8668 AND #1
ROM1:8669 TAY
ROM1:866A LDA byte_1185B6,Y
ROM1:866B STA byte_46F
ROM1:866C LDA #$A
ROM1:866D STA byte_470
ROM1:866E LDY #$14
ROM1:866F LDA prng_2
ROM1:8670 AND #2
ROM1:8671 BEQ loc_118686
ROM1:8672 LDY #$32
 
ROM1:8686 loc_118686:
ROM1:8686 STY byte_471
ROM1:8687 LDX #2
 
ROM1:868B loc_11868B:
ROM1:868B LDY enemy_state_1_1,X
ROM1:868C LDA byte_46F,Y
ROM1:868D STA enemy_state_6_4,X
ROM1:868E DEX
ROM1:868F BPL loc_11868B
 
ROM1:8697 loc_118697:
ROM1:8697 LDA #0
ROM1:8698 STA byte_416
ROM1:8699 LDA byte_118814
ROM1:869A STA enemy_state_2_1
ROM1:869B RTS
 
Subroutine spawn_blocking_npc
; In A: NPC X ; In Y: NPC Y
ROM1:86A3 spawn_blocking_npc:
ROM1:86A3 STA object_x,X
ROM1:86A4 STY object_y,X
ROM1:86A5 LDA #0
ROM1:86A6 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM1:86A7 LDA #EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink
ROM1:86A8 STA enemy_properties,X ; Set to EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink.
ROM1:86A9 LDA #$40
ROM1:86AA STA walk_state_and_weapon_state
ROM1:86AB LDA #ObjectType_Flame_Unkillable ; Spawn left and right fire around NPC
ROM1:86AC STA object_type_2
ROM1:86AD STA object_type_3
ROM1:86AE LDA #$48 ; X position of left fire
ROM1:86AF STA object_x_1,X ; Store X position of left fire
ROM1:86B0 LDA #$A8 ; X position of right fire
ROM1:86B1 STA object_x_2,X ; Store X position of right fire
ROM1:86B2 STY object_y_1,X ; Store Y position of left fire
ROM1:86B3 STY object_y_2,X ; Store Y position of right fire
ROM1:86B4 RTS
 
ROM1:86CA store_ppu_command_buffer: .BYTE $22
ROM1:86CB   .BYTE $C8
ROM1:86CC   .BYTE $D
ROM1:86CD   .BYTE $21
ROM1:86CE   .BYTE $24
ROM1:86CF   .BYTE $24
ROM1:86D0   .BYTE $24
ROM1:86D1   .BYTE $24
ROM1:86D2   .BYTE $24
ROM1:86D3   .BYTE $24
ROM1:86D4   .BYTE $24
ROM1:86D5   .BYTE $24
ROM1:86D6   .BYTE $24
ROM1:86D7   .BYTE $24
ROM1:86D8   .BYTE $24
ROM1:86D9   .BYTE $24
ROM1:86DA   .BYTE $FF
 
Function chunk for adjust_walk_state
ROM1:86DB do_update_monster_over_0x6A: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:86DB LDA global_room_state
ROM1:86DC CMP #4
ROM1:86DD BNE skip_running_event_state ; Never run the event update in state 4. We may still run it
  ; if we fall through below.
ROM1:86DE LDA frame_counter
ROM1:86DF AND #1
ROM1:86E0 BNE run_event_state_update ; Only run the event update on odd frames.
 
ROM1:86E1 skip_running_event_state:
ROM1:86E1 JSR sub_118736
ROM1:86E2 LDA object_type_1 ; Check if ObjectType_OldWomanBeforeLetter
ROM1:86E3 CMP #ObjectType_OldWoman_PotionShop
ROM1:86E4 BNE unlock_event
ROM1:86E5 LDA have_letter ; This is the old woman. Check if the letter is equipped.
ROM1:86E6 CMP #2
ROM1:86E7 BEQ unlock_event ; Branch if we've already shown the old woman the letter.
ROM1:86E8 LDY current_item
ROM1:86E9 CPY #InventoryItem_Letter
ROM1:86EA BNE letter_not_selected ; Branch if the letter isn't selected.
ROM1:86EB LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM1:86EC AND #ControllerBits_B
ROM1:86ED BNE use_letter ; Branch if B is pressed (using the letter).
 
ROM1:86EE letter_not_selected:
ROM1:86EE LDA walk_state_and_weapon_state
ROM1:86EF CMP #$40
ROM1:86F0 BNE ret
ROM1:86F1 JSR loc_1185F4
 
ROM1:86F2 ret:
ROM1:86F2 RTS
 
ROM1:86F3 use_letter: ; The player used the letter in the old woman room. Play
ROM1:86F3 LDA #Sound1_Secret ; the secret sound.
ROM1:86F4 STA play_sound_1 ; Play Sound1_Secret
ROM1:86F5 INC have_letter ; Increase have_letter from 1 to 2 to remember that we've
  ; unlocked the potion shop.
ROM1:86F6 LDA #InventoryItem_Potion
ROM1:86F7 STA current_item ; Switch from the letter to the potion inventory slot.
 
ROM1:86F8 unlock_event:
ROM1:86F8 JSR setup_store_item_sprites
 
ROM1:86F9 run_event_state_update: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:86F9 LDA global_room_state
ROM1:86FA JSR call_jump_table
 
ROM1:86FB   .WORD store_state_0
ROM1:86FD   .WORD store_state_text_scroll
ROM1:86FF   .WORD store_state_2_can_pick_up ; StoreState_CanPickUp
ROM1:8701   .WORD store_state_disappearing_after_purchase ; Disappearing (bought an item, etc)
ROM1:8703   .WORD store_state_4
ROM1:8705   .WORD store_state_5_picked_up_item ; StoreState_PickedUpItem
ROM1:8707   .WORD store_state_disappearing_after_purchase
ROM1:8709   .WORD store_state_text_scroll
ROM1:870B   .WORD locret_1189F6
 
Subroutine sub_118736
ROM1:8736 sub_118736:
ROM1:8736 JSR set_var_0_to_object_position ; Sets var_0 and var_1 to the old man's X/Y position, and var_15 to 0
ROM1:8737 LDY object_type_1 ; check if 0x7B
ROM1:8738 CPY #ObjectType_RupeeSecret_Big
ROM1:8739 BCS loc_118743 ; >= ObjectType_Unknown_7B
ROM1:873A JMP update_object_sprite_vertical
 
ROM1:8743 loc_118743:
ROM1:8743 JMP update_object_sprite_horizontal
 
ROM1:8746 store_item_x_positions: .BYTE $58 ; Left item X position
ROM1:8747   .BYTE $78 ; Center item X position
ROM1:8748   .BYTE $98 ; Right item X position
 
Subroutine setup_store_item_sprites
ROM1:8749 setup_store_item_sprites:
ROM1:8749 LDA byte_413 ; Skip setting up store item sprites if StoreFlags_ShowStoreItems isn't set.
ROM1:874A AND #StoreFlags_ShowStoreItems
ROM1:874B BEQ setup_rupee_icon
ROM1:874C LDA #2
ROM1:874D STA byte_421 ; Set to 2.
 
ROM1:874E loop: ; Set up items in the shop.
ROM1:874E LDX byte_421
ROM1:874F LDA store_item_x_positions,X
ROM1:8750 STA floor_item_x ; Store item X position
ROM1:8751 LDA #$98
ROM1:8752 STA floor_item_y ; Store item Y position
ROM1:8753 LDA store_item,X ; If 0x3F, there's no item in this store slot.
ROM1:8754 AND #$3F
ROM1:8755 CMP #$3F
ROM1:8756 BEQ skip
ROM1:8757 LDX #$13
ROM1:8758 JSR setup_sprite
 
ROM1:8759 skip:
ROM1:8759 DEC byte_421
ROM1:875A BPL loop
 
ROM1:875B setup_rupee_icon: ; Skip setting up rupee icon if StoreFlags_ShowRupeeIcon isn't set.
ROM1:875B LDA byte_413
ROM1:875C AND #StoreFlags_ShowRupeeIcon
ROM1:875D BEQ ret
ROM1:875E LDA #$30 ; Set up the rupee icon next to items.
ROM1:875F STA floor_item_x ; Shop rupee icon X
ROM1:8760 LDA #$AB
ROM1:8761 STA floor_item_y ; Shop rupee icon Y
ROM1:8762 LDA #$18
ROM1:8763 LDX #$13
ROM1:8764 JSR setup_sprite
 
ROM1:8765 ret:
ROM1:8765 RTS
 
Subroutine store_state_0
ROM1:878B store_state_0:
ROM1:878B LDA byte_413 ; Check StoreFlags_ShowRupeeIcon
ROM1:878C AND #StoreFlags_ShowRupeeIcon
ROM1:878D BEQ increase_store_state
 
ROM1:8792 loc_118792:
ROM1:8792 JSR copy_store_ppu_command_buffer
ROM1:8793 LDA #$21
 
ROM1:8797 loc_118797:
ROM1:8797 STA ppu_command_buffer_03
ROM1:8798 LDX #0
ROM1:8799 STX enemy_state_4_2
ROM1:879A STX enemy_state_4_3
 
ROM1:87A2 loc_1187A2:
ROM1:87A2 LDA enemy_state_4_4,X
ROM1:87A3 BNE loc_1187B2
ROM1:87A4 LDX #$24
ROM1:87A5 STX var_1
ROM1:87A6 STX var_2
ROM1:87A7 STX var_3
ROM1:87A8 JMP loc_1187BF
 
ROM1:87B2 loc_1187B2: ; Convert A to digits in var_1, var_2 and var_3. Leading
ROM1:87B2 JSR convert_number_to_string ; zeroes are set to 0x24. A = var_2 (tens digit), Y = var_1 (hundreds digit).
ROM1:87B3 LDX #$24
ROM1:87B4 LDA byte_413 ; Check StoreFlags_Unknown_0x80
ROM1:87B5 ASL A
ROM1:87B6 BCC loc_1187BF
ROM1:87B7 LDX #$62
 
ROM1:87BF loc_1187BF:
ROM1:87BF STX var_4
ROM1:87C0 LDY enemy_state_4_3
ROM1:87C1 LDA var_2
ROM1:87C2 JSR sub_1187F7
ROM1:87C3 STA ppu_command_buffer_06,Y
ROM1:87C4 LDA 1
ROM1:87C5 JSR sub_1187F7
ROM1:87C6 STA ppu_command_buffer_05,Y
ROM1:87C7 LDA var_3
ROM1:87C8 STA ppu_command_buffer_07,Y
ROM1:87C9 LDA enemy_state_4_3
ROM1:87CA CLC
ROM1:87CB ADC #4
ROM1:87CC STA enemy_state_4_3
ROM1:87CD INC enemy_state_4_2
ROM1:87CE LDX enemy_state_4_2
ROM1:87CF CPX #3
ROM1:87D0 BNE loc_1187A2
ROM1:87D1 LDA #$A
ROM1:87D2 STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:87D3 BNE increase_store_state
 
ROM1:87F2 store_ppu_command_index_and_increase_store_state:
ROM1:87F2 STA current_ppu_command_index
 
ROM1:87F3 increase_store_state: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:87F3 INC global_room_state
ROM1:87F4 RTS
 
Subroutine sub_1187F7
ROM1:87F7 sub_1187F7:
ROM1:87F7 CMP #$24
ROM1:87F8 BNE locret_118800
ROM1:87F9 TAX
ROM1:87FA LDA var_4
ROM1:87FB STX var_4
 
ROM1:8800 locret_118800:
ROM1:8800 RTS
 
Subroutine copy_store_ppu_command_buffer
ROM1:8801 copy_store_ppu_command_buffer:
ROM1:8801 LDY #$10
 
ROM1:8802 loop:
ROM1:8802 LDA store_ppu_command_buffer,Y
ROM1:8803 STA ppu_command_buffer,Y
ROM1:8804 DEY
ROM1:8805 BPL loop
ROM1:8806 RTS
 
ROM1:880D old_man_ppu_command: .BYTE $21
ROM1:880E   .BYTE $A4
ROM1:880F   .BYTE 1
ROM1:8810   .BYTE $24
ROM1:8811   .BYTE $FF
ROM1:8812 byte_118812: .BYTE $C4
ROM1:8813   .BYTE $E4
ROM1:8814 byte_118814: .BYTE $A4
 
Subroutine store_state_text_scroll
ROM1:8815 store_state_text_scroll:
ROM1:8815 JSR update_link_sprite_return_in_bank_1 ; Call reset_animation_frame_update_link_sprite_and_check_ladder,
  ; then set bank 1 before returning.
ROM1:8816 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8817 BNE locret_118879
ROM1:8818 LDA #6
ROM1:8819 STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:881A LDY #4
 
ROM1:881B loop:
ROM1:881B LDA old_man_ppu_command,Y
ROM1:881C STA ppu_command_buffer,Y
ROM1:881D DEY
ROM1:881E BPL loop
 
ROM1:882B loc_11882B:
ROM1:882B LDA enemy_state_2_1
ROM1:882C STA ppu_command_buffer_01
ROM1:882D INC enemy_state_2_1
ROM1:882E LDY text_scroll_index ; The index of an old man message to display
ROM1:882F LDA text_ptr_tbl,Y
ROM1:8830 STA 0
ROM1:8831 INY
ROM1:8832 LDA text_ptr_tbl,Y
ROM1:8833 STA 1
ROM1:8834 LDY byte_416
ROM1:8835 INC byte_416
ROM1:8836 LDA (0),Y
ROM1:8837 AND #$3F
ROM1:8838 CMP #$25
ROM1:8839 BEQ loc_11882B
ROM1:883A STA ppu_command_buffer_03
ROM1:883B LDA #Sound3_GainRupee
ROM1:883C STA play_sound_3 ; Play Sound3_GainRupee
ROM1:883D LDA (var_0),Y
ROM1:883E AND #$C0
ROM1:883F BEQ locret_118879
ROM1:8840 LDY #2
ROM1:8841 CMP #$C0
ROM1:8842 BEQ loc_11886A
ROM1:8843 DEY
ROM1:8844 CMP #$40
ROM1:8845 BEQ loc_11886A
ROM1:8846 DEY
 
ROM1:886A loc_11886A:
ROM1:886A LDA byte_118812,Y
ROM1:886B STA enemy_state_2_1
ROM1:886C CPY #2
ROM1:886D BNE locret_118879
ROM1:886E INC global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:886F JSR loc_1185F4
 
ROM1:8879 locret_118879:
ROM1:8879 RTS
 
Subroutine store_state_2_can_pick_up
ROM1:887A store_state_2_can_pick_up:
ROM1:887A LDA byte_413 ; Check if branch if StoreFlags_CanPickUpFloorItems was set
ROM1:887B LSR A
ROM1:887C BCS check_if_standing_on_store_item ; Branch if StoreFlags_CanPickUpFloorItems
ROM1:887D LDA #StoreState_Finished
ROM1:887E STA global_room_state ; Switch to StoreState_Finished.. We can't pick up items here (this is probably door repair).
ROM1:887F LDA object_type_1 ; Check if ObjectType_DoorRepair
ROM1:8880 CMP #ObjectType_OldMan_DoorRepair
ROM1:8881 BNE locret_118897
ROM1:8882 LDA pending_rupees_sub
ROM1:8883 CLC
ROM1:8884 ADC #20
ROM1:8885 STA pending_rupees_sub ; $20 for door repair
ROM1:8886 JSR mark_room_item_collected
 
ROM1:8897 locret_118897:
ROM1:8897 RTS
 
ROM1:8898 check_if_standing_on_store_item: ; If we're already subtracting rupees for something else,
ROM1:8898 LDA pending_rupees_sub ; don't allow making store purchases.
ROM1:8899 BNE locret_118897
ROM1:889A LDX #2 ; Check all three store item positions.
 
ROM1:889B loop: ; Get store item type to check if there's anything in the spot Link is standing on.
ROM1:889B LDA store_item,X
ROM1:889C AND #$3F
ROM1:889D CMP #$3F
ROM1:889E BEQ skip ; Skip if there's no item in this slot.
ROM1:889F LDA object_x ; Check Link's position against this store item's X position.
ROM1:88A0 CMP store_item_x_positions,X
ROM1:88A1 BNE skip
ROM1:88A2 LDA object_y ; Check Link's position against this store item's Y position.
ROM1:88A3 SEC
ROM1:88A4 SBC #$98
ROM1:88A5 JSR absolute_value ; A = abs(A)
ROM1:88A6 CMP #6
ROM1:88A7 BCC standing_on_store_item ; Must be within 6 pixels on Y.
 
ROM1:88A8 skip:
ROM1:88A8 DEX
ROM1:88A9 BPL loop
ROM1:88AA RTS
 
ROM1:88AB standing_on_store_item: ; Store the index of the item that was picked up (0, 1 or 2).
ROM1:88AB STX enemy_state_5_1
ROM1:88AC LDA byte_413
ROM1:88AD AND #StoreFlags_TakesRupeesNoItem|StoreFlags_NoItem
ROM1:88AE BEQ if_not_no_item
ROM1:88AF AND #StoreFlags_TakesRupeesNoItem ; Check if this store takes rupees (for the no item case)
ROM1:88B0 BEQ if_not_takes_rupees_for_no_item
ROM1:88B1 LDA num_rupees ; Get rupees to check store purchase
ROM1:88B2 CMP enemy_state_4_4,X ; Check if the player has enough rupees for this item
ROM1:88B3 BCC locret_118932 ; Stop if not enough
ROM1:88B4 LDA enemy_state_4_4,X ; Load the number of rupees to subtract
ROM1:88B5 JSR add_value_to_sub_rupees ; Subtract rupees after store purchase
 
ROM1:88B6 if_not_takes_rupees_for_no_item:
ROM1:88B6 LDA #StoreState_PickedUpItem
ROM1:88B7 STA global_room_state ; Set to StoreState_PickedUpItem.
ROM1:88B8 RTS
 
ROM1:88B9 if_not_no_item: ; Check StoreFlags_RequiresRupeesForItem
ROM1:88B9 LDA byte_413
ROM1:88BA AND #StoreFlags_RequiresRupeesForItem
ROM1:88BB BEQ check_if_requires_hearts
ROM1:88BC LDA num_rupees ; Get rupees to check store purchase
ROM1:88BD CMP enemy_state_4_4,X ; Check if the player has enough rupees for this item
ROM1:88BE BCC locret_118932 ; Stop if not enough
ROM1:88BF LDA enemy_state_4_4,X ; Load the number of rupees to subtract
ROM1:88C0 JSR add_value_to_sub_rupees ; Subtract rupees after store purchase
 
ROM1:88C1 check_if_requires_hearts: ; Check StoreFlags_RequiresHearts
ROM1:88C1 LDA byte_413
ROM1:88C2 AND #StoreFlags_RequiresHearts
ROM1:88C3 BEQ pick_up_store_item
ROM1:88C4 LDY #$40 ; >= 5 hearts
ROM1:88C5 LDA object_type_1
ROM1:88C6 CMP #ObjectType_OldMan_SilverSword
ROM1:88C7 BEQ check_hearts_for_sword_upgrade
ROM1:88C8 LDY #$B0 ; >= 12 hearts
 
ROM1:88C9 check_hearts_for_sword_upgrade: ; Get hearts to check if we have enough for this sword upgrade.
ROM1:88C9 CPY hearts
ROM1:88CA BEQ pick_up_store_item ; Pick up the item if the heart requirement < hearts.
ROM1:88CB BCC pick_up_store_item
ROM1:88CC RTS
 
ROM1:88CD pick_up_store_item: ; We've confirmed requirements for this item, and queued any
ROM1:88CD JSR mark_room_item_collected ; rupee cost. Pick up the item.
ROM1:88CE LDA store_item,X ; Get the InventoryItem that we're picking up.
ROM1:88CF AND #$3F
ROM1:88D0 PHA ; Push the InventoryItem that we're picking up
ROM1:88D1 LDA #$FF
ROM1:88D2 STA store_item,X ; Clear the item, since we're taking it.
ROM1:88D3 PLA ; Pop the InventoryItem that we're picking up
ROM1:88D4 JSR pick_up_item ; Pick up an item. A is the FloorItem to pick up.
ROM1:88D5 LDA #$1E
ROM1:88D6 JSR store_ppu_command_index_and_increase_store_state
ROM1:88D7 LDA #$40
ROM1:88D8 STA npc_action_timer_1 ; Set 0x40
 
ROM1:892A clear_store_flag_show_rupee_icon: ; Load to clear StoreFlags_ShowRupeeIcon
ROM1:892A LDA byte_413
ROM1:892B AND #$F7 ; Clear StoreFlags_ShowRupeeIcon
ROM1:892C STA byte_413 ; Clear StoreFlags_ShowRupeeIcon
 
ROM1:8932 locret_118932:
ROM1:8932 RTS
 
Subroutine store_state_4
ROM1:8933 store_state_4:
ROM1:8933 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8934 BNE locret_11893A
ROM1:8935 STA object_type_1
 
ROM1:893A locret_11893A:
ROM1:893A RTS
 
ROM1:893B store_message_indices: .BYTE $14 ; Indices for ObjectType_OldWoman_HintShop
ROM1:893C   .BYTE $14
ROM1:893D   .BYTE $16
ROM1:893E   .BYTE $14 ; Indices for stores other than ObjectType_OldWoman_HintShop
ROM1:893F   .BYTE $18
ROM1:8940   .BYTE $1A
 
Subroutine store_state_5_picked_up_item
ROM1:8941 store_state_5_picked_up_item:
ROM1:8941 LDA byte_413 ; Check StoreFlags_TakesRupeesNoItem
ROM1:8942 AND #StoreFlags_TakesRupeesNoItem
ROM1:8943 BEQ not_TakesRupeesNoItem ; Branch if StoreFlags_TakesRupeesNoItem not set
ROM1:8944 LDA #0 ; For ObjectType_OldWoman_HintShop, use indices starting at 0
ROM1:8945 LDY object_type_1 ; Hints?
ROM1:8946 CPY #ObjectType_OldWoman_HintShop1
ROM1:8947 BEQ show_store_message
ROM1:8948 LDA #3 ; For other types, use indices starting at 3.
 
ROM1:8949 show_store_message:
ROM1:8949 CLC
ROM1:894A ADC enemy_state_5_1 ; The index of the item that was picked up (0, 1 or 2).
ROM1:894B TAY
ROM1:894C LDA store_message_indices,Y ; Load the message number to display
ROM1:894D STA text_scroll_index ; The index of an old man message to display
ROM1:894E LDA byte_118814
ROM1:894F STA enemy_state_2_1
ROM1:8950 LDA #0
ROM1:8951 STA byte_416 ; Set to 0
ROM1:8952 JSR clear_store_flag_show_rupee_icon
ROM1:8953 LDA #$1E ; New current_ppu_command_index.
ROM1:8954 JMP store_ppu_command_index_and_increase_store_state
 
ROM1:8955 not_TakesRupeesNoItem: ; check if >= ObjectType_RupeeSecret
ROM1:8955 LDA object_type_1
ROM1:8956 CMP #ObjectType_RupeeSecret_Big
ROM1:8957 BCC object_type_money_making_game
ROM1:8958 JSR copy_store_ppu_command_buffer ; ObjectType_RupeeSecret
ROM1:8959 LDA #36
ROM1:895A JSR loc_118797
ROM1:895B LDA #Sound3_Pickup
ROM1:895C STA play_sound_3 ; Play Sound3_Pickup for rupee secret pickup
ROM1:895D JSR mark_room_item_collected
ROM1:895E LDA #StoreState_Finished
ROM1:895F STA global_room_state ; Set to StoreState_Finished after picking up rupee secret
ROM1:8960 LDA enemy_state_4_5 ; Load the number of rupees to add for this rupee secret
ROM1:8961 JMP add_value_to_add_rupees
 
ROM1:8962 object_type_money_making_game:
ROM1:8962 LDA num_rupees
ROM1:8963 CMP #10
ROM1:8964 BCC locret_11893A ; Need at least 10 rupees
ROM1:8965 LDA #Sound3_Pickup
ROM1:8966 STA play_sound_3 ; Play Sound3_Pickup
ROM1:8967 LDY #2
 
ROM1:8968 loop: ; Copy the money making game prize values.
ROM1:8968 LDA enemy_state_6_4,Y
ROM1:8969 STA enemy_state_4_4,Y
ROM1:896A DEY
ROM1:896B BPL loop
ROM1:896C JSR loc_118792
ROM1:896D LDA #8
ROM1:896E STA global_room_state ; Set to 8
ROM1:896F LDY #1 ; ppu_command_buffer_04 index
ROM1:8970 LDA enemy_state_6_4
ROM1:8971 JSR load_money_making_game_sign ; Load the tile for the money making game sign (+ or -) into ppu_command_buffer_04[Y]. In A is the prize value.
ROM1:8972 LDY #5 ; ppu_command_buffer_04 index
ROM1:8973 LDA enemy_state_6_5
ROM1:8974 JSR load_money_making_game_sign ; Load the tile for the money making game sign (+ or -) into ppu_command_buffer_04[Y]. In A is the prize value.
ROM1:8975 LDY #9 ; ppu_command_buffer_04 index
ROM1:8976 LDA enemy_state_6_6
ROM1:8977 JSR load_money_making_game_sign ; Load the tile for the money making game sign (+ or -) into ppu_command_buffer_04[Y]. In A is the prize value.
ROM1:8978 LDX enemy_state_5_1
ROM1:8979 LDA enemy_state_6_4,X
ROM1:897A CMP #20
ROM1:897B BEQ add_value_to_add_rupees ; $20 rupees is add
ROM1:897C CMP #50
ROM1:897D BNE add_value_to_sub_rupees ; $50 rupees is add, other values are subtract
 
ROM1:897E add_value_to_add_rupees:
ROM1:897E CLC
ROM1:897F ADC pending_rupees_add
ROM1:8980 STA pending_rupees_add
ROM1:8981 RTS
 
ROM1:89DE add_value_to_sub_rupees:
ROM1:89DE CLC
ROM1:89DF ADC pending_rupees_sub
ROM1:89E0 STA pending_rupees_sub
ROM1:89E1 RTS
 
Subroutine load_money_making_game_sign
; Load the tile for the money making game sign (+ or -) into ppu_command_buffer_04[Y]. In A is the prize value.
ROM1:89E6 load_money_making_game_sign:
ROM1:89E6 LDX #$64
ROM1:89E7 CMP #20 ; If A == 0x20 or 50, load 0x64 (+) into ppu_command_buffer_04[Y]. Otherwise, load 0x62 (-).
ROM1:89E8 BEQ minus
ROM1:89E9 CMP #50
ROM1:89EA BEQ minus
ROM1:89EB LDX #$62
 
ROM1:89EC minus:
ROM1:89EC TXA
ROM1:89ED STA ppu_command_buffer_04,Y
 
ROM1:89F6 locret_1189F6:
ROM1:89F6 RTS
 
Subroutine store_state_disappearing_after_purchase
ROM1:89F7 store_state_disappearing_after_purchase:
ROM1:89F7 LDA #$2A
ROM1:89F8 JMP store_ppu_command_index_and_increase_store_state
 
Function chunk for spawn_old_man
ROM1:89FC spawn_old_man_main:
ROM1:89FC LDA byte_118814
ROM1:89FD STA enemy_state_2_1
ROM1:89FE LDA dungeon_idx
ROM1:89FF JSR call_jump_table
 
ROM1:8A00   .WORD locret_118CAD ; Old man messages per dungeon
ROM1:8A02   .WORD old_man_message_1
ROM1:8A04   .WORD old_man_message_1
ROM1:8A06   .WORD old_man_message_2
ROM1:8A08   .WORD old_man_message_2
ROM1:8A0A   .WORD old_man_message_1
ROM1:8A0C   .WORD old_man_message_2
ROM1:8A0E   .WORD old_man_message_1
ROM1:8A10   .WORD old_man_message_2
ROM1:8A12   .WORD old_man_message_3_death_mountain
 
ROM1:8A1B old_man_message_1_text_indices: .BYTE $28
ROM1:8A1C   .BYTE $26
ROM1:8A1D   .BYTE $2E
ROM1:8A1E   .BYTE $30
ROM1:8A1F   .BYTE $32
ROM1:8A20   .BYTE $3E
ROM1:8A21   .BYTE $3E
ROM1:8A22   .BYTE $34
 
Subroutine old_man_message_1
ROM1:8A23 old_man_message_1:
ROM1:8A23 LDA #$78 ; X/Y position of the NPC
ROM1:8A24 LDY #$80
ROM1:8A25 JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:8A26 LDA object_type,X ; check if ObjectType_Unknown_4B
ROM1:8A27 SEC
ROM1:8A28 SBC #ObjectType_OldMan_Dungeon_Hint_0 ; Get the index relative to the first old man ID
ROM1:8A29 TAY
ROM1:8A2A LDA old_man_message_1_text_indices,Y
ROM1:8A2B STA text_scroll_index ; The index of an old man message to display
ROM1:8A2C LDA object_type_1 ; check if ObjectType_OldManItem_1
ROM1:8A2D CMP #ObjectType_OldMan_BombUpgrade ; I BET YOU'D LIKE TO HAVE MORE BOMBS.
ROM1:8A2E BNE loc_118A5E
ROM1:8A2F BEQ loc_118A52
 
ROM1:8A40 spawn_old_man_mugger_main:
ROM1:8A40 LDA #$78
ROM1:8A41 LDY #$80
ROM1:8A42 JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:8A43 LDA #$36 ; "Money or your life" message index
ROM1:8A44 STA text_scroll_index ; The index of an old man message to display
ROM1:8A45 LDA byte_118814
ROM1:8A46 STA enemy_state_2_1
 
ROM1:8A52 loc_118A52:
ROM1:8A52 JSR get_room_status_floor_item_picked_up
ROM1:8A53 BEQ loc_118A5E
ROM1:8A54 LDA #0
ROM1:8A55 STA walk_state_and_weapon_state
ROM1:8A56 JMP delete_enemy ; X = object slot
 
ROM1:8A5E loc_118A5E:
ROM1:8A5E JMP play_fairy_sound
 
ROM1:8A61 old_man_message_2_text_indices: .BYTE $2A
ROM1:8A62   .BYTE $38
ROM1:8A63   .BYTE $3A
ROM1:8A64   .BYTE $2C
ROM1:8A65   .BYTE $40
ROM1:8A66   .BYTE $42
ROM1:8A67   .BYTE $42
ROM1:8A68   .BYTE $3C
 
Subroutine old_man_message_2
ROM1:8A69 old_man_message_2:
ROM1:8A69 LDA #$78 ; X/Y position of the NPC
ROM1:8A6A LDY #$80
ROM1:8A6B JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:8A6C LDA object_type,X
ROM1:8A6D SEC
ROM1:8A6E SBC #ObjectType_OldMan_Dungeon_Hint_0 ; Get the index relative to the first old man ID
ROM1:8A6F TAY
ROM1:8A70 LDA old_man_message_2_text_indices,Y
ROM1:8A71 STA text_scroll_index ; The index of an old man message to display
ROM1:8A72 JMP play_fairy_sound
 
ROM1:8A80 old_man_message_3_text_indices: .BYTE $44
ROM1:8A81   .BYTE $46
ROM1:8A82   .BYTE $48
ROM1:8A83   .BYTE $4A
 
Subroutine old_man_message_3_death_mountain
ROM1:8A84 old_man_message_3_death_mountain:
ROM1:8A84 LDA #$78 ; X/Y position of the NPC
ROM1:8A85 LDY #$80
ROM1:8A86 JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:8A87 JSR play_fairy_sound
ROM1:8A88 LDA object_type,X
ROM1:8A89 PHA
ROM1:8A8A SEC
ROM1:8A8B SBC #ObjectType_OldMan_Dungeon_Hint_0 ; Get the index relative to the first old man ID
ROM1:8A8C TAY
ROM1:8A8D LDA old_man_message_3_text_indices,Y
ROM1:8A8E STA text_scroll_index ; The index of an old man message to display
ROM1:8A8F PLA ; Restore the object type to A
ROM1:8A90 CMP #ObjectType_OldMan_Dungeon_Hint_0 ; Check if this is the first old man room, which is locked
  ; if the player doesn't have all triforce pieces.
ROM1:8A91 BNE not_triforce_gate_room
ROM1:8A92 LDA triforce_pieces_collected ; Check if all triforce pieces collected
ROM1:8A93 CMP #$FF
ROM1:8A94 BNE not_triforce_gate_room
ROM1:8A95 LDA #1 ; All triforce pieces are collected
ROM1:8A96 STA open_doors_in_room ; Set to 1
ROM1:8A97 LSR A ; A = 0
ROM1:8A98 STA walk_state_and_weapon_state ; Set to 0 after unlocking triforce door
ROM1:8A99 JSR delete_enemy ; Delete the old man. This will unblock the top half of the room.
 
ROM1:8A9A not_triforce_gate_room:
ROM1:8A9A RTS
 
Function chunk for spawn_hungry_goriya
ROM1:8AB4 spawn_hungry_goriya_main: ; X/Y position of the NPC
ROM1:8AB4 LDA #$78
ROM1:8AB5 LDY #$80
ROM1:8AB6 JSR spawn_blocking_npc ; In A: NPC X
  ; In Y: NPC Y
ROM1:8AB7 LDA #$24 ; "Grumble grumble" text index
ROM1:8AB8 STA text_scroll_index ; The index of an old man message to display
ROM1:8AB9 LDA byte_118814
ROM1:8ABA STA enemy_state_2_1
ROM1:8ABB JSR get_room_status_floor_item_picked_up
ROM1:8ABC BEQ play_fairy_sound
ROM1:8ABD LDA #0
ROM1:8ABE STA walk_state_and_weapon_state
ROM1:8ABF STA object_type_1 ; set to 0
ROM1:8AC0 RTS
 
Subroutine play_fairy_sound
ROM1:8AD3 play_fairy_sound:
ROM1:8AD3 LDA #Sound1_Fairy
ROM1:8AD4 STA play_sound_1 ; Play Sound1_Fairy
ROM1:8AD5 RTS
 
Subroutine update_monster_old_man_main
ROM1:8AD9 update_monster_old_man_main:
 
ROM1:8AD9 LDA dungeon_idx
ROM1:8ADA CMP #3
ROM1:8ADB BCC loc_118AE7
ROM1:8ADC CMP #5
ROM1:8ADD BEQ loc_118AE7
ROM1:8ADE CMP #7
ROM1:8ADF BNE loc_118AEA
 
ROM1:8AE7 loc_118AE7: ; dungeon 1, 2, 3, 5 or 7
ROM1:8AE7 JMP loc_118B11
 
ROM1:8AEA loc_118AEA:
ROM1:8AEA JSR check_old_man_hit_and_update_sprite
ROM1:8AEB LDA global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8AEC JSR call_jump_table
 
ROM1:8AED   .WORD update_monster_old_man_main_0
ROM1:8AEF   .WORD store_state_text_scroll
ROM1:8AF1   .WORD locret_118AFF
 
Subroutine update_monster_old_man_main_0
ROM1:8AF8 update_monster_old_man_main_0:
ROM1:8AF8 LDA #0
ROM1:8AF9 STA byte_416 ; Set to 0.
ROM1:8AFA INC global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
 
ROM1:8AFF locret_118AFF:
ROM1:8AFF RTS
 
Subroutine check_if_old_man_hit
ROM1:8B00 check_if_old_man_hit:
ROM1:8B00 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM1:8B01 LDA enemy_spawn_state_1
ROM1:8B02 BEQ ret
ROM1:8B03 STA dungeon_shoots_fireballs ; Set to 1 if Link attacked the old man to make him start
  ; shooting fireballs.
ROM1:8B04 LDA #0
ROM1:8B05 STA enemy_spawn_state_1 ; Set to 0.
 
ROM1:8B06 ret:
ROM1:8B06 RTS
 
Function chunk for update_monster_old_man_main
ROM1:8B11 loc_118B11: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8B11 LDA global_room_state
ROM1:8B12 CMP #4
ROM1:8B13 BNE loc_118B1D
ROM1:8B14 LDA frame_counter
ROM1:8B15 AND #1
ROM1:8B16 BNE run_old_man_state
 
ROM1:8B1D loc_118B1D:
ROM1:8B1D JSR check_old_man_hit_and_update_sprite
ROM1:8B1E LDA object_type_1 ; check if ObjectType_OldManItem_1
ROM1:8B1F CMP #ObjectType_OldMan_BombUpgrade ; I BET YOU'D LIKE TO HAVE MORE BOMBS.
ROM1:8B20 BNE run_old_man_state
ROM1:8B21 LDA #$78 ; Set up bomb upgrade sprite
ROM1:8B22 STA floor_item_x
ROM1:8B23 LDA #$98
ROM1:8B24 STA floor_item_y
ROM1:8B25 LDA #$18
ROM1:8B26 LDX #$13
ROM1:8B27 JSR setup_sprite
 
ROM1:8B28 run_old_man_state: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8B28 LDA global_room_state
ROM1:8B29 JSR call_jump_table
 
ROM1:8B2A   .WORD update_monster_old_man_0_setup
ROM1:8B2C   .WORD store_state_text_scroll
ROM1:8B2E   .WORD bomb_upgrade_check_link_position ; Check if Link is standing on the bomb upgrade
ROM1:8B30   .WORD store_state_disappearing_after_purchase
ROM1:8B32   .WORD update_monster_old_man_4
 
Subroutine update_monster_old_man_0_setup
ROM1:8B45 update_monster_old_man_0_setup:
ROM1:8B45 LDA object_type_1 ; Check if ObjectType_OldMan_BombUpgrade
ROM1:8B46 CMP #ObjectType_OldMan_BombUpgrade ; I BET YOU'D LIKE TO HAVE MORE BOMBS.
ROM1:8B47 BNE not_bomb_upgrade
ROM1:8B48 LDA #PPUCommandIndices_BombUpgradePrice
ROM1:8B49 STA current_ppu_command_index ; Set to PPUCommandIndices_BombUpgradePrice.
 
ROM1:8B4A not_bomb_upgrade:
ROM1:8B4A LDA #$A
ROM1:8B4B STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8B4C INC global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8B4D RTS
 
Subroutine bomb_upgrade_check_link_position
ROM1:8B57 bomb_upgrade_check_link_position:
ROM1:8B57 LDA object_type_1 ; check if ObjectType_OldManItem_1
ROM1:8B58 CMP #ObjectType_OldMan_BombUpgrade ; I BET YOU'D LIKE TO HAVE MORE BOMBS.
ROM1:8B59 BNE locret_118B70 ; Skip if not a bomb upgrade
ROM1:8B5A LDA object_x ; Check if Link is standing on the bomb upgrade sprite
ROM1:8B5B CMP #$78
ROM1:8B5C BNE locret_118B70
ROM1:8B5D LDA object_y
ROM1:8B5E SEC
ROM1:8B5F SBC #$98
ROM1:8B60 JSR absolute_value ; A = abs(A)
ROM1:8B61 CMP #6
ROM1:8B62 BCC try_bomb_upgrade ; We're standing on the upgrade. See if we can buy it.
 
ROM1:8B70 locret_118B70:
ROM1:8B70 RTS
 
ROM1:8B71 try_bomb_upgrade: ; Cost for bomb upgrade
ROM1:8B71 LDA #100
ROM1:8B72 CMP num_rupees
ROM1:8B73 BEQ has_enough_rupees_for_bomb_upgrade
ROM1:8B74 BCS locret_118B70 ; Not enough rupees
 
ROM1:8B75 has_enough_rupees_for_bomb_upgrade:
ROM1:8B75 CLC
ROM1:8B76 ADC pending_rupees_sub
ROM1:8B77 STA pending_rupees_sub
ROM1:8B78 LDA #Sound3_Pickup
ROM1:8B79 STA play_sound_3 ; Play Sound3_Pickup
ROM1:8B7A LDA max_bombs
ROM1:8B7B CLC
ROM1:8B7C ADC #4 ; Number of bombs per bomb upgrade
ROM1:8B7D STA max_bombs ; Add 4 to max bombs
ROM1:8B7E STA num_bombs ; Fill bombs after bomb upgrade
ROM1:8B7F JMP mark_finished_and_increase_store_state
 
Subroutine update_monster_old_man_4
ROM1:8B95 update_monster_old_man_4:
ROM1:8B95 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8B96 BNE locret_118B9C
ROM1:8B97 STA object_type_1
 
ROM1:8B9C locret_118B9C:
ROM1:8B9C RTS
 
Subroutine check_old_man_hit_and_update_sprite
ROM1:8B9D check_old_man_hit_and_update_sprite:
ROM1:8B9D JSR check_if_old_man_hit
ROM1:8B9E JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM1:8B9F JMP update_object_sprite_vertical
 
Subroutine update_monster_event_1_main
ROM1:8BA6 update_monster_event_1_main:
ROM1:8BA6 LDA global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8BA7 CMP #4
ROM1:8BA8 BNE not_state_4
ROM1:8BA9 LDA frame_counter
ROM1:8BAA AND #1
ROM1:8BAB BNE odd_frame
 
ROM1:8BAC not_state_4:
ROM1:8BAC JSR check_old_man_hit_and_update_sprite
ROM1:8BAD JSR setup_mugging_item_sprites ; Set up floor item sprites in a mugging room
 
ROM1:8BAE odd_frame: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8BAE LDA global_room_state
ROM1:8BAF JSR call_jump_table
 
ROM1:8BB0   .WORD update_monster_event_1_0
ROM1:8BB2   .WORD store_state_text_scroll
ROM1:8BB4   .WORD update_monster_event_1_2 ; See if Link is standing on hearts or rupees in a mugging room
ROM1:8BB6   .WORD store_state_disappearing_after_purchase
ROM1:8BB8   .WORD update_monster_old_man_4
 
ROM1:8BC7 mugging_item_x: .BYTE $58
ROM1:8BC8   .BYTE $98
ROM1:8BC9 mugging_item_y: .BYTE $1A
ROM1:8BCA   .BYTE $18
 
Subroutine setup_mugging_item_sprites
; Set up floor item sprites in a mugging room
ROM1:8BCB setup_mugging_item_sprites:
ROM1:8BCB LDX #1
 
ROM1:8BCC loop:
ROM1:8BCC TXA
ROM1:8BCD PHA
ROM1:8BCE LDA mugging_item_x,X
ROM1:8BCF STA floor_item_x
ROM1:8BD0 LDA #$98
ROM1:8BD1 STA floor_item_y
ROM1:8BD2 LDA mugging_item_y,X
ROM1:8BD3 LDX #$13
ROM1:8BD4 JSR setup_sprite
ROM1:8BD5 PLA
ROM1:8BD6 TAX
ROM1:8BD7 DEX
ROM1:8BD8 BPL loop
ROM1:8BD9 RTS
 
ROM1:8BE6 update_monster_event_1_0:
ROM1:8BE6 LDA #$A
ROM1:8BE7 STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8BE8 LDA #$76
ROM1:8BE9 JMP store_ppu_command_index_and_increase_store_state
 
Subroutine update_monster_event_1_2
; See if Link is standing on hearts or rupees in a mugging room
ROM1:8BEF update_monster_event_1_2:
ROM1:8BEF LDX #1
 
ROM1:8BF0 loop: ; Check Link's position against the mugging floor items
ROM1:8BF0 LDA object_x
ROM1:8BF1 CMP mugging_item_x,X
ROM1:8BF2 BNE skip
ROM1:8BF3 LDA object_y
ROM1:8BF4 SEC
ROM1:8BF5 SBC #$98
ROM1:8BF6 JSR absolute_value ; A = abs(A)
ROM1:8BF7 CMP #6
ROM1:8BF8 BCC standing_on_floor_item
 
ROM1:8BF9 skip:
ROM1:8BF9 DEX
ROM1:8BFA BPL loop
 
ROM1:8C07 locret_118C07:
ROM1:8C07 RTS
 
ROM1:8C08 standing_on_floor_item: ; We're standing on a mugging floor item. X = 0 for life, 1 for money.
ROM1:8C08 CPX #0
ROM1:8C09 BEQ life
ROM1:8C0A LDA #50 ; We're standing on the "money" option.
ROM1:8C0B CMP num_rupees ; See if we have 50 rupees to pay.
ROM1:8C0C BEQ have_50_rupees
ROM1:8C0D BCS locret_118C07
 
ROM1:8C0E have_50_rupees:
ROM1:8C0E CLC
ROM1:8C0F ADC pending_rupees_sub
ROM1:8C10 STA pending_rupees_sub ; Subtract $50 for mugging
ROM1:8C11 JMP open_door
 
ROM1:8C12 life: ; Check if we have more than 3 hearts.
ROM1:8C12 LDA hearts
ROM1:8C13 AND #$F0
ROM1:8C14 CMP #$30
ROM1:8C15 BCS take_life
ROM1:8C16 STA hearts ; We don't have 3 hearts. This is handling the corner case
  ; of the player making it to a mugging room with only 3 hearts.
ROM1:8C17 LDA #0
ROM1:8C18 STA partial_heart ; If we only have 3 hearts in a mugging room, just take some damage and don't subtract any hearts.
ROM1:8C19 JMP open_door
 
ROM1:8C1A take_life: ; 0xF0 = max hearts, 0x0F = current hearts
ROM1:8C1A LDA hearts
ROM1:8C1B PHA ; Store hearts.
ROM1:8C1C AND #$F0 ; Mask out heart containers.
ROM1:8C1D SEC
ROM1:8C1E SBC #$10 ; Subtract one heart container.
ROM1:8C1F STA var_0
ROM1:8C20 PLA ; Load hearts.
ROM1:8C21 AND #$F ; Mask out current health.
ROM1:8C22 SEC
ROM1:8C23 SBC #1
ROM1:8C24 BPL had_one_heart
ROM1:8C25 LDA #0 ; The player had no full hearts. Keep it at 0 and don't wrap to 0xFF.
 
ROM1:8C26 had_one_heart: ; Combine hearts and heart containers.
ROM1:8C26 ORA var_0
ROM1:8C27 STA hearts ; Subtract a heart container.
 
ROM1:8C28 open_door:
ROM1:8C28 LDA #Sound3_Pickup
ROM1:8C29 STA play_sound_3 ; Play Sound3_Pickup
ROM1:8C2A LDA #1
ROM1:8C2B STA open_doors_in_room ; Open doors after paying the mugger.
ROM1:8C2C JMP mark_finished_and_increase_store_state
 
Function chunk for update_monster_hungry_goriya
ROM1:8C2D update_monster_hungry_goriya_main: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8C2D LDA global_room_state
ROM1:8C2E CMP #3
ROM1:8C2F BNE not_state_3
ROM1:8C30 LDA frame_counter ; Skip the following update on odd frames unless we're in state 3.
ROM1:8C31 AND #1
ROM1:8C32 BNE odd_frame
 
ROM1:8C33 not_state_3:
ROM1:8C33 JSR check_if_old_man_hit
ROM1:8C34 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM1:8C35 JSR update_object_sprite_horizontal
 
ROM1:8C36 odd_frame: ; Global room state. This is used by the fairy lake, stores, etc.
ROM1:8C36 LDA global_room_state
ROM1:8C37 JSR call_jump_table
 
ROM1:8C38   .WORD store_state_text_scroll
ROM1:8C3A   .WORD update_monster_hungry_goriya_1
ROM1:8C3C   .WORD store_state_disappearing_after_purchase
ROM1:8C3E   .WORD update_monster_hungry_goriya_3
 
Subroutine update_monster_hungry_goriya_1
ROM1:8C7C update_monster_hungry_goriya_1:
ROM1:8C7C LDY #$F
ROM1:8C7D LDA walk_state_and_weapon_state,Y
ROM1:8C7E ASL A
ROM1:8C7F BCC locret_118CAD
ROM1:8C80 LDA #$40
ROM1:8C81 STA walk_state_and_weapon_state
ROM1:8C82 LDA #Sound1_Secret
ROM1:8C83 STA play_sound_1 ; Play Sound1_Secret
 
ROM1:8C8D mark_finished_and_increase_store_state:
ROM1:8C8D JSR mark_room_item_collected
ROM1:8C8E LDA #$40
ROM1:8C8F STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8C90 LDA #$1E
ROM1:8C91 JMP store_ppu_command_index_and_increase_store_state
 
Subroutine update_monster_hungry_goriya_3
ROM1:8C99 update_monster_hungry_goriya_3:
ROM1:8C99 JSR update_link_sprite_and_check_ladder_bank_1 ; Call update_link_sprite_and_check_ladder, then set bank 1 before returning.
ROM1:8C9A LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM1:8C9B BNE locret_118CAD
ROM1:8C9C LDY #$F
ROM1:8C9D STA walk_state_and_weapon_state,Y
ROM1:8C9E STA have_meat
ROM1:8C9F STA walk_state_and_weapon_state
ROM1:8CA0 STA object_type_1
 
ROM1:8CAD locret_118CAD:
ROM1:8CAD RTS
 
ROM1:8CAE   .BYTE $FF
ROM1:8CAF   .BYTE $FF
ROM1:8CB0   .BYTE $FF
ROM1:8CB1   .BYTE $FF
ROM1:8CB2   .BYTE $FF
ROM1:8CB3   .BYTE $FF
ROM1:8CB4   .BYTE $FF
ROM1:8CB5   .BYTE $FF
ROM1:8CB6   .BYTE $FF
ROM1:8CB7   .BYTE $FF
ROM1:8CB8   .BYTE $FF
ROM1:8CB9   .BYTE $FF
ROM1:8CBA   .BYTE $FF
ROM1:8CBB   .BYTE $FF
ROM1:8CBC   .BYTE $FF
ROM1:8CBD   .BYTE $FF
ROM1:8CBE   .BYTE $FF
ROM1:8CBF   .BYTE $FF
ROM1:8CC0   .BYTE $FF
ROM1:8CC1   .BYTE $FF
ROM1:8CC2   .BYTE $FF
ROM1:8CC3   .BYTE $FF
ROM1:8CC4   .BYTE $FF
ROM1:8CC5   .BYTE $FF
ROM1:8CC6   .BYTE $FF
ROM1:8CC7   .BYTE $FF
ROM1:8CC8   .BYTE $FF
ROM1:8CC9   .BYTE $FF
ROM1:8CCA   .BYTE $FF
ROM1:8CCB   .BYTE $FF
ROM1:8CCC   .BYTE $FF
ROM1:8CCD   .BYTE $FF
ROM1:8CCE   .BYTE $FF
ROM1:8CCF   .BYTE $FF
ROM1:8CD0   .BYTE $FF
ROM1:8CD1   .BYTE $FF
ROM1:8CD2   .BYTE $FF
ROM1:8CD3   .BYTE $FF
ROM1:8CD4   .BYTE $FF
ROM1:8CD5   .BYTE $FF
ROM1:8CD6   .BYTE $FF
ROM1:8CD7   .BYTE $FF
ROM1:8CD8   .BYTE $FF
ROM1:8CD9   .BYTE $FF
ROM1:8CDA   .BYTE $FF
ROM1:8CDB   .BYTE $FF
ROM1:8CDC   .BYTE $FF
ROM1:8CDD   .BYTE $FF
ROM1:8CDE   .BYTE $FF
ROM1:8CDF   .BYTE $FF
ROM1:8CE0   .BYTE $FF
ROM1:8CE1   .BYTE $FF
ROM1:8CE2   .BYTE $FF
ROM1:8CE3   .BYTE $FF
ROM1:8CE4   .BYTE $FF
ROM1:8CE5   .BYTE $FF
ROM1:8CE6   .BYTE $FF
ROM1:8CE7   .BYTE $FF
ROM1:8CE8   .BYTE $FF
ROM1:8CE9   .BYTE $FF
ROM1:8CEA   .BYTE $FF
ROM1:8CEB   .BYTE $FF
ROM1:8CEC   .BYTE $FF
ROM1:8CED   .BYTE $FF
ROM1:8CEE   .BYTE $FF
ROM1:8CEF   .BYTE $FF
ROM1:8CF0   .BYTE $FF
ROM1:8CF1   .BYTE $FF
ROM1:8CF2   .BYTE $FF
ROM1:8CF3   .BYTE $FF
ROM1:8CF4   .BYTE $FF
ROM1:8CF5   .BYTE $FF
ROM1:8CF6   .BYTE $FF
ROM1:8CF7   .BYTE $FF
ROM1:8CF8   .BYTE $FF
ROM1:8CF9   .BYTE $FF
ROM1:8CFA   .BYTE $FF
ROM1:8CFB   .BYTE $FF
ROM1:8CFC   .BYTE $FF
ROM1:8CFD   .BYTE $FF
ROM1:8CFE   .BYTE $FF
ROM1:8CFF   .BYTE $FF
 
Subroutine init_sram_code
; Copy the code block from ROM1:90A5 to CODE:6C90.
ROM1:8D00 init_sram_code:
ROM1:8D00 LDA #0
ROM1:8D01 STA var_0 ; var_0 = $90A5
ROM1:8D02 LDA #$A5
ROM1:8D03 STA var_1
ROM1:8D04 LDA #$90
ROM1:8D05 STA var_2 ; var_2 = $6C90
ROM1:8D06 LDA #$6C
ROM1:8D07 STA var_3
ROM1:8D08 LDY #0
 
ROM1:8D09 loop:
ROM1:8D09 LDA (var_0),Y
ROM1:8D0A STA (var_2),Y
ROM1:8D0B LDA var_0 ; 16-bit increment var_0
ROM1:8D0C CLC
ROM1:8D0D ADC #1
ROM1:8D0E STA var_0
ROM1:8D0F LDA var_1
ROM1:8D10 ADC #0
ROM1:8D11 STA var_1
ROM1:8D12 LDA var_2 ; 16-bit increment var_2
ROM1:8D13 CLC
ROM1:8D14 ADC #1
ROM1:8D15 STA var_2
ROM1:8D16 LDA var_3
ROM1:8D17 ADC #0
ROM1:8D18 STA var_3
ROM1:8D19 CMP #$7F ; Loop until $7F00
ROM1:8D1A BNE loop
ROM1:8D1B LDA var_2
ROM1:8D1C CMP #0
ROM1:8D1D BNE loop
ROM1:8D1E RTS
 
ROM1:8D3B rom1_sprite_data_ptrs: .WORD rom1_sprite_data_0
ROM1:8D3D   .WORD rom1_sprite_data_1
ROM1:8D3F rom1_sprite_data_size: .WORD 9 ; These are stored backwards (wrong endian), and are actually
  ; 0x0900 and 0x0820.
ROM1:8D41   .WORD $2008
ROM1:8D43 rom1_sprite_data_ppu_addresses: .WORD 7
ROM1:8D45   .WORD $17
 
Subroutine setup_rom1_sprite_data
; Copy a block of sprite data to the PPU.
ROM1:8D47 setup_rom1_sprite_data:
ROM1:8D47 JSR clear_ppumask
ROM1:8D48 LDA PPUSTATUS
 
ROM1:8D49 loop: ; 0 at start
ROM1:8D49 LDA usually_zero
ROM1:8D4A ASL A ; A << 1, since we're indexing 16-bit tables
ROM1:8D4B TAX
ROM1:8D4C LDA rom1_sprite_data_ptrs,X
ROM1:8D4D STA var_0
ROM1:8D4E LDA rom1_sprite_data_size,X
ROM1:8D4F STA var_2
ROM1:8D50 LDA rom1_sprite_data_ppu_addresses,X
ROM1:8D51 STA PPUADDR ; PPU address high byte
ROM1:8D52 INX
ROM1:8D53 LDA rom1_sprite_data_ptrs,X
ROM1:8D54 STA var_1
ROM1:8D55 LDA rom1_sprite_data_size,X
ROM1:8D56 STA var_3
ROM1:8D57 LDA rom1_sprite_data_ppu_addresses,X ; PPU address low byte
ROM1:8D58 JSR copy_sprite_data_2
ROM1:8D59 LDA usually_zero
ROM1:8D5A CMP #2 ; Write 2 blocks of data to the PPU.
ROM1:8D5B BNE loop
ROM1:8D5C LDA #$A5
ROM1:8D5D STA sprite_data_2_initialized ; Set to 0xA5. This signals the title menu that this is already
  ; set up and doesn't need to be done again.
ROM1:8D5E LDA #0
ROM1:8D5F STA usually_zero ; Set to 0.
ROM1:8D60 RTS
 
Subroutine copy_sprite_data_2
ROM1:8D84 copy_sprite_data_2:
ROM1:8D84 STA PPUADDR
ROM1:8D85 LDY #0
 
ROM1:8D86 loop: ; Read a byte of sprite data
ROM1:8D86 LDA (var_0),Y
ROM1:8D87 STA PPUDATA ; Write a byte of sprite data
ROM1:8D88 LDA var_0 ; Source ptr low byte++
ROM1:8D89 CLC
ROM1:8D8A ADC #1
ROM1:8D8B STA var_0
ROM1:8D8C LDA var_1 ; Carry into source ptr high byte
ROM1:8D8D ADC #0
ROM1:8D8E STA var_1
ROM1:8D8F LDA var_3 ; Decrement 16-bit bytes left
ROM1:8D90 SEC
ROM1:8D91 SBC #1
ROM1:8D92 STA var_3
ROM1:8D93 LDA var_2
ROM1:8D94 SBC #0
ROM1:8D95 STA var_2
ROM1:8D96 LDA var_2
ROM1:8D97 BNE loop ; Loop if var_2/var_3 != 0
ROM1:8D98 LDA var_3
ROM1:8D99 BNE loop
ROM1:8D9A INC usually_zero
ROM1:8D9B RTS
 
ROM1:8DB4 rom1_sprite_data_0:
Subroutine create_recorder_whirlwind_at_A
; Create a whistle whirlwind at Y = A. This is done when ; creating the whirlwind after warping into the new screen.
ROM1:A000 create_recorder_whirlwind_at_A:
ROM1:A000 STA object_y
 
ROM1:A002 create_recorder_whirlwind_at_link: ; Create a whistle whirlwind at Link's Y position and X = 0.
ROM1:A002 LDA object_y ; This is done when creating the whirlwind before warping out
  ; of the screen.
ROM1:A003 STA object_y,X
ROM1:A004 LDA #0
ROM1:A005 STA object_x,X
ROM1:A006 LDA #ObjectType_Whirlwind
ROM1:A007 STA object_type,X ; Set ObjectType_Whirlwind
ROM1:A008 RTS
 
ROM1:A010 recorder_locations_tbl: .BYTE $36
ROM1:A011   .BYTE $3B
ROM1:A012   .BYTE $73
ROM1:A013   .BYTE $44
ROM1:A014   .BYTE $A
ROM1:A015   .BYTE $21
ROM1:A016   .BYTE $41
ROM1:A017   .BYTE $6C
 
Function chunk for update_monster_whirlwind
ROM1:A018 update_monster_whirlwind_main:
ROM1:A018 LDA walk_state_and_weapon_state
ROM1:A019 AND #$40
ROM1:A01A TAY
ROM1:A01B LDA #var_2
ROM1:A01C CLC
ROM1:A01D ADC object_x,X
ROM1:A01E STA object_x,X
ROM1:A01F CPY #$40
ROM1:A020 BNE loc_11A049
ROM1:A021 LDY held_by_recorder_whirlwind ; If 1, Link is outbound on the whirlwind.
  ; If 2, Link is inbound on the whirlwind.
ROM1:A022 BEQ loc_11A049
ROM1:A023 STA object_x
ROM1:A024 DEY
ROM1:A025 BEQ loc_11A075
ROM1:A026 CMP #$80
ROM1:A027 BNE loc_11A075
ROM1:A028 ASL A ; A = 80, so this sets A = 0.
ROM1:A029 STA walk_state_and_weapon_state ; Set to 0
ROM1:A02A STA held_by_recorder_whirlwind ; Set to 0
ROM1:A02B STA object_type,X ; Set to 0
ROM1:A02C TXA
ROM1:A02D PHA
ROM1:A02E JSR setup_minimap_triforce_position_unless_in_cellar_or_whirlwind
ROM1:A02F PLA
ROM1:A030 TAX
ROM1:A031 JMP loc_11A08A
 
ROM1:A049 loc_11A049: ; Check if Link was hit by an enemy. X is the enemy we're
ROM1:A049 JSR check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM1:A04A LDA var_6
ROM1:A04B BEQ loc_11A075
ROM1:A04C LDA #ControllerBits_Dpad_Right
ROM1:A04D STA object_direction
ROM1:A04E LSR A ; A = 0
ROM1:A04F STA object_knockback ; Set to 0.
ROM1:A050 STA knockback_frames ; Set to 0.
ROM1:A051 STA is_in_cellar ; Set to 0.
ROM1:A052 LDA #$40
ROM1:A053 STA walk_state_and_weapon_state
ROM1:A054 LDA #$F8
ROM1:A055 STA sprite_oam_data_48
ROM1:A056 STA sprite_oam_data_4C
ROM1:A057 LDA next_recorder_location
ROM1:A058 AND #7
ROM1:A059 TAY
ROM1:A05A LDA recorder_locations_tbl,Y
ROM1:A05B STA displayed_map_location ; Set from the next whistle location
ROM1:A05C INC held_by_recorder_whirlwind ; If 1, Link is outbound on the whirlwind.
  ; If 2, Link is inbound on the whirlwind.
 
ROM1:A075 loc_11A075:
ROM1:A075 LDA object_x,X
ROM1:A076 CMP #240
ROM1:A077 BCC loc_11A08A ; Branch if whirlwind X < 240
ROM1:A078 JSR clear_recorder_whirlwind
ROM1:A079 LDA held_by_recorder_whirlwind ; If 1, Link is outbound on the whirlwind.
  ; If 2, Link is inbound on the whirlwind.
ROM1:A07A BEQ loc_11A08A ; Branch if not held_by_recorder_whirlwind
ROM1:A07B TXA
ROM1:A07C PHA
ROM1:A07D JSR start_GameMode_PrepareScroll
ROM1:A07E PLA
ROM1:A07F TAX
 
ROM1:A08A loc_11A08A:
ROM1:A08A JMP loc_11A105
 
Subroutine clear_recorder_whirlwind
ROM1:A08D clear_recorder_whirlwind:
ROM1:A08D LDA #0
ROM1:A08E STA object_type,X ; Set to 0
ROM1:A08F STA object_knockback,X ; Set to 0.
ROM1:A090 STA knockback_frames,X ; Set to 0.
ROM1:A091 STA enemy_action_timers,X ; Set to 0.
ROM1:A092 STA walk_state_and_weapon_state,X ; Set to 0.
ROM1:A093 STA invincibility_frames,X ; Set to 0.
ROM1:A094 LDA #$FF
ROM1:A095 STA object_slot_in_use,X ; Set to 0xFF
ROM1:A096 LDA #1
ROM1:A097 STA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM1:A098 RTS
 
Subroutine recorder_call_whirlwind
ROM1:A0A8 recorder_call_whirlwind:
ROM1:A0A8 LDA game_mode ; Only call the whirlwind in normal mode
ROM1:A0A9 CMP #GameMode_Normal
ROM1:A0AA BNE locret_11A104
ROM1:A0AB JSR increase_or_decrease_recorder_idx
ROM1:A0AC LDA next_recorder_location
ROM1:A0AD AND #7
ROM1:A0AE TAY
ROM1:A0AF LDA powers_of_two,Y
ROM1:A0B0 STA var_0
 
ROM1:A0B1 find_next_recorder_location: ; Find the next location that we can whistle to.
ROM1:A0B1 LDA triforce_pieces_collected
ROM1:A0B2 BEQ locret_11A104 ; If zero, there aren't any available locations.
ROM1:A0B3 BIT var_0
ROM1:A0B4 BNE create_outbound_whistle_whirlwind ; Don't allow calling the whirlwind if it's already been
  ; called on this screen.
ROM1:A0B5 JSR increase_or_decrease_recorder_idx
ROM1:A0B6 LDA object_direction
ROM1:A0B7 AND #9
ROM1:A0B8 BEQ loc_11A0D7
ROM1:A0B9 ASL var_0
ROM1:A0BA BCC find_next_recorder_location
ROM1:A0BB ROL var_0
ROM1:A0BC JMP find_next_recorder_location
 
ROM1:A0D7 loc_11A0D7:
ROM1:A0D7 LSR var_0
ROM1:A0D8 BCC find_next_recorder_location
ROM1:A0D9 ROR var_0
ROM1:A0DA JMP find_next_recorder_location
 
ROM1:A0DB create_outbound_whistle_whirlwind: ; Don't allow calling the whirlwind if it's already been
ROM1:A0DB LDA recorder_called_whirlwind_already ; called on this screen.
ROM1:A0DC ORA held_by_recorder_whirlwind ; Don't allow calling the whirlwind if we're already caught by
  ; one, so you can't call a whirlwind while you're still being
  ; dropped off by the previous one.
ROM1:A0DD BNE locret_11A104
ROM1:A0DE JSR find_last_available_object_idx ; Result is returned in tmp_result.
ROM1:A0DF BEQ locret_11A104 ; Stop if there are no object slots free.
ROM1:A0E0 INC recorder_called_whirlwind_already ; Mark that the player has used the whistle, so we won't
  ; allow it again until the screen is exited.
ROM1:A0E1 TYA
ROM1:A0E2 TAX
ROM1:A0E3 JMP create_recorder_whirlwind_at_link ; Create a whistle whirlwind at Link's Y position and X = 0.
  ; This is done when creating the whirlwind before warping out
  ; of the screen.
 
Subroutine increase_or_decrease_recorder_idx
ROM1:A0F5 increase_or_decrease_recorder_idx:
ROM1:A0F5 INC next_recorder_location ; Move to next whistle entry
ROM1:A0F6 LDA object_direction
ROM1:A0F7 AND #9
ROM1:A0F8 BNE locret_11A104
ROM1:A0F9 DEC next_recorder_location ; Or undo and move to previous whistle entry
ROM1:A0FA DEC next_recorder_location ; (undo)
 
ROM1:A104 locret_11A104:
ROM1:A104 RTS
 
Function chunk for update_monster_whirlwind
ROM1:A105 loc_11A105:
ROM1:A105 LDA #1
ROM1:A106 JSR update_object_animation_frame
ROM1:A107 LDA frame_counter
ROM1:A108 AND #OAMAttributes_Palette_3
ROM1:A109 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM1:A10A JSR store_animation_frame
ROM1:A10B LDA #0
ROM1:A10C JMP update_object_sprite_horizontal
 
ROM1:A119 recorder_locations_y_tbl: .BYTE $8D ; Y positions where the whirlwind appears when entering the
  ; new screen.
ROM1:A11A   .BYTE $AD
ROM1:A11B   .BYTE $8D
ROM1:A11C   .BYTE $8D
ROM1:A11D   .BYTE $AD
ROM1:A11E   .BYTE $8D
ROM1:A11F   .BYTE $AD
ROM1:A120   .BYTE $5D
 
Function chunk for task0_Normal
ROM1:A121 task0_Normal_p2: ; Check if we exited the previous screen via recorder (== 1)
ROM1:A121 LDA held_by_recorder_whirlwind
ROM1:A122 BEQ not_entering_by_whirlwind
ROM1:A123 INC held_by_recorder_whirlwind ; Switch from 1 to 2. We're inbound now.
ROM1:A124 LDA #$40
ROM1:A125 STA walk_state_and_weapon_state
ROM1:A126 LDX #9
ROM1:A127 LDA next_recorder_location ; Load to create the inbound whirlwind
ROM1:A128 AND #7 ; Is this a sanity check or can other things be in this byte?
ROM1:A129 TAY
ROM1:A12A LDA recorder_locations_y_tbl,Y ; Load the Y location that the whirlwind appears on this screen when entering.
ROM1:A12B JSR create_recorder_whirlwind_at_A ; Create the whirlwind that's carrying us in.
 
ROM1:A12C not_entering_by_whirlwind: ; We're finished with screen initialization. Switch to
ROM1:A12C JMP start_task1 ; normal updates.
 
Subroutine check_push_blocks
; Set var_15 to 0 if Link is near any push blocks.
ROM1:A13E check_push_blocks:
ROM1:A13E LDX #$C ; For each object slot
 
ROM1:A13F loop:
ROM1:A13F LDA object_type,X
ROM1:A140 CMP #ObjectType_DungeonSecret_Push_Block ; An overworld push block.
ROM1:A141 BEQ loc_11A153
ROM1:A142 CMP #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM1:A143 BEQ loc_11A153
ROM1:A144 CMP #ObjectType_OverworldSecret_Push_Tomb ; An overworld push block (tomb sprite).
ROM1:A145 BEQ loc_11A153
ROM1:A146 CMP #ObjectType_OverworldSecret_Push_Armos ; An overworld push block (Armos sprite).
ROM1:A147 BNE continue
 
ROM1:A153 loc_11A153:
ROM1:A153 LDA walk_state_and_weapon_state,X
ROM1:A154 CMP #1
ROM1:A155 BNE continue
ROM1:A156 LDA object_x
ROM1:A157 SEC
ROM1:A158 SBC object_x,X
ROM1:A159 JSR absolute_value ; A = abs(A)
ROM1:A15A CMP #16
ROM1:A15B BCS continue
ROM1:A15C LDA object_y
ROM1:A15D CLC
ROM1:A15E ADC #3
ROM1:A15F SEC
ROM1:A160 SBC object_y,X
ROM1:A161 JSR absolute_value ; A = abs(A)
ROM1:A162 CMP #16
ROM1:A163 BCS continue
ROM1:A164 LDA #0
ROM1:A165 STA var_15 ; Set to 0.
 
ROM1:A166 continue:
ROM1:A166 DEX
ROM1:A167 BNE loop
ROM1:A168 RTS
 
Subroutine update_picking_up_ganon_triforce
ROM1:A17C update_picking_up_ganon_triforce:
ROM1:A17C LDA picking_up_ganon_triforce
ROM1:A17D BEQ ret
ROM1:A17E LDA enemy_action_timers
ROM1:A17F BEQ timer_expired
ROM1:A180 LDY #PPUCommandIndices_DungeonPPUData ; This sends ppu_data_for_current_dungeon.
ROM1:A181 LDA enemy_action_timers
ROM1:A182 BEQ set_triforce_refill_and_advance_task_state
ROM1:A183 AND #7
ROM1:A184 CMP #4
ROM1:A185 BCC store_ppu_index
ROM1:A186 LDY #PPUCommandIndices_PickedUpTriforce
 
ROM1:A187 store_ppu_index: ; Set to PPUCommandIndices_DungeonPPUData or PPUCommandIndices_PickedUpTriforce.
ROM1:A187 STY current_ppu_command_index
ROM1:A188 RTS
 
ROM1:A189 set_triforce_refill_and_advance_task_state:
ROM1:A189 LDA #2
ROM1:A18A STA health_refill ; Set to 2 for triforce health refill
ROM1:A18B INC task_state
ROM1:A18C RTS
 
ROM1:A18D timer_expired: ; This is called after picking up Ganon's triforce, as the
ROM1:A18D JSR send_ppu_data_after_picking_up_ganon_triforce ; death mountain music starts back up.
ROM1:A18E LDA #Music_DeathMountain
ROM1:A18F STA play_music ; Play Music_DeathMountain
ROM1:A190 LDA #1
ROM1:A191 STA has_ganon_triforce ; Set to 1.
ROM1:A192 LSR A
ROM1:A193 STA walk_state_and_weapon_state
ROM1:A194 STA picking_up_ganon_triforce
 
ROM1:A195 ret:
ROM1:A195 RTS
 
Subroutine pick_up_ganon_triforce
ROM1:A1B1 pick_up_ganon_triforce:
ROM1:A1B1 INC picking_up_ganon_triforce
ROM1:A1B2 LDA #$C0
ROM1:A1B3 STA enemy_action_timers
ROM1:A1B4 LDA #$40
ROM1:A1B5 STA walk_state_and_weapon_state
ROM1:A1B6 RTS
 
ROM1:A1BD byte_11A1BD: .BYTE $3F
ROM1:A1BE   .BYTE $1C
ROM1:A1BF   .BYTE 4
ROM1:A1C0   .BYTE $F
ROM1:A1C1   .BYTE 7
ROM1:A1C2   .BYTE $17
ROM1:A1C3   .BYTE $27
ROM1:A1C4   .BYTE $FF
ROM1:A1C5 byte_11A1C5: .BYTE 7
ROM1:A1C6   .BYTE $17
ROM1:A1C7   .BYTE $30
ROM1:A1C8   .BYTE $16
ROM1:A1C9   .BYTE $2C
ROM1:A1CA   .BYTE $3C
ROM1:A1CB   .BYTE $27
ROM1:A1CC   .BYTE 6
ROM1:A1CD   .BYTE $16
ROM1:A1CE   .BYTE $A0
ROM1:A1CF   .BYTE 2
ROM1:A1D0   .BYTE $D0
ROM1:A1D1   .BYTE 6
ROM1:A1D2   .BYTE $A0
ROM1:A1D3   .BYTE 5
ROM1:A1D4   .BYTE $D0
ROM1:A1D5   .BYTE 2
 
Subroutine send_ppu_data_after_picking_up_ganon_triforce
; This is called after picking up Ganon's triforce, as the ; death mountain music starts back up.
ROM1:A1D6 send_ppu_data_after_picking_up_ganon_triforce:
ROM1:A1D6 LDY #8
ROM1:A1D7 TYA
ROM1:A1D8 PHA
ROM1:A1D9 LDX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM1:A1DA LDY #0
 
ROM1:A1DB loop1:
ROM1:A1DB LDA byte_11A1BD,Y
ROM1:A1DC STA ppu_command_buffer,X
ROM1:A1DD INX
ROM1:A1DE INY
ROM1:A1DF CPY #8
ROM1:A1E0 BNE loop1
ROM1:A1E1 STX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM1:A1E2 PLA
ROM1:A1E3 TAY
ROM1:A1E4 LDX #2
 
ROM1:A1E5 loop2:
ROM1:A1E5 LDA byte_11A1C5,Y
ROM1:A1E6 STA ppu_command_buffer_04,X
ROM1:A1E7 DEY
ROM1:A1E8 DEX
ROM1:A1E9 BPL loop2
ROM1:A1EA LDX processing_object_index
ROM1:A1EB RTS
 
Subroutine sub_11A200
; XXX: find refs
ROM1:A200 sub_11A200:
ROM1:A200 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM1:A201 LDA #$B
ROM1:A202 JMP update_object_sprite_horizontal
 
ROM1:A203 LDA current_room_floor_item_hidden ; Load to check if 0.
ROM1:A204 BEQ ret
ROM1:A205 JSR get_room_status_floor_item_picked_up
ROM1:A206 BNE ret
ROM1:A207 LDA #0
ROM1:A208 STA current_room_floor_item_hidden ; Set to 0.
ROM1:A209 LDA #Sound1_ItemAppeared
ROM1:A20A STA play_sound_1 ; Play Sound1_ItemAppeared
 
ROM1:A20B ret:
ROM1:A20B RTS
 
ROM1:A21B armos_x_offsets: .BYTE 0
ROM1:A21C   .BYTE 0
ROM1:A21D   .BYTE $F0
ROM1:A21E   .BYTE $10
ROM1:A21F armos_y_offsets: .BYTE $FB
ROM1:A220   .BYTE $13
ROM1:A221   .BYTE 3
ROM1:A222   .BYTE 3
 
Subroutine handle_spawning_armos_ghini_on_touch
; This is called when walking into an object. ; - Handles summoning an Armos when walking into a statue ; - Handles summoning Ghini from graves ; - Clears the tile that the new enemy is spawned onto
ROM1:A223 handle_spawning_armos_ghini_on_touch:
ROM1:A223 LDA object_tile_offset_whole
ROM1:A224 BNE ret
ROM1:A225 LDA walking_directions
ROM1:A226 BEQ ret ; Return if not moving
ROM1:A227 LDA #$BB
ROM1:A228 STA var_2 ; Store 0xBB. This will check tile types 0xBB through 0xC2.
ROM1:A229 LDX #8 ; X = 8
ROM1:A22A LDA tile_walking_onto
 
ROM1:A22B loop: ; var_2++
ROM1:A22B INC var_2
ROM1:A22C DEX ; X--
ROM1:A22D BPL check_tile ; branch if X != 0xFF (didn't wrap)
 
ROM1:A22E ret:
ROM1:A22E LDX #0
ROM1:A22F RTS
 
ROM1:A230 check_tile:
ROM1:A230 CMP var_2
ROM1:A231 BNE loop ; Branch if A != var_2
ROM1:A232 LDA object_x
ROM1:A233 STA var_0 ; Store Link's X position
ROM1:A234 LDA object_y
ROM1:A235 STA var_1 ; Store Link's Y position
ROM1:A236 LDA object_direction ; Load Link's walking direction
ROM1:A237 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM1:A238 BEQ vertical
ROM1:A239 LDA var_2
ROM1:A23A AND #3 ; A &= 3
ROM1:A23B TAY ; Y = A
ROM1:A23C LDA var_0 ; A = Link's X position
ROM1:A23D CPY #2
ROM1:A23E BCS loc_11A25E ; branch if Y < 2
ROM1:A23F CLC
ROM1:A240 ADC #8
 
ROM1:A25E loc_11A25E:
ROM1:A25E AND #$F0
ROM1:A25F STA var_0 ; Spawn the enemy at X = 0xF0
ROM1:A260 JMP spawn_object
 
ROM1:A261 vertical:
ROM1:A261 LDA var_2
ROM1:A262 LSR A
ROM1:A263 BCS spawn_object
ROM1:A264 LDA var_1
ROM1:A265 CLC
ROM1:A266 ADC #8
ROM1:A267 STA var_1
 
ROM1:A268 spawn_object: ; Result is returned in tmp_result.
ROM1:A268 JSR find_last_available_object_idx
ROM1:A269 BEQ ret2 ; Abort if there are no empty object slots
ROM1:A26A LDX tmp_result ; Set the object slot that we'll put the new enemy in
ROM1:A26B LDA object_direction
ROM1:A26C JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM1:A26D LDA var_0 ; Load the new enemy's X position
ROM1:A26E CLC
ROM1:A26F ADC armos_x_offsets,Y
ROM1:A270 STA object_x,X ; Store the new enemy's X position
ROM1:A271 LDA var_1 ; Load the new enemy's Y position
ROM1:A272 CLC
ROM1:A273 ADC armos_y_offsets,Y
ROM1:A274 STA object_y,X ; Store the new enemy's Y position
ROM1:A275 LDA object_slot_in_use,X
ROM1:A276 BEQ ret2
ROM1:A277 LDY #$B
ROM1:A278 STX var_3 ; Store the new enemy's object ID
 
ROM1:A279 loop2:
ROM1:A279 CPY var_3
ROM1:A27A BEQ skip ; Skip checking this object if it's the one we just created
ROM1:A27B LDA object_x,Y
ROM1:A27C CMP object_x,X
ROM1:A27D BNE skip ; Skip if the X position of this object is different than the position of our new object
ROM1:A27E LDA object_y,Y
ROM1:A27F CMP object_y,X
ROM1:A280 BNE skip ; Skip if the X position of this object is different than the position of our new object
ROM1:A281 LDA object_type,Y ; This object is in the same screen position as the place we chose for our new enemy
ROM1:A282 BNE ret2 ; Don't spawn the enemy if this object exists (ID != 0)
ROM1:A283 LDA object_slot_in_use,Y ; Don't spawn Armos/Ghini if byte_492[Y] == 0
ROM1:A284 BEQ ret2
ROM1:A285 BNE loc_11A2B7
 
ROM1:A286 skip:
ROM1:A286 DEY
ROM1:A287 BNE loop2 ; Loop Y through object ID 1
 
ROM1:A2B7 loc_11A2B7:
ROM1:A2B7 LDA #ObjectType_Armos
ROM1:A2B8 LDY var_2
ROM1:A2B9 CPY #$C0
ROM1:A2BA BCS create_armos
ROM1:A2BB LDA #ObjectType_GhiniFromTombs ; Created by handle_spawning_armos_ghini_on_touch
 
ROM1:A2BC create_armos: ; Create ObjectType_Armos or ObjectType_GhiniFromTombs when touching overworld object
ROM1:A2BC STA object_type,X
ROM1:A2BD JSR set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM1:A2BE LDA #$3F
ROM1:A2BF STA enemy_action_timers,X ; Set 0x3F timer for new Armos/Ghini
 
ROM1:A2C0 ret2:
ROM1:A2C0 LDX #0
 
ROM1:A2CD ten_rupee_pattern_x_positions: ; Object indices start at 1, so this really points to the table below this function.
ROM1:A2CD RTS
 
ROM1:A2CE   .BYTE $78
ROM1:A2CF   .BYTE $70
ROM1:A2D0   .BYTE $80
ROM1:A2D1   .BYTE $60
ROM1:A2D2   .BYTE $70
ROM1:A2D3   .BYTE $80
ROM1:A2D4   .BYTE $90
ROM1:A2D5   .BYTE $70
ROM1:A2D6   .BYTE $80
ROM1:A2D7 ten_rupee_pattern_y_positions: .BYTE $78
ROM1:A2D8   .BYTE $70
ROM1:A2D9   .BYTE $80
ROM1:A2DA   .BYTE $80
ROM1:A2DB   .BYTE $90
ROM1:A2DC   .BYTE $90
ROM1:A2DD   .BYTE $90
ROM1:A2DE   .BYTE $90
ROM1:A2DF   .BYTE $A0
ROM1:A2E0   .BYTE $A0
ROM1:A2E1   .BYTE $B0
 
Function chunk for spawn_ten_rupee
ROM1:A2E2 spawn_ten_rupees_main: ; This object creates ten copies of itself when it's spawned.
ROM1:A2E2 LDA enemy_properties,X ; The copies act like 1-rupee drops.
ROM1:A2E3 STA var_1 ; Load enemy_properties to copy to spawned rupees
ROM1:A2E4 LDA #ObjectType_TenRupees ; One rupee, spawned in a pattern of 10
ROM1:A2E5 STA var_0
ROM1:A2E6 LDX #10 ; Spawn ten one rupees
 
ROM1:A2E7 spawn_ten_rupees_loop: ; This is used for spawning the ten rupee pattern and
ROM1:A2E7 JSR set_object_type_and_enemy_properties ; wall traps.
ROM1:A2E8 LDA ten_rupee_pattern_x_positions,X
ROM1:A2E9 STA object_x,X
ROM1:A2EA LDA ten_rupee_pattern_y_positions,X
ROM1:A2EB STA object_y,X
ROM1:A2EC DEX
ROM1:A2ED BNE spawn_ten_rupees_loop
ROM1:A2EE RTS
 
Subroutine set_object_type_and_enemy_properties
; This is used for spawning the ten rupee pattern and ; wall traps.
ROM1:A2FE set_object_type_and_enemy_properties:
ROM1:A2FE LDA var_0
ROM1:A2FF STA object_type,X ; ObjectType_TenRupees or ObjectType_WallTrap_Vert
ROM1:A300 LDA #0
ROM1:A301 STA object_slot_in_use,X ; Set to 0
ROM1:A302 LDA var_1
ROM1:A303 STA enemy_properties,X ; Copy from our source object
ROM1:A304 RTS
 
ROM1:A30E wall_trap_x_positions: .BYTE $20
ROM1:A30F   .BYTE $20
ROM1:A310   .BYTE $D0
ROM1:A311   .BYTE $D0
ROM1:A312   .BYTE $40
ROM1:A313   .BYTE $B0
ROM1:A314 wall_trap_y_positions: .BYTE $5D
ROM1:A315   .BYTE $BD
ROM1:A316   .BYTE $5D
ROM1:A317   .BYTE $BD
ROM1:A318   .BYTE $8D
ROM1:A319   .BYTE $8D
 
Function chunk for spawn_wall_trap
ROM1:A31A spawn_wall_trap_main: ; Load to copy to spawned traps
ROM1:A31A LDA enemy_properties,X
ROM1:A31B STA var_1
ROM1:A31C LDY #5 ; Number of traps to spawn
ROM1:A31D LDA #ObjectType_WallTrap_Vert
ROM1:A31E STA var_0
ROM1:A31F CMP object_type,X ; Check if ObjectType_WallTrap_Vert
ROM1:A320 BEQ spawn_wall_traps ; 3 or 5
ROM1:A321 LDY #3 ; Number of traps to spawn
 
ROM1:A322 spawn_wall_traps: ; 3 or 5
ROM1:A322 TYA
ROM1:A323 CLC
ROM1:A324 ADC processing_object_index
ROM1:A325 TAX
ROM1:A326 LDA wall_trap_x_positions,Y
ROM1:A327 STA object_x,X ; Store X position for wall trap
ROM1:A328 LDA wall_trap_y_positions,Y
ROM1:A329 STA object_y,X ; Store Y position for wall trap
ROM1:A32A JSR set_object_type_and_enemy_properties ; This is used for spawning the ten rupee pattern and
  ; wall traps.
ROM1:A32B DEX
ROM1:A32C DEY
ROM1:A32D BPL spawn_wall_traps ; 3 or 5
 
ROM1:A343 locret_11A343:
ROM1:A343 RTS
 
ROM1:A344   .BYTE 5
ROM1:A345   .BYTE 9
ROM1:A346   .BYTE 6
ROM1:A347   .BYTE $A
ROM1:A348   .BYTE 1
ROM1:A349   .BYTE 2
 
Function chunk for update_monster_wall_trap
ROM1:A34A update_monster_wall_trap_main:
ROM1:A34A LDA walk_state_and_weapon_state,X
ROM1:A34B BNE loc_11A399
ROM1:A34C LDA object_y
ROM1:A34D SEC
ROM1:A34E SBC object_y,X
ROM1:A34F JSR absolute_value ; A = abs(A)
ROM1:A350 CMP #$E
ROM1:A351 BCS loc_11A37D
ROM1:A352 LDY #1
ROM1:A353 LDA object_x
ROM1:A354 CMP object_x,X
ROM1:A355 BEQ loc_11A37D
ROM1:A356 BCS loc_11A366
ROM1:A357 LDY #2
 
ROM1:A366 loc_11A366:
ROM1:A366 LDA object_x,X
 
ROM1:A368 loc_11A368:
ROM1:A368 STA enemy_state_11,X
ROM1:A369 TYA
ROM1:A36A STA object_direction,X
ROM1:A36B AND locret_11A343,X
ROM1:A36C BEQ loc_11A37A
ROM1:A36D INC walk_state_and_weapon_state,X
ROM1:A36E LDA #$70
ROM1:A36F STA object_walk_speed,X
 
ROM1:A37A loc_11A37A:
ROM1:A37A JMP loc_11A3EB
 
ROM1:A37D loc_11A37D:
ROM1:A37D LDA object_x
ROM1:A37E SEC
ROM1:A37F SBC object_x,X
ROM1:A380 JSR absolute_value ; A = abs(A)
ROM1:A381 CMP #$E
ROM1:A382 BCS loc_11A37A
ROM1:A383 LDY #4
ROM1:A384 LDA object_y
ROM1:A385 CMP object_y,X
ROM1:A386 BEQ loc_11A37A
ROM1:A387 BCS loc_11A395
ROM1:A388 LDY #8
 
ROM1:A395 loc_11A395:
ROM1:A395 LDA object_y,X
ROM1:A396 BNE loc_11A368
 
ROM1:A399 loc_11A399:
ROM1:A399 LDA object_direction,X
ROM1:A39A STA var_15
ROM1:A39B JSR process_movement
ROM1:A39C LDA object_tile_offset_whole,X
ROM1:A39D AND #$F
ROM1:A39E BNE loc_11A3AA
ROM1:A39F STA object_tile_offset_whole,X
 
ROM1:A3AA loc_11A3AA: ; Check if Link was hit by an enemy. X is the enemy we're
ROM1:A3AA JSR check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM1:A3AB LDY object_x,X
ROM1:A3AC LDA #$78
ROM1:A3AD STA var_0
ROM1:A3AE LDA object_direction,X
ROM1:A3AF AND #$C
ROM1:A3B0 BEQ loc_11A3BF
ROM1:A3B1 LDY object_y,X
ROM1:A3B2 LDA #$90
ROM1:A3B3 STA var_0
 
ROM1:A3BF loc_11A3BF:
ROM1:A3BF LDA walk_state_and_weapon_state,X
ROM1:A3C0 AND #1
ROM1:A3C1 BEQ loc_11A3E1
ROM1:A3C2 TYA
ROM1:A3C3 SEC
ROM1:A3C4 SBC var_0
ROM1:A3C5 JSR absolute_value ; A = abs(A)
ROM1:A3C6 CMP #5
ROM1:A3C7 BCS loc_11A3DE
ROM1:A3C8 LDA object_direction,X
ROM1:A3C9 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM1:A3CA STA object_direction,X
ROM1:A3CB LDA #$20
ROM1:A3CC STA object_walk_speed,X
ROM1:A3CD INC walk_state_and_weapon_state,X
 
ROM1:A3DE loc_11A3DE:
ROM1:A3DE JMP loc_11A3EB
 
ROM1:A3E1 loc_11A3E1:
ROM1:A3E1 TYA
ROM1:A3E2 CMP enemy_state_11,X
ROM1:A3E3 BNE loc_11A3EB
ROM1:A3E4 LDA #0
ROM1:A3E5 STA walk_state_and_weapon_state,X
 
ROM1:A3EB loc_11A3EB:
ROM1:A3EB JMP loc_1079BA
 
Function chunk for update_monster_10_rupee
ROM1:A3EC update_monster_10_rupee_main: ; Push X.
ROM1:A3EC TXA
ROM1:A3ED PHA
ROM1:A3EE LDA object_y ; Compare Link's Y position to our Y position.
ROM1:A3EF SEC
ROM1:A3F0 SBC object_y,X
ROM1:A3F1 JSR absolute_value ; A = abs(A)
ROM1:A3F2 CMP #9
ROM1:A3F3 BCS too_far
ROM1:A3F4 LDA object_x ; Compare Link's X position to our Y position.
ROM1:A3F5 SEC
ROM1:A3F6 SBC object_x,X
ROM1:A3F7 JSR absolute_value ; A = abs(A)
ROM1:A3F8 CMP #9
ROM1:A3F9 BCS too_far
ROM1:A3FA JSR pick_up_rupee ; Play the rupee sound and add 1 to the pending rupee count.
ROM1:A3FB JSR delete_enemy ; We've been picked up, so delete ourself.
ROM1:A3FC LDA #0
ROM1:A3FD STA total_enemies_spawned_in_room ; Set to 0.
ROM1:A3FE JMP ret
 
ROM1:A3FF too_far: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM1:A3FF JSR set_var_0_to_object_position
ROM1:A400 LDX #$16
ROM1:A401 LDY #$16
ROM1:A402 JSR update_inventory_item_sprite
 
ROM1:A403 ret: ; Restore X.
ROM1:A403 PLA
ROM1:A404 TAX
ROM1:A405 RTS
 
ROM1:A406 Skipped empty chunk
ROM1:A500 sram_code_start: .BYTE $A9 ; Data from here to sram_code_end is copied to 0x6C90
  ; (SRAMCODE) at runtime. The original code is omitted here.
ROM1:A501 Skipped empty chunk
ROM1:B870 sram_code_end: .BYTE $FF
ROM1:B871 Skipped empty chunk
 
Subroutine rom1_OnReset
ROM1:BF50 rom1_OnReset:
ROM1:BF50 SEI
ROM1:BF51 CLD
ROM1:BF52 LDA #0
ROM1:BF53 STA PPUCTRL
ROM1:BF54 LDX #$FF
ROM1:BF55 TXS
 
ROM1:BF5A loc_11BF5A:
ROM1:BF5A LDA PPUSTATUS
ROM1:BF5B AND #$80
ROM1:BF5C BEQ loc_11BF5A
 
ROM1:BF61 loc_11BF61:
ROM1:BF61 LDA PPUSTATUS
ROM1:BF62 AND #$80
ROM1:BF63 BEQ loc_11BF61
ROM1:BF64 ORA #$FF
ROM1:BF65 STA text_ptr_tbl
ROM1:BF66 STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF67 STA $C000
ROM1:BF68 STA $E000
ROM1:BF69 LDA #$F
ROM1:BF6A JSR rom1_set_mmc_control_register
ROM1:BF6B LDA #0
ROM1:BF6C STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF6D LSR A
ROM1:BF6E STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF6F LSR A
ROM1:BF70 STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF71 LSR A
ROM1:BF72 STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF73 LSR A
ROM1:BF74 STA create_recorder_whirlwind_at_A ; Create a whistle whirlwind at Y = A. This is done when
  ; creating the whirlwind after warping into the new screen.
ROM1:BF75 LDA #7
ROM1:BF76 JSR rom1_set_prg_bank
ROM1:BF77 JMP continue_setup
 
Subroutine rom1_set_mmc_control_register
ROM1:BF98 rom1_set_mmc_control_register:
ROM1:BF98 STA text_ptr_tbl
ROM1:BF99 LSR A
ROM1:BF9A STA text_ptr_tbl
ROM1:BF9B LSR A
ROM1:BF9C STA text_ptr_tbl
ROM1:BF9D LSR A
ROM1:BF9E STA text_ptr_tbl
ROM1:BF9F LSR A
ROM1:BFA0 STA text_ptr_tbl
ROM1:BFA1 RTS
 
Subroutine rom1_set_prg_bank
ROM1:BFAC rom1_set_prg_bank:
ROM1:BFAC STA $E000
ROM1:BFAD LSR A
ROM1:BFAE STA $E000
ROM1:BFAF LSR A
ROM1:BFB0 STA $E000
ROM1:BFB1 LSR A
ROM1:BFB2 STA $E000
ROM1:BFB3 LSR A
ROM1:BFB4 STA $E000
ROM1:BFB5 RTS
 
ROM1:BFB6 Skipped empty chunk
 
Segment: RAM2
 
Segment: ROM2
ROM2:8000 rom2_sprite_data_ptrs: .WORD rom2_sprite_data_0
ROM2:8002   .WORD rom2_sprite_data_1
ROM2:8004   .WORD rom2_sprite_data_2
ROM2:8006 rom2_sprite_data_size: .WORD 7 ; These are stored backwards (wrong endian), and are actually
  ; 0x0700, 0x0700 and 0x00E0.
ROM2:8008   .WORD 7
ROM2:800A   .WORD $E000
ROM2:800C rom2_sprite_data_ppu_addresses: .WORD 0
ROM2:800E   .WORD $10
ROM2:8010   .WORD $201F
 
Subroutine setup_rom2_sprite_data
; Copy a block of sprite data to the PPU.
ROM2:8012 setup_rom2_sprite_data:
ROM2:8012 JSR clear_ppumask
ROM2:8013 LDA PPUSTATUS
 
ROM2:8014 loop: ; 0 at start
ROM2:8014 LDA usually_zero
ROM2:8015 ASL A ; A << 1, since we're indexing 16-bit tables
ROM2:8016 TAX
ROM2:8017 LDA rom2_sprite_data_ptrs,X
ROM2:8018 STA var_0
ROM2:8019 LDA rom2_sprite_data_size,X
ROM2:801A STA var_2
ROM2:801B LDA rom2_sprite_data_ppu_addresses,X
ROM2:801C STA PPUADDR ; PPU address high byte
ROM2:801D INX
ROM2:801E LDA rom2_sprite_data_ptrs,X
ROM2:801F STA var_1
ROM2:8020 LDA rom2_sprite_data_size,X
ROM2:8021 STA var_3
ROM2:8022 LDA rom2_sprite_data_ppu_addresses,X ; PPU address low byte
ROM2:8023 JSR copy_sprite_data_1 ; var_0 = pointer to data to copy
  ; var_2 = number of bytes to copy (16-bit)
ROM2:8024 LDA usually_zero
ROM2:8025 CMP #3 ; Write 3 blocks of data to the PPU.
ROM2:8026 BNE loop
ROM2:8027 LDA #$5A
ROM2:8028 STA sprite_data_1_initialized ; Set to 0x5A. This signals the title menu that this is already
  ; set up and doesn't need to be done again.
ROM2:8029 LDA #0
ROM2:802A STA usually_zero ; Set to 0.
ROM2:802B RTS
 
Subroutine copy_sprite_data_1
; var_0 = pointer to data to copy ; var_2 = number of bytes to copy (16-bit)
ROM2:804F copy_sprite_data_1:
ROM2:804F STA PPUADDR
ROM2:8050 LDY #0
 
ROM2:8051 loop: ; Read a byte of sprite data
ROM2:8051 LDA (var_0),Y
ROM2:8052 STA PPUDATA ; Write a byte of sprite data
ROM2:8053 LDA var_0 ; Source ptr low byte++
ROM2:8054 CLC
ROM2:8055 ADC #1
ROM2:8056 STA var_0
ROM2:8057 LDA var_1 ; Carry into source ptr high byte
ROM2:8058 ADC #0
ROM2:8059 STA var_1
ROM2:805A LDA var_3 ; Decrement 16-bit bytes left
ROM2:805B SEC
ROM2:805C SBC #1
ROM2:805D STA var_3
ROM2:805E LDA var_2
ROM2:805F SBC #0
ROM2:8060 STA var_2
ROM2:8061 LDA var_2
ROM2:8062 BNE loop ; Loop if var_2/var_3 != 0
ROM2:8063 LDA var_3
ROM2:8064 BNE loop
ROM2:8065 INC usually_zero
ROM2:8066 RTS
 
ROM2:807F rom2_sprite_data_0:
ROM2:877F rom2_sprite_data_1:
ROM2:8E7F rom2_sprite_data_2:
Function chunk for task0_Title
ROM2:8E7F task0_title_continue:
ROM2:8E7F JSR clear_ppumask
ROM2:8E80 LDA enemy_state_4
ROM2:8E81 BNE loc_9014
ROM2:8E82 LDA enemy_state_4_1
ROM2:8E83 JSR call_jump_table
 
ROM2:8E84   .WORD task0_Title_Splash_0
ROM2:8E86   .WORD task0_Title_Splash_1
ROM2:8E88   .WORD task0_Title_Splash_2
 
ROM2:9014 loc_9014:
ROM2:9014 LDA enemy_state_4_1
ROM2:9015 JSR call_jump_table
 
ROM2:9016   .WORD task0_Title_Splash_0
ROM2:9018   .WORD task0_intro_text_1
ROM2:901A   .WORD task0_intro_text_2
 
Subroutine task1_Title
ROM2:9020 task1_Title:
ROM2:9020 LDA task_state
ROM2:9021 BNE run_task
ROM2:9022 LDA already_exited_title_screen ; If true, we've exited from the title screen to the main menu
  ; at least once. Once this is true, the title menu will auto-
  ; advance to the main menu in the future if we end up back in
  ; that state (eg. after exiting the create save menu) instead
  ; of showing the title screen again.
ROM2:9023 BNE run_task
ROM2:9024 JSR task1_Title_splash
ROM2:9025 LDA active_game_mode_task ; Load to re-check that we're in task 1.
ROM2:9026 BEQ locret_905C ; Exit if the active task is 0. I'm not sure how it would
  ; be 0, since task1 is called when it's 1.
 
ROM2:9027 run_task:
ROM2:9027 LDA task_state
ROM2:9028 JSR call_jump_table
 
ROM2:9029   .WORD task1_Title_state_0
ROM2:902B   .WORD task0_MainMenu_0_and_task1_Title_state_1
ROM2:902D   .WORD task1_Title_state_2
 
Subroutine task1_Title_state_0
ROM2:903B task1_Title_state_0:
ROM2:903B LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:903C AND #ControllerBits_Start
ROM2:903D BEQ locret_905C
ROM2:903E STA sprite_data_2_initialized ; Set to controller_1_pressed & ControllerBits_Start.
  ; I'm not sure what this is for. This would cause the
  ; second main block of sprite data to be reinitialized
  ; if we reached the title menu again, but that could be
  ; done by simply setting this to 0.
ROM2:903F LDA #0
ROM2:9040 STA play_music ; Set to 0
ROM2:9041 JSR stop_sounds
ROM2:9042 LDA #$5A
ROM2:9043 STA already_exited_title_screen ; Remember that we've exited from the title screen to the main
  ; menu. Once we exit the title screen once, we always skip to
  ; it if we end up in the title screen state, instead of showing
  ; the title screen.
ROM2:9044 INC task_state ; Set to 1
ROM2:9045 JSR clear_ppumask
ROM2:9046 JSR clear_oam ; Clear the OAM buffer.
ROM2:9047 LDA #$12
ROM2:9048 STA current_ppu_command_index ; Set PPUCommandIndices_MainMenu_1.
 
ROM2:905C locret_905C:
ROM2:905C RTS
 
Subroutine task1_Title_state_2
ROM2:905D task1_Title_state_2:
ROM2:905D JSR clear_ppumask
ROM2:905E LDA #0
ROM2:905F STA current_save_slot
ROM2:9060 JSR sub_106DF1
ROM2:9061 LDY #2
 
ROM2:9069 loc_9069:
ROM2:9069 LDA (var_6),Y
ROM2:906A STA byte_633,Y
ROM2:906B BNE loc_9083
ROM2:906C TYA
ROM2:906D PHA
ROM2:906E STY current_save_slot
ROM2:906F JSR sub_106DF1
ROM2:9070 JSR sub_A35D
ROM2:9071 LDA #0
ROM2:9072 STA current_save_slot
ROM2:9073 JSR sub_106DF1
ROM2:9074 PLA
ROM2:9075 TAY
 
ROM2:9083 loc_9083:
ROM2:9083 LDA (var_10),Y
ROM2:9084 STA deaths_per_save_slot,Y
ROM2:9085 LDA (var_12),Y
ROM2:9086 STA quest_no,Y
ROM2:9087 DEY
ROM2:9088 BPL loc_9069
ROM2:9089 LDY #$18
ROM2:908A LDX #0
 
ROM2:9094 loc_9094:
ROM2:9094 LDA (0),Y
ROM2:9095 PHA
ROM2:9096 TXA
ROM2:9097 LSR A
ROM2:9098 BCS loc_90A7
ROM2:9099 PLA
ROM2:909A AND #$F0
ROM2:909B STA var_12
ROM2:909C LSR A
ROM2:909D LSR A
ROM2:909E LSR A
ROM2:909F LSR A
ROM2:90A0 ORA var_12
ROM2:90A1 PHA
 
ROM2:90A7 loc_90A7:
ROM2:90A7 PLA
ROM2:90A8 STA saved_hearts_slot_0,X
ROM2:90A9 INY
ROM2:90AA INX
ROM2:90AB CPX #6
ROM2:90AC BEQ loc_90BC
ROM2:90AD TXA
ROM2:90AE LSR A
ROM2:90AF BCS loc_9094
ROM2:90B0 TYA
ROM2:90B1 ADC #$26
ROM2:90B2 TAY
ROM2:90B3 JMP loc_9094
 
ROM2:90BC loc_90BC:
ROM2:90BC LDY #$17
 
ROM2:90BE loc_90BE:
ROM2:90BE LDA (var_4),Y
ROM2:90BF STA byte_638,Y
ROM2:90C0 DEY
ROM2:90C1 BPL loc_90BE
ROM2:90C2 INC game_mode ; Set to GameMode_MainMenu.
ROM2:90C3 LDA #0
ROM2:90C4 STA active_game_mode_task ; Set to 0
ROM2:90C5 STA task_state ; Set to 0
ROM2:90C6 RTS
 
Subroutine task1_Title_splash
ROM2:90CF task1_Title_splash:
ROM2:90CF LDA enemy_state_4 ; Check if we're on the splash or the intro text. 0 is the
  ; splash screen, 1 is the intro scroll.
ROM2:90D0 BNE main_Title_intro_text ; Branch if the screen state isn't 0 (we're on the intro text)
ROM2:90D1 LDA enemy_state_4_1
ROM2:90D2 JSR call_jump_table
 
ROM2:90D3   .WORD title_splash_main
ROM2:90D5   .WORD title_splash_fading ; This updates the palette for the title screen fading
  ; out, and keeps updating the waterfall sprites.
 
ROM2:90D7 main_Title_intro_text:
ROM2:90D7 LDA enemy_state_4_1
ROM2:90D8 JSR call_jump_table
 
ROM2:90D9   .WORD intro_text_first_scroll
ROM2:90DB   .WORD intro_text_pause_for_big_text
ROM2:90DD   .WORD intro_text_item_scroll
ROM2:90DF   .WORD intro_text_end_pause
ROM2:90EC off_90EC: .WORD intro_text_finish
 
ROM2:90EE
ROM2:915E byte_915E:
ROM2:9268 byte_9268: .BYTE $44
ROM2:9269 byte_9269: .BYTE $AC
ROM2:926A byte_926A: .BYTE $E0
ROM2:926B   .BYTE $E2
ROM2:926C   .BYTE $EC
ROM2:926D   .BYTE $EE
ROM2:926E   .BYTE $F8
ROM2:926F   .BYTE $FA
ROM2:9270   .BYTE $E4
ROM2:9271   .BYTE $E6
ROM2:9272   .BYTE $F0
ROM2:9273   .BYTE $F2
ROM2:9274   .BYTE $FC
ROM2:9275   .BYTE $FE
ROM2:9276   .BYTE $E8
ROM2:9277   .BYTE $EA
ROM2:9278   .BYTE $F4
ROM2:9279   .BYTE $F6
ROM2:927A   .BYTE $DC
ROM2:927B   .BYTE $DE
ROM2:927C   .BYTE 0
ROM2:927D   .BYTE 0
ROM2:927E   .BYTE $78
ROM2:927F   .BYTE $78
ROM2:9280   .BYTE 0
ROM2:9281   .BYTE 0
ROM2:9282 byte_9282: .BYTE 0
ROM2:9283   .BYTE 0
ROM2:9284   .BYTE 0
ROM2:9285   .BYTE 0
ROM2:9286   .BYTE 0
ROM2:9287   .BYTE 0
ROM2:9288   .BYTE 0
ROM2:9289   .BYTE 0
ROM2:928A   .BYTE 0
ROM2:928B   .BYTE 0
ROM2:928C   .BYTE 0
ROM2:928D   .BYTE 0
ROM2:928E   .BYTE 0
ROM2:928F   .BYTE 0
ROM2:9290   .BYTE 0
ROM2:9291   .BYTE 0
ROM2:9292   .BYTE 0
ROM2:9293   .BYTE 0
ROM2:9294   .BYTE 0
ROM2:9295   .BYTE 0
ROM2:9296   .BYTE 0
ROM2:9297   .BYTE $40
ROM2:9298   .BYTE 0
ROM2:9299   .BYTE 0
ROM2:929A intro_text_item_scroll_ppu_command_00: .BYTE 0
ROM2:929B   .BYTE $E4
ROM2:929C   .BYTE $E5
ROM2:929D   .BYTE $E4
ROM2:929E   .BYTE $E5
ROM2:929F   .BYTE $E4
ROM2:92A0   .BYTE $E5
ROM2:92A1   .BYTE $E6
ROM2:92A2   .BYTE $24
ROM2:92A3   .BYTE $A
ROM2:92A4   .BYTE $15
ROM2:92A5   .BYTE $15
ROM2:92A6   .BYTE $24
ROM2:92A7   .BYTE $18
ROM2:92A8   .BYTE $F
ROM2:92A9   .BYTE $24
ROM2:92AA   .BYTE $1D
ROM2:92AB   .BYTE $1B
ROM2:92AC   .BYTE $E
ROM2:92AD   .BYTE $A
ROM2:92AE   .BYTE $1C
ROM2:92AF   .BYTE $1E
ROM2:92B0   .BYTE $1B
ROM2:92B1   .BYTE $E
ROM2:92B2   .BYTE $1C
ROM2:92B3   .BYTE $24
ROM2:92B4   .BYTE $E6
ROM2:92B5   .BYTE $E4
ROM2:92B6   .BYTE $E5
ROM2:92B7   .BYTE $E4
ROM2:92B8   .BYTE $E5
ROM2:92B9   .BYTE $E4
ROM2:92BA   .BYTE $E5
ROM2:92BB   .BYTE $FF
ROM2:92BC intro_text_item_scroll_ppu_command_01: .BYTE 7
ROM2:92BD   .BYTE $11
ROM2:92BE   .BYTE $E
ROM2:92BF   .BYTE $A
ROM2:92C0   .BYTE $1B
ROM2:92C1   .BYTE $1D
ROM2:92C2   .BYTE $24
ROM2:92C3   .BYTE $24
ROM2:92C4   .BYTE $24
ROM2:92C5   .BYTE $24
ROM2:92C6   .BYTE $24
ROM2:92C7   .BYTE $C
ROM2:92C8   .BYTE $18
ROM2:92C9   .BYTE $17
ROM2:92CA   .BYTE $1D
ROM2:92CB   .BYTE $A
ROM2:92CC   .BYTE $12
ROM2:92CD   .BYTE $17
ROM2:92CE   .BYTE $E
ROM2:92CF   .BYTE $1B
ROM2:92D0   .BYTE $FF
ROM2:92D1 intro_text_item_scroll_ppu_command_02: .BYTE $14
ROM2:92D2   .BYTE $11
ROM2:92D3   .BYTE $E
ROM2:92D4   .BYTE $A
ROM2:92D5   .BYTE $1B
ROM2:92D6   .BYTE $1D
ROM2:92D7   .BYTE $FF
ROM2:92D8 intro_text_item_scroll_ppu_command_03: .BYTE 7
ROM2:92D9   .BYTE $F
ROM2:92DA   .BYTE $A
ROM2:92DB   .BYTE $12
ROM2:92DC   .BYTE $1B
ROM2:92DD   .BYTE $22
ROM2:92DE   .BYTE $24
ROM2:92DF   .BYTE $24
ROM2:92E0   .BYTE $24
ROM2:92E1   .BYTE $24
ROM2:92E2   .BYTE $24
ROM2:92E3   .BYTE $24
ROM2:92E4   .BYTE $24
ROM2:92E5   .BYTE $24
ROM2:92E6   .BYTE $C
ROM2:92E7   .BYTE $15
ROM2:92E8   .BYTE $18
ROM2:92E9   .BYTE $C
ROM2:92EA   .BYTE $14
ROM2:92EB   .BYTE $FF
ROM2:92EC intro_text_item_scroll_ppu_command_04: .BYTE 7
ROM2:92ED   .BYTE $1B
ROM2:92EE   .BYTE $1E
ROM2:92EF   .BYTE $19
ROM2:92F0   .BYTE $22
ROM2:92F1   .BYTE $24
ROM2:92F2   .BYTE $24
ROM2:92F3   .BYTE $24
ROM2:92F4   .BYTE $24
ROM2:92F5   .BYTE $24
ROM2:92F6   .BYTE $24
ROM2:92F7   .BYTE $24
ROM2:92F8   .BYTE 5
ROM2:92F9   .BYTE $24
ROM2:92FA   .BYTE $1B
ROM2:92FB   .BYTE $1E
ROM2:92FC   .BYTE $19
ROM2:92FD   .BYTE $12
ROM2:92FE   .BYTE $E
ROM2:92FF   .BYTE $1C
ROM2:9300   .BYTE $FF
ROM2:9301 intro_text_item_scroll_ppu_command_07: .BYTE 7
ROM2:9302   .BYTE $1C
ROM2:9303   .BYTE $20
ROM2:9304   .BYTE $18
ROM2:9305   .BYTE $1B
ROM2:9306   .BYTE $D
ROM2:9307   .BYTE $24
ROM2:9308   .BYTE $24
ROM2:9309   .BYTE $24
ROM2:930A   .BYTE $24
ROM2:930B   .BYTE $24
ROM2:930C   .BYTE $24
ROM2:930D   .BYTE $24
ROM2:930E   .BYTE $24
ROM2:930F   .BYTE $20
ROM2:9310   .BYTE $11
ROM2:9311   .BYTE $12
ROM2:9312   .BYTE $1D
ROM2:9313   .BYTE $E
ROM2:9314   .BYTE $FF
ROM2:9315 intro_text_item_scroll_ppu_command_08: .BYTE $14
ROM2:9316   .BYTE $1C
ROM2:9317   .BYTE $20
ROM2:9318   .BYTE $18
ROM2:9319   .BYTE $1B
ROM2:931A   .BYTE $D
ROM2:931B   .BYTE $FF
ROM2:931C intro_text_item_scroll_ppu_command_09: .BYTE 6
ROM2:931D   .BYTE $16
ROM2:931E   .BYTE $A
ROM2:931F   .BYTE $10
ROM2:9320   .BYTE $12
ROM2:9321   .BYTE $C
ROM2:9322   .BYTE $A
ROM2:9323   .BYTE $15
ROM2:9324   .BYTE $24
ROM2:9325   .BYTE $24
ROM2:9326   .BYTE $24
ROM2:9327   .BYTE $24
ROM2:9328   .BYTE $24
ROM2:9329   .BYTE $24
ROM2:932A   .BYTE $16
ROM2:932B   .BYTE $A
ROM2:932C   .BYTE $10
ROM2:932D   .BYTE $12
ROM2:932E   .BYTE $C
ROM2:932F   .BYTE $A
ROM2:9330   .BYTE $15
ROM2:9331   .BYTE $FF
ROM2:9332 intro_text_item_scroll_ppu_command_0A: .BYTE 7
ROM2:9333   .BYTE $1C
ROM2:9334   .BYTE $20
ROM2:9335   .BYTE $18
ROM2:9336   .BYTE $1B
ROM2:9337   .BYTE $D
ROM2:9338   .BYTE $24
ROM2:9339   .BYTE $24
ROM2:933A   .BYTE $24
ROM2:933B   .BYTE $24
ROM2:933C   .BYTE $24
ROM2:933D   .BYTE $24
ROM2:933E   .BYTE $24
ROM2:933F   .BYTE $24
ROM2:9340   .BYTE $1C
ROM2:9341   .BYTE $11
ROM2:9342   .BYTE $12
ROM2:9343   .BYTE $E
ROM2:9344   .BYTE $15
ROM2:9345   .BYTE $D
ROM2:9346   .BYTE $FF
ROM2:9347 intro_text_item_scroll_ppu_command_0B: .BYTE 5
ROM2:9348   .BYTE $B
ROM2:9349   .BYTE $18
ROM2:934A   .BYTE $18
ROM2:934B   .BYTE $16
ROM2:934C   .BYTE $E
ROM2:934D   .BYTE $1B
ROM2:934E   .BYTE $A
ROM2:934F   .BYTE $17
ROM2:9350   .BYTE $10
ROM2:9351   .BYTE $24
ROM2:9352   .BYTE $24
ROM2:9353   .BYTE $24
ROM2:9354   .BYTE $24
ROM2:9355   .BYTE $24
ROM2:9356   .BYTE $16
ROM2:9357   .BYTE $A
ROM2:9358   .BYTE $10
ROM2:9359   .BYTE $12
ROM2:935A   .BYTE $C
ROM2:935B   .BYTE $A
ROM2:935C   .BYTE $15
ROM2:935D   .BYTE $FF
ROM2:935E intro_text_item_scroll_ppu_command_0C: .BYTE $12
ROM2:935F   .BYTE $B
ROM2:9360   .BYTE $18
ROM2:9361   .BYTE $18
ROM2:9362   .BYTE $16
ROM2:9363   .BYTE $E
ROM2:9364   .BYTE $1B
ROM2:9365   .BYTE $A
ROM2:9366   .BYTE $17
ROM2:9367   .BYTE $10
ROM2:9368   .BYTE $FF
ROM2:9369 intro_text_item_scroll_ppu_command_0D: .BYTE 7
ROM2:936A   .BYTE $B
ROM2:936B   .BYTE $18
ROM2:936C   .BYTE $16
ROM2:936D   .BYTE $B
ROM2:936E   .BYTE $24
ROM2:936F   .BYTE $24
ROM2:9370   .BYTE $24
ROM2:9371   .BYTE $24
ROM2:9372   .BYTE $24
ROM2:9373   .BYTE $24
ROM2:9374   .BYTE $24
ROM2:9375   .BYTE $24
ROM2:9376   .BYTE $24
ROM2:9377   .BYTE $24
ROM2:9378   .BYTE $B
ROM2:9379   .BYTE $18
ROM2:937A   .BYTE $20
ROM2:937B   .BYTE $FF
ROM2:937C intro_text_item_scroll_ppu_command_0E: .BYTE 7
ROM2:937D   .BYTE $A
ROM2:937E   .BYTE $1B
ROM2:937F   .BYTE $1B
ROM2:9380   .BYTE $18
ROM2:9381   .BYTE $20
ROM2:9382   .BYTE $24
ROM2:9383   .BYTE $24
ROM2:9384   .BYTE $24
ROM2:9385   .BYTE $24
ROM2:9386   .BYTE $24
ROM2:9387   .BYTE $24
ROM2:9388   .BYTE $24
ROM2:9389   .BYTE $24
ROM2:938A   .BYTE $1C
ROM2:938B   .BYTE $12
ROM2:938C   .BYTE $15
ROM2:938D   .BYTE $1F
ROM2:938E   .BYTE $E
ROM2:938F   .BYTE $1B
ROM2:9390   .BYTE $FF
ROM2:9391 intro_text_item_scroll_ppu_command_0F: .BYTE $14
ROM2:9392   .BYTE $A
ROM2:9393   .BYTE $1B
ROM2:9394   .BYTE $1B
ROM2:9395   .BYTE $18
ROM2:9396   .BYTE $20
ROM2:9397   .BYTE $FF
ROM2:9398 intro_text_item_scroll_ppu_command_10: .BYTE 7
ROM2:9399   .BYTE $B
ROM2:939A   .BYTE $15
ROM2:939B   .BYTE $1E
ROM2:939C   .BYTE $E
ROM2:939D   .BYTE $24
ROM2:939E   .BYTE $24
ROM2:939F   .BYTE $24
ROM2:93A0   .BYTE $24
ROM2:93A1   .BYTE $24
ROM2:93A2   .BYTE $24
ROM2:93A3   .BYTE $24
ROM2:93A4   .BYTE $24
ROM2:93A5   .BYTE $24
ROM2:93A6   .BYTE $24
ROM2:93A7   .BYTE $1B
ROM2:93A8   .BYTE $E
ROM2:93A9   .BYTE $D
ROM2:93AA   .BYTE $FF
ROM2:93AB intro_text_item_scroll_ppu_command_11: .BYTE 6
ROM2:93AC   .BYTE $C
ROM2:93AD   .BYTE $A
ROM2:93AE   .BYTE $17
ROM2:93AF   .BYTE $D
ROM2:93B0   .BYTE $15
ROM2:93B1   .BYTE $E
ROM2:93B2   .BYTE $24
ROM2:93B3   .BYTE $24
ROM2:93B4   .BYTE $24
ROM2:93B5   .BYTE $24
ROM2:93B6   .BYTE $24
ROM2:93B7   .BYTE $24
ROM2:93B8   .BYTE $24
ROM2:93B9   .BYTE $24
ROM2:93BA   .BYTE $C
ROM2:93BB   .BYTE $A
ROM2:93BC   .BYTE $17
ROM2:93BD   .BYTE $D
ROM2:93BE   .BYTE $15
ROM2:93BF   .BYTE $E
ROM2:93C0   .BYTE $FF
ROM2:93C1 intro_text_item_scroll_ppu_command_12: .BYTE 7
ROM2:93C2   .BYTE $B
ROM2:93C3   .BYTE $15
ROM2:93C4   .BYTE $1E
ROM2:93C5   .BYTE $E
ROM2:93C6   .BYTE $24
ROM2:93C7   .BYTE $24
ROM2:93C8   .BYTE $24
ROM2:93C9   .BYTE $24
ROM2:93CA   .BYTE $24
ROM2:93CB   .BYTE $24
ROM2:93CC   .BYTE $24
ROM2:93CD   .BYTE $24
ROM2:93CE   .BYTE $24
ROM2:93CF   .BYTE $24
ROM2:93D0   .BYTE $1B
ROM2:93D1   .BYTE $E
ROM2:93D2   .BYTE $D
ROM2:93D3   .BYTE $FF
ROM2:93D4 intro_text_item_scroll_ppu_command_13: .BYTE 7
ROM2:93D5   .BYTE $1B
ROM2:93D6   .BYTE $12
ROM2:93D7   .BYTE $17
ROM2:93D8   .BYTE $10
ROM2:93D9   .BYTE $24
ROM2:93DA   .BYTE $24
ROM2:93DB   .BYTE $24
ROM2:93DC   .BYTE $24
ROM2:93DD   .BYTE $24
ROM2:93DE   .BYTE $24
ROM2:93DF   .BYTE $24
ROM2:93E0   .BYTE $24
ROM2:93E1   .BYTE $24
ROM2:93E2   .BYTE $24
ROM2:93E3   .BYTE $1B
ROM2:93E4   .BYTE $12
ROM2:93E5   .BYTE $17
ROM2:93E6   .BYTE $10
ROM2:93E7   .BYTE $FF
ROM2:93E8 intro_text_item_scroll_ppu_command_14: .BYTE 7
ROM2:93E9   .BYTE $19
ROM2:93EA   .BYTE $18
ROM2:93EB   .BYTE $20
ROM2:93EC   .BYTE $E
ROM2:93ED   .BYTE $1B
ROM2:93EE   .BYTE $24
ROM2:93EF   .BYTE $24
ROM2:93F0   .BYTE $24
ROM2:93F1   .BYTE $24
ROM2:93F2   .BYTE $24
ROM2:93F3   .BYTE $24
ROM2:93F4   .BYTE $24
ROM2:93F5   .BYTE $1B
ROM2:93F6   .BYTE $E
ROM2:93F7   .BYTE $C
ROM2:93F8   .BYTE $18
ROM2:93F9   .BYTE $1B
ROM2:93FA   .BYTE $D
ROM2:93FB   .BYTE $E
ROM2:93FC   .BYTE $1B
ROM2:93FD   .BYTE $FF
ROM2:93FE intro_text_item_scroll_ppu_command_15: .BYTE 5
ROM2:93FF   .BYTE $B
ROM2:9400   .BYTE $1B
ROM2:9401   .BYTE $A
ROM2:9402   .BYTE $C
ROM2:9403   .BYTE $E
ROM2:9404   .BYTE $15
ROM2:9405   .BYTE $E
ROM2:9406   .BYTE $1D
ROM2:9407   .BYTE $FF
ROM2:9408 intro_text_item_scroll_ppu_command_16: .BYTE 7
ROM2:9409   .BYTE $1B
ROM2:940A   .BYTE $A
ROM2:940B   .BYTE $F
ROM2:940C   .BYTE $1D
ROM2:940D   .BYTE $24
ROM2:940E   .BYTE $24
ROM2:940F   .BYTE $24
ROM2:9410   .BYTE $24
ROM2:9411   .BYTE $24
ROM2:9412   .BYTE $24
ROM2:9413   .BYTE $24
ROM2:9414   .BYTE $1C
ROM2:9415   .BYTE $1D
ROM2:9416   .BYTE $E
ROM2:9417   .BYTE $19
ROM2:9418   .BYTE $15
ROM2:9419   .BYTE $A
ROM2:941A   .BYTE $D
ROM2:941B   .BYTE $D
ROM2:941C   .BYTE $E
ROM2:941D   .BYTE $1B
ROM2:941E   .BYTE $FF
ROM2:941F intro_text_item_scroll_ppu_command_17: .BYTE 6
ROM2:9420   .BYTE $16
ROM2:9421   .BYTE $A
ROM2:9422   .BYTE $10
ROM2:9423   .BYTE $12
ROM2:9424   .BYTE $C
ROM2:9425   .BYTE $A
ROM2:9426   .BYTE $15
ROM2:9427   .BYTE $24
ROM2:9428   .BYTE $24
ROM2:9429   .BYTE $24
ROM2:942A   .BYTE $24
ROM2:942B   .BYTE $24
ROM2:942C   .BYTE $24
ROM2:942D   .BYTE $B
ROM2:942E   .BYTE $18
ROM2:942F   .BYTE $18
ROM2:9430   .BYTE $14
ROM2:9431   .BYTE $24
ROM2:9432   .BYTE $18
ROM2:9433   .BYTE $F
ROM2:9434   .BYTE $FF
ROM2:9435 intro_text_item_scroll_ppu_command_18: .BYTE 8
ROM2:9436   .BYTE $1B
ROM2:9437   .BYTE $18
ROM2:9438   .BYTE $D
ROM2:9439   .BYTE $24
ROM2:943A   .BYTE $24
ROM2:943B   .BYTE $24
ROM2:943C   .BYTE $24
ROM2:943D   .BYTE $24
ROM2:943E   .BYTE $24
ROM2:943F   .BYTE $24
ROM2:9440   .BYTE $24
ROM2:9441   .BYTE $24
ROM2:9442   .BYTE $16
ROM2:9443   .BYTE $A
ROM2:9444   .BYTE $10
ROM2:9445   .BYTE $12
ROM2:9446   .BYTE $C
ROM2:9447   .BYTE $FF
ROM2:9448 intro_text_item_scroll_ppu_command_19: .BYTE 8
ROM2:9449   .BYTE $14
ROM2:944A   .BYTE $E
ROM2:944B   .BYTE $22
ROM2:944C   .BYTE $24
ROM2:944D   .BYTE $24
ROM2:944E   .BYTE $24
ROM2:944F   .BYTE $24
ROM2:9450   .BYTE $24
ROM2:9451   .BYTE $24
ROM2:9452   .BYTE $24
ROM2:9453   .BYTE $24
ROM2:9454   .BYTE $16
ROM2:9455   .BYTE $A
ROM2:9456   .BYTE $10
ROM2:9457   .BYTE $12
ROM2:9458   .BYTE $C
ROM2:9459   .BYTE $A
ROM2:945A   .BYTE $15
ROM2:945B   .BYTE $FF
ROM2:945C intro_text_item_scroll_ppu_command_1A: .BYTE $15
ROM2:945D   .BYTE $14
ROM2:945E   .BYTE $E
ROM2:945F   .BYTE $22
ROM2:9460   .BYTE $FF
ROM2:9461 intro_text_item_scroll_ppu_command_1B: .BYTE 8
ROM2:9462   .BYTE $16
ROM2:9463   .BYTE $A
ROM2:9464   .BYTE $19
ROM2:9465   .BYTE $24
ROM2:9466   .BYTE $24
ROM2:9467   .BYTE $24
ROM2:9468   .BYTE $24
ROM2:9469   .BYTE $24
ROM2:946A   .BYTE $24
ROM2:946B   .BYTE $24
ROM2:946C   .BYTE $24
ROM2:946D   .BYTE $C
ROM2:946E   .BYTE $18
ROM2:946F   .BYTE $16
ROM2:9470   .BYTE $19
ROM2:9471   .BYTE $A
ROM2:9472   .BYTE $1C
ROM2:9473   .BYTE $1C
ROM2:9474   .BYTE $FF
ROM2:9475 intro_text_item_scroll_ppu_command_1C: .BYTE $C
ROM2:9476   .BYTE $1D
ROM2:9477   .BYTE $1B
ROM2:9478   .BYTE $12
ROM2:9479   .BYTE $F
ROM2:947A   .BYTE $18
ROM2:947B   .BYTE $1B
ROM2:947C   .BYTE $C
ROM2:947D   .BYTE $E
ROM2:947E   .BYTE $FF
ROM2:947F intro_text_item_scroll_ppu_command_05: .BYTE 4
ROM2:9480   .BYTE $15
ROM2:9481   .BYTE $12
ROM2:9482   .BYTE $F
ROM2:9483   .BYTE $E
ROM2:9484   .BYTE $24
ROM2:9485   .BYTE $19
ROM2:9486   .BYTE $18
ROM2:9487   .BYTE $1D
ROM2:9488   .BYTE $12
ROM2:9489   .BYTE $18
ROM2:948A   .BYTE $17
ROM2:948B   .BYTE $24
ROM2:948C   .BYTE $24
ROM2:948D   .BYTE $24
ROM2:948E   .BYTE 2
ROM2:948F   .BYTE $17
ROM2:9490   .BYTE $D
ROM2:9491   .BYTE $24
ROM2:9492   .BYTE $19
ROM2:9493   .BYTE $18
ROM2:9494   .BYTE $1D
ROM2:9495   .BYTE $12
ROM2:9496   .BYTE $18
ROM2:9497   .BYTE $17
ROM2:9498   .BYTE $FF
ROM2:9499 intro_text_item_scroll_ppu_command_06: .BYTE 6
ROM2:949A   .BYTE $15
ROM2:949B   .BYTE $E
ROM2:949C   .BYTE $1D
ROM2:949D   .BYTE $1D
ROM2:949E   .BYTE $E
ROM2:949F   .BYTE $1B
ROM2:94A0   .BYTE $24
ROM2:94A1   .BYTE $24
ROM2:94A2   .BYTE $24
ROM2:94A3   .BYTE $24
ROM2:94A4   .BYTE $24
ROM2:94A5   .BYTE $24
ROM2:94A6   .BYTE $24
ROM2:94A7   .BYTE $24
ROM2:94A8   .BYTE $F
ROM2:94A9   .BYTE $18
ROM2:94AA   .BYTE $18
ROM2:94AB   .BYTE $D
ROM2:94AC   .BYTE $FF
ROM2:94AD intro_text_item_scroll_ppu_command_table: .WORD intro_text_item_scroll_ppu_command_00
ROM2:94AF   .WORD intro_text_item_scroll_ppu_command_01
ROM2:94B1   .WORD intro_text_item_scroll_ppu_command_02
ROM2:94B3   .WORD intro_text_item_scroll_ppu_command_03
ROM2:94B5   .WORD intro_text_item_scroll_ppu_command_04
ROM2:94B7   .WORD intro_text_item_scroll_ppu_command_05
ROM2:94B9   .WORD intro_text_item_scroll_ppu_command_06
ROM2:94BB   .WORD intro_text_item_scroll_ppu_command_07
ROM2:94BD   .WORD intro_text_item_scroll_ppu_command_08
ROM2:94BF   .WORD intro_text_item_scroll_ppu_command_09
ROM2:94C1   .WORD intro_text_item_scroll_ppu_command_0A
ROM2:94C3   .WORD intro_text_item_scroll_ppu_command_0B
ROM2:94C5   .WORD intro_text_item_scroll_ppu_command_0C
ROM2:94C7   .WORD intro_text_item_scroll_ppu_command_0D
ROM2:94C9   .WORD intro_text_item_scroll_ppu_command_0E
ROM2:94CB   .WORD intro_text_item_scroll_ppu_command_0F
ROM2:94CD   .WORD intro_text_item_scroll_ppu_command_10
ROM2:94CF   .WORD intro_text_item_scroll_ppu_command_11
ROM2:94D1   .WORD intro_text_item_scroll_ppu_command_12
ROM2:94D3   .WORD intro_text_item_scroll_ppu_command_13
ROM2:94D5   .WORD intro_text_item_scroll_ppu_command_14
ROM2:94D7   .WORD intro_text_item_scroll_ppu_command_15
ROM2:94D9   .WORD intro_text_item_scroll_ppu_command_16
ROM2:94DB   .WORD intro_text_item_scroll_ppu_command_17
ROM2:94DD   .WORD intro_text_item_scroll_ppu_command_18
ROM2:94DF   .WORD intro_text_item_scroll_ppu_command_19
ROM2:94E1   .WORD intro_text_item_scroll_ppu_command_1A
ROM2:94E3   .WORD intro_text_item_scroll_ppu_command_1B
ROM2:94E5   .WORD intro_text_item_scroll_ppu_command_1C
 
Subroutine task0_Title_Splash_0
ROM2:94E7 task0_Title_Splash_0:
ROM2:94E7 JSR clear_nametables
 
ROM2:94EA title_splash_next_state:
ROM2:94EA INC enemy_state_4_1
ROM2:94EB RTS
 
ROM2:94EE ppu_title_splash_command: .BYTE $3F
ROM2:94EF   .BYTE 0
ROM2:94F0   .BYTE $20
ROM2:94F1   .BYTE $36
ROM2:94F2   .BYTE $F
ROM2:94F3   .BYTE 0
ROM2:94F4   .BYTE $10
ROM2:94F5   .BYTE $36
ROM2:94F6   .BYTE $17
ROM2:94F7   .BYTE $27
ROM2:94F8   .BYTE $F
ROM2:94F9   .BYTE $36
ROM2:94FA   .BYTE 8
ROM2:94FB   .BYTE $1A
ROM2:94FC   .BYTE $28
ROM2:94FD   .BYTE $36
ROM2:94FE   .BYTE $30
ROM2:94FF   .BYTE $3B
ROM2:9500   .BYTE $22
ROM2:9501   .BYTE $36
ROM2:9502   .BYTE $30
ROM2:9503   .BYTE $3B
ROM2:9504   .BYTE $16
ROM2:9505   .BYTE $36
ROM2:9506   .BYTE $17
ROM2:9507   .BYTE $27
ROM2:9508   .BYTE $F
ROM2:9509   .BYTE $36
ROM2:950A   .BYTE 8
ROM2:950B   .BYTE $1A
ROM2:950C   .BYTE $28
ROM2:950D   .BYTE $36
ROM2:950E   .BYTE $30
ROM2:950F   .BYTE $3B
ROM2:9510   .BYTE $22
ROM2:9511   .BYTE $FF
 
Subroutine task0_Title_Splash_1
ROM2:9512 task0_Title_Splash_1:
ROM2:9512 LDX #$23
ROM2:9513 STX ppu_unknown_0 ; Set to 0x23 (the number of bytes in the PPU command)
ROM2:9514 STX ppu_command_buffer_bytes_used ; Set to 0x23 (the number of bytes in the PPU command)
 
ROM2:9515 loop1:
ROM2:9515 LDA ppu_title_splash_command,X
ROM2:9516 STA ppu_command_buffer,X
ROM2:9517 DEX
ROM2:9518 BPL loop1
ROM2:9519 LDX #$A
ROM2:951A LDA #0
ROM2:951B STA enemy_state_4_2
ROM2:951C STA enemy_state_4_3
 
ROM2:951D loop2:
ROM2:951D STA enemy_state_0,X
ROM2:951E STA enemy_projectile_speed_x,X
ROM2:951F STA enemy_state_5,X
ROM2:9520 DEX
ROM2:9521 BPL loop2
ROM2:9522 LDX #$A
 
ROM2:9523 loop3:
ROM2:9523 LDA #$FF
ROM2:9524 STA walk_state_and_weapon_state,X
ROM2:9525 DEX
ROM2:9526 BNE loop3
ROM2:9527 JMP title_splash_next_state
 
Subroutine task0_Title_Splash_2
ROM2:9545 task0_Title_Splash_2:
ROM2:9545 LDA #Music_Title
ROM2:9546 STA play_music ; Play Music_Title
ROM2:9547 LDA #PPUCommandIndices_IntroTextRelated_1
ROM2:9548 JMP task0_Title_Splash_2_sub ; Set to PPUCommandIndices_IntroTextRelated_2 or PPUCommandIndices_IntroTextRelated_1.
 
ROM2:954F ppu_intro_text_command: .BYTE $3F
ROM2:9550   .BYTE 0
ROM2:9551   .BYTE $20
ROM2:9552   .BYTE $F
ROM2:9553   .BYTE $30
ROM2:9554   .BYTE $30
ROM2:9555   .BYTE $30
ROM2:9556   .BYTE $F
ROM2:9557   .BYTE $21
ROM2:9558   .BYTE $30
ROM2:9559   .BYTE $30
ROM2:955A   .BYTE $F
ROM2:955B   .BYTE $16
ROM2:955C   .BYTE $30
ROM2:955D   .BYTE $30
ROM2:955E   .BYTE $F
ROM2:955F   .BYTE $29
ROM2:9560   .BYTE $1A
ROM2:9561   .BYTE 9
ROM2:9562   .BYTE $F
ROM2:9563   .BYTE $29
ROM2:9564   .BYTE $37
ROM2:9565   .BYTE $17
ROM2:9566   .BYTE $F
ROM2:9567   .BYTE 2
ROM2:9568   .BYTE $22
ROM2:9569   .BYTE $30
ROM2:956A   .BYTE $F
ROM2:956B   .BYTE $16
ROM2:956C   .BYTE $27
ROM2:956D   .BYTE $30
ROM2:956E   .BYTE $F
ROM2:956F   .BYTE $B
ROM2:9570   .BYTE $1B
ROM2:9571   .BYTE $2B
ROM2:9572   .BYTE $FF
 
Subroutine task0_intro_text_1
ROM2:9573 task0_intro_text_1:
ROM2:9573 LDX #$23
ROM2:9574 STX ppu_unknown_0 ; Set to 0x23 (the number of bytes in the PPU command)
ROM2:9575 STX ppu_command_buffer_bytes_used ; Set to 0x23 (the number of bytes in the PPU command)
 
ROM2:9576 loop:
ROM2:9576 LDA ppu_intro_text_command,X
ROM2:9577 STA ppu_command_buffer,X
ROM2:9578 DEX
ROM2:9579 BPL loop
ROM2:957A LDX #$A
ROM2:957B LDA #0
 
ROM2:9588 loc_9588:
ROM2:9588 STA enemy_state_0,X
ROM2:9589 STA enemy_projectile_speed_x,X
ROM2:958A STA enemy_state_5,X
ROM2:958B STA enemy_state_6,X
ROM2:958C DEX
ROM2:958D BPL loc_9588
ROM2:958E JMP title_splash_next_state
 
Subroutine task0_intro_text_2
ROM2:959A task0_intro_text_2:
ROM2:959A INC alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
ROM2:959B LDA #$10
ROM2:959C STA desired_ppuscroll_y
ROM2:959D LDA #PPUCommandIndices_IntroTextRelated_2 ; PPUCommandIndices_Unknown_Copied_Data_0
 
ROM2:95A2 task0_Title_Splash_2_sub: ; Set to PPUCommandIndices_IntroTextRelated_2 or PPUCommandIndices_IntroTextRelated_1.
ROM2:95A2 STA current_ppu_command_index
ROM2:95A3 LDA #0
ROM2:95A4 STA enemy_state_4_1
ROM2:95A5 INC active_game_mode_task ; Set to 1
ROM2:95A6 RTS
 
Subroutine title_splash_main
ROM2:95AC title_splash_main:
ROM2:95AC LDA frame_counter
ROM2:95AD AND #1
ROM2:95AE BEQ even_frame
ROM2:95AF INC title_screen_timer ; Increment this every other frame. We'll move to the next
  ; state after it wraps to 0 (512 frames).
ROM2:95B0 LDA title_screen_timer
ROM2:95B1 BNE even_frame
ROM2:95B2 JMP title_splash_next_state
 
ROM2:95B3 even_frame:
ROM2:95B3 JSR title_splash_main_setup_decoration_sprites
ROM2:95B4 RTS
 
Subroutine intro_text_first_scroll
ROM2:95C1 intro_text_first_scroll:
ROM2:95C1 LDA frame_counter
ROM2:95C2 AND #1
ROM2:95C3 BEQ loc_95D8
ROM2:95C4 INC desired_ppuscroll_y
ROM2:95C5 LDA desired_ppuscroll_y
ROM2:95C6 CMP #$F0
ROM2:95C7 BNE loc_95D8
ROM2:95C8 INC text_scroll_index ; The index of an old man message to display
ROM2:95C9 LDA #0
ROM2:95CA STA desired_ppuscroll_y
ROM2:95CB INC alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
 
ROM2:95D8 loc_95D8:
ROM2:95D8 LDA desired_ppuscroll_y
ROM2:95D9 CMP #8
ROM2:95DA BNE locret_95EB
ROM2:95DB LDA text_scroll_index ; The index of an old man message to display
ROM2:95DC BEQ locret_95EB
ROM2:95DD LDA #0
ROM2:95DE STA text_scroll_index ; The index of an old man message to display
ROM2:95DF INC enemy_state_4_1
 
ROM2:95EB locret_95EB:
ROM2:95EB RTS
 
Subroutine intro_text_pause_for_big_text
ROM2:95EC intro_text_pause_for_big_text:
ROM2:95EC INC title_screen_timer
ROM2:95ED LDA title_screen_timer
ROM2:95EE BNE loc_95F7
ROM2:95EF INC enemy_state_4_1
 
ROM2:95F7 loc_95F7:
ROM2:95F7 LDA #$29
ROM2:95F8 STA byte_41D ; Set to 0x29.
ROM2:95F9 LDA #0
ROM2:95FA STA byte_41C ; Set to 0.
ROM2:95FB LDA #$2B
ROM2:95FC STA byte_418 ; Set to 0x2B.
ROM2:95FD LDA #$E0
ROM2:95FE STA byte_417 ; Set to 0xE0.
ROM2:95FF RTS
 
Subroutine intro_text_item_scroll
ROM2:960C intro_text_item_scroll:
ROM2:960C JSR clear_oam ; Clear the OAM buffer.
ROM2:960D JSR intro_text_item_scroll_1
ROM2:960E JSR intro_text_item_scroll_3
ROM2:960F LDA frame_counter
ROM2:9610 AND #1
ROM2:9611 BEQ locret_963E
ROM2:9612 LDX #$A
 
ROM2:961D loc_961D:
ROM2:961D DEC object_y,X
ROM2:961E DEX
ROM2:961F BNE loc_961D
ROM2:9620 INC byte_41B
ROM2:9621 LDA byte_41B
ROM2:9622 BNE loc_962D
ROM2:9623 INC text_scroll_index ; The index of an old man message to display
 
ROM2:962D loc_962D: ; The index of an old man message to display
ROM2:962D LDA text_scroll_index
ROM2:962E CMP #5
ROM2:962F BNE loc_963F
ROM2:9630 LDA byte_41B
ROM2:9631 CMP #$80
ROM2:9632 BNE loc_963F
ROM2:9633 INC enemy_state_4_1
 
ROM2:963E locret_963E:
ROM2:963E RTS
 
ROM2:963F loc_963F:
ROM2:963F INC desired_ppuscroll_y
ROM2:9640 LDA desired_ppuscroll_y
ROM2:9641 CMP #$F0
ROM2:9642 BNE loc_964D
ROM2:9643 INC alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
ROM2:9644 LDA #0
ROM2:9645 STA desired_ppuscroll_y
 
ROM2:964D loc_964D:
ROM2:964D LDA byte_41B
ROM2:964E AND #7
ROM2:964F BNE locret_963E
ROM2:9650 JSR intro_text_item_scroll_2
ROM2:9651 LDX #$20
ROM2:9652 LDA #$FF
ROM2:9653 STA ppu_command_buffer_03,X
ROM2:9654 DEX
 
ROM2:965F loc_965F:
ROM2:965F LDA #$24
ROM2:9660 STA ppu_command_buffer_03,X
ROM2:9661 DEX
ROM2:9662 BPL loc_965F
ROM2:9663 LDA #$20
ROM2:9664 STA ppu_command_buffer_02
ROM2:9665 LDA byte_41D
ROM2:9666 STA ppu_command_buffer
ROM2:9667 LDA byte_41C
ROM2:9668 STA ppu_command_buffer_01
ROM2:9669 CLC
ROM2:966A ADC #$20
ROM2:966B STA byte_41C
ROM2:966C BNE loc_9686
ROM2:966D INC byte_41D
ROM2:966E JMP loc_96A7
 
ROM2:9686 loc_9686:
ROM2:9686 CMP #$C0
ROM2:9687 BNE loc_96A7
ROM2:9688 LDA byte_41D
ROM2:9689 CMP #$2B
ROM2:968A BNE loc_9699
ROM2:968B LDA #$20
ROM2:968C STA byte_41D
ROM2:968D JMP loc_96A2
 
ROM2:9699 loc_9699:
ROM2:9699 CMP #$23
ROM2:969A BNE loc_96A7
ROM2:969B LDA #$28
ROM2:969C STA byte_41D
 
ROM2:96A2 loc_96A2:
ROM2:96A2 LDA #0
ROM2:96A3 STA byte_41C
 
ROM2:96A7 loc_96A7:
ROM2:96A7 LDX byte_419
ROM2:96A8 LDA byte_915E,X
ROM2:96A9 AND #$80
ROM2:96AA BEQ loc_96D6
ROM2:96AB LDA enemy_state_4_2
ROM2:96AC ASL A
ROM2:96AD TAX
ROM2:96AE LDY #0
ROM2:96AF LDA intro_text_item_scroll_ppu_command_table,X
ROM2:96B0 STA var_0
ROM2:96B1 LDA intro_text_item_scroll_ppu_command_table+1,X
ROM2:96B2 STA var_1
ROM2:96B3 LDA (var_0),Y
ROM2:96B4 TAX
 
ROM2:96B5 ppu_command_copy_loop:
ROM2:96B5 INY
ROM2:96B6 LDA (var_0),Y
ROM2:96B7 CMP #$FF
ROM2:96B8 BEQ loc_96D3
ROM2:96B9 STA ppu_command_buffer_03,X
ROM2:96BA INX
ROM2:96BB JMP ppu_command_copy_loop
 
ROM2:96D3 loc_96D3:
ROM2:96D3 INC enemy_state_4_2
 
ROM2:96D6 loc_96D6:
ROM2:96D6 JSR intro_text_item_scroll_0
ROM2:96D7 INC byte_419
ROM2:96D8 RTS
 
Subroutine intro_text_item_scroll_0
ROM2:96DD intro_text_item_scroll_0:
ROM2:96DD LDX byte_419
ROM2:96DE LDA byte_915E,X
ROM2:96DF AND #$40
ROM2:96E0 BEQ locret_9729
ROM2:96E1 LDA byte_418
ROM2:96E2 STA byte_325
ROM2:96E3 LDA byte_417
ROM2:96E4 STA byte_326
ROM2:96E5 LDA #$48
ROM2:96E6 STA byte_327
ROM2:96E7 LDA #0
ROM2:96E8 STA byte_328
ROM2:96E9 LDA #$FF
ROM2:96EA STA byte_329
ROM2:96EB INC byte_416
ROM2:96EC LDA byte_417
ROM2:96ED CLC
ROM2:96EE ADC #8
ROM2:96EF STA byte_417
ROM2:96F0 BNE locret_9729
ROM2:96F1 LDA byte_418
ROM2:96F2 CMP #$23
ROM2:96F3 BNE loc_971F
ROM2:96F4 LDA #$2B
ROM2:96F5 STA byte_418
ROM2:96F6 JMP loc_9724
 
ROM2:971F loc_971F:
ROM2:971F LDA #$23
ROM2:9720 STA byte_418
 
ROM2:9724 loc_9724:
ROM2:9724 LDA #$C0
ROM2:9725 STA byte_417
 
ROM2:9729 locret_9729:
ROM2:9729 RTS
 
Subroutine intro_text_item_scroll_1
ROM2:972A intro_text_item_scroll_1:
ROM2:972A LDX #$A
 
ROM2:972C loc_972C:
ROM2:972C LDA object_y,X
ROM2:972D CMP #$F0
ROM2:972E BNE loc_9736
ROM2:972F LDA #$FF
ROM2:9730 STA $AC,X
 
ROM2:9736 loc_9736:
ROM2:9736 DEX
ROM2:9737 BNE loc_972C
ROM2:9738 RTS
 
Subroutine intro_text_item_scroll_2
ROM2:973A intro_text_item_scroll_2:
ROM2:973A LDY byte_419
ROM2:973B LDA $915E,Y
ROM2:973C AND #$20
ROM2:973D BNE loc_9745
ROM2:973E RTS
 
ROM2:9745 loc_9745:
ROM2:9745 LDX #$A
 
ROM2:9747 loc_9747:
ROM2:9747 LDA $AC,X
ROM2:9748 BNE loc_974F
ROM2:9749 DEX
ROM2:974A JMP loc_9747
 
ROM2:974F loc_974F:
ROM2:974F LDY enemy_state_4_3
ROM2:9750 LDA $9240,Y
ROM2:9751 STA $444,X
ROM2:9752 LDA #$EF
ROM2:9753 STA $84,X
ROM2:9754 LDA byte_9268
ROM2:9755 STA $70,X
ROM2:9756 LDA #0
ROM2:9757 STA $AC,X
ROM2:9758 LDA $444,X
ROM2:9759 CMP #$30
ROM2:975A BCS loc_9796
ROM2:975B DEX
ROM2:975C LDA $9256,Y
ROM2:975D STA $444,X
ROM2:975E LDA #$EF
ROM2:975F STA $84,X
ROM2:9760 LDA byte_9269
ROM2:9761 STA $70,X
ROM2:9762 LDA #0
ROM2:9763 STA $AC,X
ROM2:9764 LDA $9240,Y
ROM2:9765 CMP #$1B
ROM2:9766 BNE loc_9792
ROM2:9767 LDA #$78
ROM2:9768 STA $70,X
ROM2:9769 STA $71,X
ROM2:976A LDA #0
ROM2:976B STA enemy_state_4_4
 
ROM2:9792 loc_9792:
ROM2:9792 INC enemy_state_4_3
ROM2:9793 RTS
 
ROM2:9796 loc_9796:
ROM2:9796 LDA #$68
ROM2:9797 STA $70,X
ROM2:9798 JMP loc_9792
 
Subroutine intro_text_item_scroll_3
ROM2:979D intro_text_item_scroll_3:
ROM2:979D LDX #$A
 
ROM2:979F loc_979F:
ROM2:979F LDA walk_state_and_weapon_state,X
ROM2:97A0 BNE loc_97C1
ROM2:97A1 TXA
ROM2:97A2 PHA
ROM2:97A3 LDA enemy_state_6,X
ROM2:97A4 CMP #$23
ROM2:97A5 BNE loc_97B2
ROM2:97A6 JSR intro_text_item_scroll_3b
ROM2:97A7 JMP loc_97BF
 
ROM2:97B2 loc_97B2:
ROM2:97B2 CMP #$30
ROM2:97B3 BCS loc_97BC
ROM2:97B4 JSR setup_sprite
ROM2:97B5 JMP loc_97BF
 
ROM2:97BC loc_97BC:
ROM2:97BC JSR intro_text_item_scroll_3a
 
ROM2:97BF loc_97BF:
ROM2:97BF PLA
ROM2:97C0 TAX
 
ROM2:97C1 loc_97C1:
ROM2:97C1 DEX
ROM2:97C2 BNE loc_979F
ROM2:97C3 RTS
 
ROM2:97C4   .BYTE $A2
ROM2:97C5   .BYTE 4
ROM2:97C6   .BYTE $C9
ROM2:97C7   .BYTE $14
ROM2:97C8   .BYTE $D0
ROM2:97C9   .BYTE 2
ROM2:97CA   .BYTE $A2
ROM2:97CB   .BYTE $C
ROM2:97CC   .BYTE $DE
ROM2:97CD   .BYTE $50
ROM2:97CE   .BYTE 2
ROM2:97CF   .BYTE $AA
ROM2:97D0   .BYTE $38
ROM2:97D1   .BYTE $E9
ROM2:97D2   .BYTE 4
ROM2:97D3   .BYTE $AA
ROM2:97D4   .BYTE $10
ROM2:97D5   .BYTE $F6
ROM2:97D6   .BYTE $60
 
Subroutine intro_text_item_scroll_3b
ROM2:97D8 intro_text_item_scroll_3b:
ROM2:97D8 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM2:97D9 JSR store_palette_2_in_tile_attributes ; Store 0x2 in var_4 and var_5, and set A to 2.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM2:97DA ASL A
ROM2:97DB AND frame_counter
ROM2:97DC LSR A
ROM2:97DD LSR A
ROM2:97DE STA var_12
ROM2:97DF LDY #$14
ROM2:97E0 JMP after_setting_some_frame_state
 
Subroutine intro_text_item_scroll_3a
ROM2:97EA intro_text_item_scroll_3a:
ROM2:97EA LDA enemy_state_6,X
ROM2:97EB AND #$F
ROM2:97EC ASL A
ROM2:97ED STA var_0
ROM2:97EE ASL A
ROM2:97EF CLC
ROM2:97F0 ADC var_0
ROM2:97F1 TAY
ROM2:97F2 LDA object_y,X
ROM2:97F3 STA var_0
ROM2:97F4 LDA object_x,X
ROM2:97F5 STA var_1
ROM2:97F6 LDA #5
ROM2:97F7 STA var_2
ROM2:97F8 TYA
ROM2:97F9 ASL A
ROM2:97FA ASL A
ROM2:97FB TAX
 
ROM2:97FC loop:
ROM2:97FC LDA byte_926A,Y
ROM2:97FD BEQ loc_9823
ROM2:97FE STA sprite_oam_data.tile,X
ROM2:97FF LDA var_0
ROM2:9800 STA sprite_oam_data,X
ROM2:9801 LDA byte_9282,Y
ROM2:9802 STA sprite_oam_data.attr,X
ROM2:9803 LDA var_1
ROM2:9804 STA sprite_oam_data.x_pos,X
ROM2:9805 INX
ROM2:9806 INX
ROM2:9807 INX
ROM2:9808 INX
 
ROM2:9823 loc_9823:
ROM2:9823 LDA var_1
ROM2:9824 CLC
ROM2:9825 ADC #8
ROM2:9826 STA var_1
ROM2:9827 INY
ROM2:9828 DEC var_2
ROM2:9829 BPL loop
ROM2:982A RTS
 
Subroutine intro_text_end_pause
ROM2:9830 intro_text_end_pause:
ROM2:9830 INC title_screen_timer
ROM2:9831 LDA title_screen_timer
ROM2:9832 BNE loc_9854
ROM2:9833 INC enemy_state_4_1
ROM2:9834 RTS
 
Subroutine intro_text_finish
ROM2:983C intro_text_finish:
ROM2:983C INC title_screen_timer
ROM2:983D LDA title_screen_timer
ROM2:983E CMP #$39
ROM2:983F BNE loc_9854
ROM2:9840 LDA #0
ROM2:9841 STA active_game_mode_task ; Set to 0
ROM2:9842 STA title_screen_timer ; Set to 0
ROM2:9843 STA enemy_state_4 ; Return to the title splash
ROM2:9844 STA enemy_state_4_1 ; Set to 0
ROM2:9845 RTS
 
ROM2:9854 loc_9854: ; Clear the OAM buffer.
ROM2:9854 JSR clear_oam
ROM2:9855 JSR intro_text_item_scroll_3
ROM2:9856 RTS
 
ROM2:985B title_screen_triforce_palette_shift_ppu_cmd: .WORD $43F
ROM2:985D   .BYTE 4
ROM2:985E   .BYTE $36
ROM2:985F   .BYTE $17
ROM2:9860   .BYTE $27
ROM2:9861   .BYTE $F ; This byte is overwritten from the table below for the
  ; triforce's current color.
ROM2:9862   .BYTE $FF
ROM2:9863 title_screen_triforce_palette_values: .BYTE $27
ROM2:9864   .BYTE $37
ROM2:9865   .BYTE $37
ROM2:9866   .BYTE $27
ROM2:9867   .BYTE $17
ROM2:9868   .BYTE 7
ROM2:9869   .BYTE 7
ROM2:986A   .BYTE $17
 
Subroutine title_splash_main_setup_decoration_sprites
ROM2:986B title_splash_main_setup_decoration_sprites:
ROM2:986B LDY #$70 ; Copy 0x70 bytes of sprites. The first 0x60 of this is the
  ; decoration leaves around the logo (over the base rectangle,
  ; which is in the background), and the last 0x10 is the sword
  ; where it overlaps the triforce.
 
ROM2:986C loop:
ROM2:986C LDA off_90EC+1,Y
ROM2:986D STA byte_1FF,Y
ROM2:986E DEY
ROM2:986F BNE loop
ROM2:9870 JSR title_update_waterfall ; Update the waterfall sprites on the title screen.
ROM2:9871 LDA enemy_state_0 ; On the title screen, this is the triforce palette shift timer.
ROM2:9872 BNE waiting_for_triforce_timer ; Skip this if it's not time to shift the triforce color yet.
ROM2:9873 LDY #7
 
ROM2:9874 loop2: ; Copy the palette shift command to ppu_command_buffer.
ROM2:9874 LDA title_screen_triforce_palette_shift_ppu_cmd,Y
ROM2:9875 STA ppu_command_buffer,Y
ROM2:9876 DEY
ROM2:9877 BPL loop2
ROM2:9878 LDY byte_413 ; Load the current palette position.
ROM2:9879 LDA title_screen_triforce_palette_values,Y ; Overwrite the byte for the triforce palette with its
  ; current color.
ROM2:987A STA ppu_command_buffer_05
ROM2:987B LDA #6
ROM2:987C STA enemy_state_0 ; The triforce shifts color every 6 frames.
ROM2:987D INC byte_413 ; Increase the palette index for next time.
ROM2:987E LDA byte_413
ROM2:987F CMP #8
ROM2:9880 BNE waiting_for_triforce_timer
ROM2:9881 LDA #$10
ROM2:9882 STA enemy_state_0 ; If we've reached the end of the triforce palette cycle, wait
  ; 16 frames instead of 6.
ROM2:9883 LDA #0
ROM2:9884 STA byte_413 ; Reset the triforce palette index.
 
ROM2:9885 waiting_for_triforce_timer:
ROM2:9885 DEC enemy_state_0
ROM2:9886 RTS
 
ROM2:9887   .BYTE $B2
ROM2:9888   .BYTE $B4
ROM2:9889   .BYTE $B6
ROM2:988A   .BYTE $B8
ROM2:988B   .BYTE $A2
ROM2:988C   .BYTE $A4
ROM2:988D   .BYTE $A6
ROM2:988E   .BYTE $A8
ROM2:98B7 byte_98B7: .BYTE $50
ROM2:98B8   .BYTE $58
ROM2:98B9   .BYTE $60
ROM2:98BA   .BYTE $68
ROM2:98BB   .BYTE $70
ROM2:98BC   .BYTE $80
ROM2:98BD   .BYTE $90
ROM2:98BE   .BYTE $A0
ROM2:98BF   .BYTE $B0
ROM2:98C0   .BYTE $C0
ROM2:98C1   .BYTE $D0
ROM2:98C2   .BYTE $E0
 
Subroutine title_update_waterfall
; Update the waterfall sprites on the title screen.
ROM2:98C3 title_update_waterfall:
ROM2:98C3 LDA enemy_projectile_speed_x
ROM2:98C4 BNE skip
ROM2:98C5 LDA #$B6 ; Waterfall sprite Y positions
ROM2:98C6 STA enemy_projectile_speed_x_1
ROM2:98C7 LDA #$C8
ROM2:98C8 STA byte_421
ROM2:98C9 LDA #$D8
ROM2:98CA STA store_item
ROM2:98CB LDA #$C0
ROM2:98CC STA byte_423
ROM2:98CD LDA #$D0
ROM2:98CE STA byte_424
ROM2:98CF LDA #$DD
ROM2:98D0 STA byte_425
ROM2:98D1 INC enemy_projectile_speed_x
 
ROM2:98D2 skip:
ROM2:98D2 LDX #2
 
ROM2:98D3 loop: ; Update one waterfall sprite on the title screen.
ROM2:98D3 JSR title_update_waterfall_piece
ROM2:98D4 DEX
ROM2:98D5 BPL loop
ROM2:98D6 JSR title_update_waterfall_sprites
ROM2:98D7 RTS
 
Subroutine title_update_waterfall_piece
; Update one waterfall sprite on the title screen.
ROM2:98F5 title_update_waterfall_piece:
ROM2:98F5 INC enemy_projectile_speed_x_1,X
ROM2:98F6 INC enemy_projectile_speed_x_1,X
ROM2:98F7 LDA enemy_projectile_speed_x_1,X
ROM2:98F8 CMP #$E3
ROM2:98F9 BCC skip1 ; Skip if < 0xE3
ROM2:98FA LDA #$B2 ; Wrap back to 0xB2.
ROM2:98FB STA enemy_projectile_speed_x_1,X
 
ROM2:98FC skip1:
ROM2:98FC STA var_5
ROM2:98FD TAY
ROM2:98FE LDA #$10
ROM2:98FF CPY #$C2
ROM2:9900 BCS skip2 ; Branch if >= 0xC2.
ROM2:9901 LSR A
ROM2:9902 CPY #$B9
ROM2:9903 BCS skip2 ; Branch if >= 0xB9.
ROM2:9904 LDA #0
 
ROM2:9905 skip2:
ROM2:9905 STA var_0
ROM2:9906 STX var_2
ROM2:9907 LDY byte_D8BB,X
ROM2:9908 LDX #3
 
ROM2:9909 loop:
ROM2:9909 LDA byte_D8AF,X
ROM2:990A CLC
ROM2:990B ADC var_0
ROM2:990C STA sprite_oam_data.tile,Y
ROM2:990D LDA byte_D8B7,X
ROM2:990E STA sprite_oam_data.x_pos,Y
ROM2:990F LDA var_5
ROM2:9910 STA sprite_oam_data,Y
ROM2:9911 LDA #0
ROM2:9912 STA sprite_oam_data.attr,Y
ROM2:9913 INY
ROM2:9914 INY
ROM2:9915 INY
ROM2:9916 INY
ROM2:9917 DEX
ROM2:9918 BPL loop
ROM2:9919 LDX var_2
ROM2:991A RTS
 
Subroutine title_update_waterfall_sprites
ROM2:9943 title_update_waterfall_sprites:
ROM2:9943 LDX #3
ROM2:9944 LDY #$F0
 
ROM2:9945 loop:
ROM2:9945 LDA frame_counter
ROM2:9946 AND #8
ROM2:9947 ADC byte_D8B3,X
ROM2:9948 STA sprite_oam_data.tile,Y
ROM2:9949 LDA #$A8
ROM2:994A STA sprite_oam_data,Y
ROM2:994B LDA byte_98B7,X
ROM2:994C STA sprite_oam_data.x_pos,Y
ROM2:994D LDA #0
ROM2:994E STA sprite_oam_data.attr,Y
ROM2:994F INY
ROM2:9950 INY
ROM2:9951 INY
ROM2:9952 INY
ROM2:9953 DEX
ROM2:9954 BPL loop
ROM2:9955 RTS
 
ROM2:9956
ROM2:9B68 title_splash_fading_palette_data: .BYTE $F
ROM2:9B69   .BYTE 8
ROM2:9B6A   .BYTE 8
ROM2:9B6B   .BYTE 6
ROM2:9B6C   .BYTE 5
ROM2:9B6D   .BYTE 4
ROM2:9B6E   .BYTE 3
ROM2:9B6F   .BYTE 2
ROM2:9B70   .BYTE 2
ROM2:9B71   .BYTE 2
ROM2:9B72   .BYTE $C0
ROM2:9B73   .BYTE 6
ROM2:9B74   .BYTE 4
ROM2:9B75   .BYTE $C0
ROM2:9B76   .BYTE 3
ROM2:9B77   .BYTE 4
ROM2:9B78   .BYTE 4
 
Subroutine title_splash_fading
; This updates the palette for the title screen fading ; out, and keeps updating the waterfall sprites.
ROM2:9B79 title_splash_fading:
ROM2:9B79 LDA enemy_state_5_1
ROM2:9B7A BNE skip
ROM2:9B7B LDA #0
ROM2:9B7C STA var_1 ; Set to 0.
ROM2:9B7D LDA enemy_state_5
ROM2:9B7E ASL A ; A <<= 4
ROM2:9B7F ASL A
ROM2:9B80 ASL A
ROM2:9B81 ASL A
ROM2:9B82 ROL var_1
ROM2:9B83 ASL A
ROM2:9B84 ROL var_1
ROM2:9B85 ADC #$69
ROM2:9B86 STA var_0
ROM2:9B87 LDA var_1
ROM2:9B88 ADC #$99
ROM2:9B89 STA var_1
ROM2:9B8A LDA #$3F
ROM2:9B8B STA ppu_command_buffer
ROM2:9B8C LDA #0
ROM2:9B8D STA ppu_command_buffer_01
ROM2:9B8E LDA #$20
ROM2:9B8F STA ppu_command_buffer_02
ROM2:9B90 LDY #$1F
ROM2:9B91 LDA #$FF
ROM2:9B92 STA ppu_command_buffer_04,Y
 
ROM2:9B93 loop:
ROM2:9B93 LDA (0),Y
ROM2:9B94 STA ppu_command_buffer_03,Y
ROM2:9B95 DEY
ROM2:9B96 BPL loop
ROM2:9B97 INC enemy_state_5
ROM2:9B98 LDY enemy_state_5
ROM2:9B99 LDA title_splash_fading_palette_data,Y
ROM2:9B9A STA enemy_state_5_1
ROM2:9B9B CPY #$E
ROM2:9B9C BCC skip
ROM2:9B9D INC enemy_state_4
ROM2:9B9E LDA #0
ROM2:9B9F STA enemy_state_4_1 ; Set to 0
ROM2:9BA0 STA active_game_mode_task ; Set to 0
 
ROM2:9BA1 skip:
ROM2:9BA1 DEC enemy_state_5_1
ROM2:9BA2 JSR title_update_waterfall ; Update the waterfall sprites on the title screen.
ROM2:9BA3 RTS
 
ROM2:9BA4 Skipped empty chunk
ROM2:9BA4   .BYTE $98
ROM2:9BA5   .BYTE $68
ROM2:9BA6   .BYTE $10
ROM2:9BA7   .BYTE $69
ROM2:9BA8   .BYTE $80
ROM2:9BA9   .BYTE $68
ROM2:9BAA   .BYTE $90
ROM2:9BAB   .BYTE $6D
ROM2:9BAC   .BYTE $93
ROM2:9BAD   .BYTE $6D
ROM2:9BAE   .BYTE $96
ROM2:9BAF   .BYTE $6D
ROM2:9BB0   .BYTE $99
ROM2:9BB1   .BYTE $6D
ROM2:9BB2   .BYTE $C0
ROM2:9BB3   .BYTE $68
ROM2:9BB4   .BYTE $90
ROM2:9BB5   .BYTE $6A
ROM2:9BB6   .BYTE $88
ROM2:9BB7   .BYTE $68
ROM2:9BB8   .BYTE $91
ROM2:9BB9   .BYTE $6D
ROM2:9BBA   .BYTE $94
ROM2:9BBB   .BYTE $6D
ROM2:9BBC   .BYTE $97
ROM2:9BBD   .BYTE $6D
ROM2:9BBE   .BYTE $9A
ROM2:9BBF   .BYTE $6D
ROM2:9BC0   .BYTE $E8
ROM2:9BC1   .BYTE $68
ROM2:9BC2   .BYTE $10
ROM2:9BC3   .BYTE $6C
ROM2:9BC4   .BYTE $90
ROM2:9BC5   .BYTE $68
ROM2:9BC6   .BYTE $92
ROM2:9BC7   .BYTE $6D
ROM2:9BC8   .BYTE $95
ROM2:9BC9   .BYTE $6D
ROM2:9BCA   .BYTE $98
ROM2:9BCB   .BYTE $6D
ROM2:9BCC   .BYTE $9B
ROM2:9BCD   .BYTE $6D
 
Subroutine sub_9D2A
ROM2:9D2A sub_9D2A:
ROM2:9D2A LDA #$FF
ROM2:9D2B LDY current_save_slot
 
ROM2:9D2E loc_9D2E:
ROM2:9D2E CLC
ROM2:9D2F ADC #$E
ROM2:9D30 DEY
ROM2:9D31 BPL loc_9D2E
ROM2:9D32 TAY
ROM2:9D33 LDX #$D
 
ROM2:9D37 loc_9D37:
ROM2:9D37 LDA $9D00,Y
ROM2:9D38 STA $C0,X
ROM2:9D39 DEY
ROM2:9D3A DEX
ROM2:9D3B BPL loc_9D37
ROM2:9D3C RTS
 
ROM2:9D41 ppu_create_delete_save_command: .BYTE $20
ROM2:9D42   .BYTE $64
ROM2:9D43   .BYTE $19
ROM2:9D44   .BYTE $6A
ROM2:9D45   .BYTE $6A
ROM2:9D46   .BYTE $6A
ROM2:9D47   .BYTE $6A
ROM2:9D48   .BYTE $E
ROM2:9D49   .BYTE $15
ROM2:9D4A   .BYTE $12
ROM2:9D4B   .BYTE $16
ROM2:9D4C   .BYTE $12
ROM2:9D4D   .BYTE $17
ROM2:9D4E   .BYTE $A
ROM2:9D4F   .BYTE $1D
ROM2:9D50   .BYTE $12
ROM2:9D51   .BYTE $18
ROM2:9D52   .BYTE $17
ROM2:9D53   .BYTE $24
ROM2:9D54   .BYTE $24
ROM2:9D55   .BYTE $16
ROM2:9D56   .BYTE $18
ROM2:9D57 unk_9D57: .BYTE $D
ROM2:9D58   .BYTE $E
ROM2:9D59   .BYTE $6A
ROM2:9D5A   .BYTE $6A
ROM2:9D5B   .BYTE $6A
ROM2:9D5C   .BYTE $6A
ROM2:9D5D   .BYTE $FF
ROM2:9D5E ppu_create_save_command: .BYTE $1B
ROM2:9D5F   .BYTE $E
ROM2:9D60   .BYTE $10
ROM2:9D61   .BYTE $12
ROM2:9D62   .BYTE $1C
ROM2:9D63   .BYTE $1D
ROM2:9D64   .BYTE $E
ROM2:9D65   .BYTE $1B
ROM2:9D66   .BYTE $24
ROM2:9D67   .BYTE $22
ROM2:9D68   .BYTE $18
ROM2:9D69   .BYTE $1E
ROM2:9D6A   .BYTE $1B
ROM2:9D6B   .BYTE $24
ROM2:9D6C   .BYTE $17
ROM2:9D6D   .BYTE $A
ROM2:9D6E   .BYTE $16
ROM2:9D6F   .BYTE $E
ROM2:9D70 byte_9D70: .BYTE $1B
ROM2:9D71   .BYTE $E
ROM2:9D72   .BYTE $10
ROM2:9D73   .BYTE $12
ROM2:9D74   .BYTE $1C
ROM2:9D75   .BYTE $1D
ROM2:9D76   .BYTE $E
ROM2:9D77   .BYTE $1B
ROM2:9D78   .BYTE $24
ROM2:9D79   .BYTE $24
ROM2:9D7A   .BYTE $24
ROM2:9D7B byte_9D7B: .BYTE $20
ROM2:9D7C   .BYTE $CE
ROM2:9D7D   .BYTE 8
ROM2:9D7E   .BYTE $24
ROM2:9D7F   .BYTE $24
ROM2:9D80   .BYTE $24
ROM2:9D81   .BYTE $24
ROM2:9D82   .BYTE $24
ROM2:9D83   .BYTE $24
ROM2:9D84   .BYTE $24
ROM2:9D85   .BYTE $24
ROM2:9D86   .BYTE $21
ROM2:9D87   .BYTE $2E
ROM2:9D88   .BYTE 8
ROM2:9D89   .BYTE $24
ROM2:9D8A   .BYTE $24
ROM2:9D8B   .BYTE $24
ROM2:9D8C   .BYTE $24
ROM2:9D8D   .BYTE $24
ROM2:9D8E   .BYTE $24
ROM2:9D8F   .BYTE $24
ROM2:9D90   .BYTE $24
ROM2:9D91   .BYTE $21
ROM2:9D92   .BYTE $8E
ROM2:9D93   .BYTE 8
ROM2:9D94   .BYTE $24
ROM2:9D95   .BYTE $24
ROM2:9D96   .BYTE $24
ROM2:9D97   .BYTE $24
ROM2:9D98   .BYTE $24
ROM2:9D99   .BYTE $24
ROM2:9D9A   .BYTE $24
ROM2:9D9B unk_9D9B: .BYTE $24
ROM2:9D9C   .BYTE $21
ROM2:9D9D   .BYTE $EA
ROM2:9D9E   .BYTE $F
ROM2:9D9F   .BYTE $E
ROM2:9DA0   .BYTE $15
ROM2:9DA1   .BYTE $12
ROM2:9DA2   .BYTE $16
ROM2:9DA3   .BYTE $12
ROM2:9DA4   .BYTE $17
ROM2:9DA5   .BYTE $A
ROM2:9DA6   .BYTE $1D
ROM2:9DA7   .BYTE $12
ROM2:9DA8   .BYTE $18
ROM2:9DA9   .BYTE $17
ROM2:9DAA   .BYTE $24
ROM2:9DAB   .BYTE $E
ROM2:9DAC   .BYTE $17
ROM2:9DAD   .BYTE $D
ROM2:9DAE   .BYTE $FF
ROM2:9DAF byte_9DAF: .BYTE $2F
ROM2:9DB0   .BYTE $47
ROM2:9DB1   .BYTE $5F
ROM2:9DB2   .BYTE $77
ROM2:9DB3 byte_9DB3: .BYTE $A
ROM2:9DB4   .BYTE $B
ROM2:9DB5   .BYTE $C
ROM2:9DB6   .BYTE $D
ROM2:9DB7   .BYTE $E
ROM2:9DB8   .BYTE $F
ROM2:9DB9   .BYTE $10
ROM2:9DBA   .BYTE $11
ROM2:9DBB   .BYTE $12
ROM2:9DBC   .BYTE $13
ROM2:9DBD   .BYTE $14
ROM2:9DBE   .BYTE $15
ROM2:9DBF   .BYTE $16
ROM2:9DC0   .BYTE $17
ROM2:9DC1   .BYTE $18
ROM2:9DC2   .BYTE $19
ROM2:9DC3   .BYTE $1A
ROM2:9DC4   .BYTE $1B
ROM2:9DC5   .BYTE $1C
ROM2:9DC6   .BYTE $1D
ROM2:9DC7   .BYTE $1E
ROM2:9DC8   .BYTE $1F
ROM2:9DC9   .BYTE $20
ROM2:9DCA   .BYTE $21
ROM2:9DCB   .BYTE $22
ROM2:9DCC   .BYTE $23
ROM2:9DCD   .BYTE $62
ROM2:9DCE   .BYTE $63
ROM2:9DCF   .BYTE $28
ROM2:9DD0   .BYTE $29
ROM2:9DD1   .BYTE $2A
ROM2:9DD2   .BYTE $2B
ROM2:9DD3   .BYTE $2C
ROM2:9DD4   .BYTE 0
ROM2:9DD5   .BYTE 1
ROM2:9DD6   .BYTE 2
ROM2:9DD7   .BYTE 3
ROM2:9DD8   .BYTE 4
ROM2:9DD9   .BYTE 5
ROM2:9DDA   .BYTE 6
ROM2:9DDB   .BYTE 7
ROM2:9DDC   .BYTE 8
ROM2:9DDD   .BYTE 9
ROM2:9DDE   .BYTE $24
ROM2:9DDF byte_9DDF: .BYTE $20
ROM2:9DE0   .BYTE $CE
ROM2:9DE1   .BYTE 1
ROM2:9DE2   .BYTE $21
ROM2:9DE3   .BYTE $2E
ROM2:9DE4   .BYTE 1
ROM2:9DE5   .BYTE $21
ROM2:9DE6   .BYTE $8E
ROM2:9DE7   .BYTE 1
ROM2:9DE8 byte_9DE8: .BYTE $20
ROM2:9DE9   .BYTE $CE
ROM2:9DEA   .BYTE $48
ROM2:9DEB   .BYTE $24
ROM2:9DEC   .BYTE $FF
ROM2:9DED   .BYTE $21
ROM2:9DEE   .BYTE $2E
ROM2:9DEF   .BYTE $48
ROM2:9DF0   .BYTE $24
ROM2:9DF1   .BYTE $FF
ROM2:9DF2   .BYTE $21
ROM2:9DF3   .BYTE $8E
ROM2:9DF4   .BYTE $48
ROM2:9DF5   .BYTE $24
ROM2:9DF6   .BYTE $FF
ROM2:9DF7 byte_9DF7: .BYTE $F3
ROM2:9DF8   .BYTE 3
ROM2:9DF9   .BYTE $43
ROM2:9DFA   .BYTE $F8
ROM2:9DFB   .BYTE $25
ROM2:9DFC   .BYTE $23
ROM2:9DFD   .BYTE $70
ROM2:9DFE   .BYTE $F8
ROM2:9DFF   .BYTE $25
ROM2:9E00   .BYTE $23
ROM2:9E01   .BYTE $30
ROM2:9E02 byte_9E02: .BYTE $10
ROM2:9E03   .BYTE $C7
ROM2:9E04   .BYTE $87
ROM2:9E05   .BYTE $F0
ROM2:9E06   .BYTE $77
ROM2:9E07   .BYTE $B7
ROM2:9E08 byte_9E08: .BYTE 4
ROM2:9E09   .BYTE 9
ROM2:9E0A   .BYTE $E
ROM2:9E0B byte_9E0B: .BYTE 0
ROM2:9E0C   .BYTE 8
ROM2:9E0D   .BYTE $10
ROM2:9E0E byte_9E0E: .BYTE 2
ROM2:9E0F   .BYTE 5
ROM2:9E10   .BYTE 8
 
Function chunk for task0_CreateDeleteSave
ROM2:9E11 task0_CreateDeleteSave_main:
ROM2:9E11 LDA #0
ROM2:9E12 STA current_save_slot
ROM2:9E13 JSR create_delete_save_helper
ROM2:9E14 JSR clear_ppumask
ROM2:9E15 LDA task_state ; Set to 1 to run task_state_1 next time
ROM2:9E16 BNE task_state_1
ROM2:9E17 JSR clear_nametables
 
ROM2:9E22 loc_9E22:
ROM2:9E22 JSR sub_9D2A
ROM2:9E23 JSR sub_A437
ROM2:9E24 INC current_save_slot
ROM2:9E25 LDA current_save_slot
ROM2:9E26 CMP #3
ROM2:9E27 BNE loc_9E22 ; repeat for each save slot
ROM2:9E28 LDA #0
ROM2:9E29 STA current_save_slot ; reset to save slot 0
ROM2:9E2A LDX #$1C
 
ROM2:9E2B loop:
ROM2:9E2B LDA ppu_create_delete_save_command,X
ROM2:9E2C STA ppu_command_buffer,X
ROM2:9E2D DEX
ROM2:9E2E BPL loop
ROM2:9E2F LDA game_mode
ROM2:9E30 CMP #GameMode_CreateSave
ROM2:9E31 BNE not_in_create_save
ROM2:9E32 LDY #0
 
ROM2:9E33 loop2: ; Modify the PPU command for create save mode. This changes 0x12 bytes starting at buffer+0x07.
ROM2:9E33 LDA ppu_create_save_command,Y
ROM2:9E34 STA ppu_command_buffer_07,Y
ROM2:9E35 INY
ROM2:9E36 CPY #$12
ROM2:9E37 BNE loop2
 
ROM2:9E52 not_in_create_save: ; If we did the above loop, A = 0x309[0x11]
ROM2:9E52 LDA #$1D
 
ROM2:9E54 loc_9E54: ; Set to 0x1D or 0x34
ROM2:9E54 STA ppu_command_buffer_bytes_used
ROM2:9E55 INC task_state ; Set to 2 to run task_state_2 next time
ROM2:9E56 RTS
 
ROM2:9E57 task_state_1:
ROM2:9E57 CMP #1
ROM2:9E58 BNE task_state_2
ROM2:9E59 LDX #$33
 
ROM2:9E60 loc_9E60:
ROM2:9E60 LDA byte_9D7B,X
ROM2:9E61 STA ppu_command_buffer,X
ROM2:9E62 DEX
ROM2:9E63 BPL loc_9E60
ROM2:9E64 LDX #0
ROM2:9E65 LDY #0
 
ROM2:9E6D loc_9E6D:
ROM2:9E6D LDA byte_638,Y
ROM2:9E6E STA ppu_command_buffer_03,X
ROM2:9E6F INX
ROM2:9E70 INY
ROM2:9E71 TYA
ROM2:9E72 AND #7
ROM2:9E73 BNE loc_9E6D
ROM2:9E74 INX
ROM2:9E75 INX
ROM2:9E76 INX
ROM2:9E77 CPX #$21
ROM2:9E78 BNE loc_9E6D
ROM2:9E79 LDA game_mode
ROM2:9E7A CMP #GameMode_CreateSave
ROM2:9E7B BNE in_create_save ; GameMode_DeleteSave
ROM2:9E7C LDY #0
 
ROM2:9E89 loc_9E89:
ROM2:9E89 LDA byte_9D70,Y
ROM2:9E8A STA ppu_command_buffer_03,X
ROM2:9E8B INX
ROM2:9E8C INY
ROM2:9E8D CPY #$B
ROM2:9E8E BNE loc_9E89
 
ROM2:9E8F in_create_save:
ROM2:9E8F LDA #$34
ROM2:9E90 BNE loc_9E54 ; Set to 0x1D or 0x34
 
ROM2:9E91 task_state_2:
ROM2:9E91 CMP #2
ROM2:9E92 BNE task_state_3
ROM2:9E93 LDA #PPUCommandIndices_DeleteSave
 
ROM2:9E9F loc_9E9F: ; Set to 0x12 or PPUCommandIndices_CreateSave
ROM2:9E9F STA current_ppu_command_index
ROM2:9EA0 INC task_state ; Set to 3 to run task_state_3 next time
ROM2:9EA1 RTS
 
ROM2:9EA2 task_state_3:
ROM2:9EA2 CMP #3
ROM2:9EA3 BNE task_state_4
ROM2:9EA4 LDA #$15
ROM2:9EA5 LDY game_mode
ROM2:9EA6 CPY #GameMode_DeleteSave
ROM2:9EA7 BNE in_create_save_2
ROM2:9EA8 LDA #$30
 
ROM2:9EA9 in_create_save_2:
ROM2:9EA9 STA unk_26810
ROM2:9EAA LDA #PPUCommandIndices_MainMenu_1
ROM2:9EAB BNE loc_9E9F ; Set to 0x12 or PPUCommandIndices_CreateSave
 
ROM2:9EAC task_state_4:
ROM2:9EAC LDA game_mode
ROM2:9EAD CMP #GameMode_DeleteSave
ROM2:9EAE BEQ in_delete_save
ROM2:9EAF LDX #3
ROM2:9EB0 LDY #$FF
ROM2:9EB1 STY current_save_slot
 
ROM2:9EC5 loc_9EC5:
ROM2:9EC5 INY
ROM2:9EC6 INC current_save_slot
ROM2:9EC7 LDA byte_633,Y
ROM2:9EC8 BEQ in_delete_save
ROM2:9EC9 DEX
ROM2:9ECA BPL loc_9EC5
 
ROM2:9ECB in_delete_save:
ROM2:9ECB JSR task0_CreateDeleteSave_setup_some_sprite
ROM2:9ECC LDA current_save_slot
ROM2:9ECD CMP #3
ROM2:9ECE BNE loc_9EDE
ROM2:9ECF LDA #$F8
ROM2:9ED0 STA sprite_oam_data_08
 
ROM2:9EDE loc_9EDE:
ROM2:9EDE LDA #$50
ROM2:9EDF STA var_0
ROM2:9EE0 LDA #$30
ROM2:9EE1 STA var_1
ROM2:9EE2 INC active_game_mode_task ; Set to 1
ROM2:9EE3 JMP loc_A638
 
ROM2:9EEB byte_9EEB: .BYTE $23
ROM2:9EEC   .BYTE $E
ROM2:9EED   .BYTE $15
ROM2:9EEE   .BYTE $D
ROM2:9EEF   .BYTE $A
 
Subroutine task1_CreateSave
ROM2:9EF0 task1_CreateSave:
 
ROM2:9EF0 LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:9EF1 AND #ControllerBits_Start
ROM2:9EF2 BEQ loc_9EFC
ROM2:9EF3 LDA current_save_slot
ROM2:9EF4 CMP #3
ROM2:9EF5 BEQ loc_9EFF
 
ROM2:9EFC loc_9EFC:
ROM2:9EFC JMP loc_9FB0
 
ROM2:9EFF loc_9EFF:
ROM2:9EFF LDA #0
ROM2:9F00 STA audio_misc_0607
ROM2:9F01 STA byte_425
ROM2:9F02 STA byte_423
ROM2:9F03 STA current_save_slot
ROM2:9F04 TAX
 
ROM2:9F0D loc_9F0D:
ROM2:9F0D LDY current_save_slot
ROM2:9F0E LDA #$FF
ROM2:9F0F STA byte_2652A,Y
ROM2:9F10 TYA
ROM2:9F11 ASL A
ROM2:9F12 TAY
ROM2:9F13 LDA #0
ROM2:9F14 STA byte_426
ROM2:9F15 STA loc_106D9C,Y
ROM2:9F16 INY
ROM2:9F17 STA loc_106D9C,Y
ROM2:9F18 TXA
ROM2:9F19 PHA
ROM2:9F1A JSR sub_9D2A
ROM2:9F1B PLA
ROM2:9F1C TAX
 
ROM2:9F2A loc_9F2A:
ROM2:9F2A LDY byte_423
ROM2:9F2B LDA byte_638,Y
ROM2:9F2C LDY byte_425
ROM2:9F2D STA (object_knockback_4),Y
ROM2:9F2E CMP #$24
ROM2:9F2F BEQ loc_9F79
ROM2:9F30 LDA byte_633,X
ROM2:9F31 BNE loc_9F79
ROM2:9F32 LDY #$18
ROM2:9F33 LDA #$22
ROM2:9F34 STA (object_knockback),Y
ROM2:9F35 INY
ROM2:9F36 LDA #$FF
ROM2:9F37 STA (object_knockback),Y
ROM2:9F38 LDY #$25
ROM2:9F39 LDA #8
ROM2:9F3A STA (object_knockback),Y
ROM2:9F3B TXA
ROM2:9F3C PHA
ROM2:9F3D ASL A
ROM2:9F3E ASL A
ROM2:9F3F ASL A
ROM2:9F40 TAY
ROM2:9F41 LDX #0
 
ROM2:9F57 loc_9F57:
ROM2:9F57 LDA byte_638,Y
ROM2:9F58 CMP byte_9EEB,X
ROM2:9F59 BNE loc_9F6E
ROM2:9F5A INY
ROM2:9F5B INX
ROM2:9F5C CPX #5
ROM2:9F5D BCC loc_9F57
ROM2:9F5E PLA
ROM2:9F5F PHA
ROM2:9F60 TAX
ROM2:9F61 LDY #0
ROM2:9F62 LDA #1
ROM2:9F63 STA (object_knockback_12),Y
 
ROM2:9F6E loc_9F6E:
ROM2:9F6E PLA
ROM2:9F6F TAX
ROM2:9F70 LDA #1
ROM2:9F71 STA byte_426
ROM2:9F72 LDY #0
ROM2:9F73 STA (object_knockback_6),Y
 
ROM2:9F79 loc_9F79:
ROM2:9F79 INC byte_423
ROM2:9F7A INC byte_425
ROM2:9F7B LDA byte_425
ROM2:9F7C CMP #8
ROM2:9F7D BNE loc_9F2A
ROM2:9F7E INX
ROM2:9F7F LDA #0
ROM2:9F80 STA byte_425
ROM2:9F81 LDA byte_426
ROM2:9F82 BEQ loc_9F94
ROM2:9F83 JSR sub_A3C8
 
ROM2:9F94 loc_9F94:
ROM2:9F94 INC current_save_slot
ROM2:9F95 LDA current_save_slot
ROM2:9F96 CMP #3
ROM2:9F97 BEQ loc_9F9F
ROM2:9F98 JMP loc_9F0D
 
ROM2:9F9F loc_9F9F:
ROM2:9F9F LDA #0
ROM2:9FA0 STA byte_426
ROM2:9FA1 STA current_save_slot
ROM2:9FA2 JSR create_delete_save_helper
ROM2:9FA3 LDA #1
ROM2:9FA4 STA active_game_mode_task ; Set to 1
ROM2:9FA5 JMP set_game_mode_title_state_1 ; Set game_mode to the title screen, state 1. This actually
  ; skips the title screen and goes to the main menu.
 
ROM2:9FB0 loc_9FB0:
ROM2:9FB0 LDA current_save_slot
ROM2:9FB1 CMP #3
ROM2:9FB2 BEQ loc_9FB9
ROM2:9FB3 JSR create_save_handle_dpad ; This is related to moving the cursor around in the save creation menu.
 
ROM2:9FB9 loc_9FB9:
ROM2:9FB9 JSR create_delete_save_handle_changing_items
ROM2:9FBA JSR create_save_update_sprites_1
ROM2:9FBB JSR create_save_update_sprites_2
ROM2:9FBC JMP loc_A10B
 
Subroutine task1_DeleteSave
ROM2:9FC5 task1_DeleteSave:
 
ROM2:9FC5 LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:9FC6 CMP #ControllerBits_Start
ROM2:9FC7 BEQ loc_9FCE
ROM2:9FC8 JMP create_delete_save_handle_changing_items
 
ROM2:9FCE loc_9FCE:
ROM2:9FCE LDA current_save_slot
ROM2:9FCF CMP #3 ; Jump if not on "Register your name"
ROM2:9FD0 BNE loc_9FE8
ROM2:9FD1 LDA #GameMode_CreateSave
ROM2:9FD2 STA game_mode ; set GameMode_CreateSave
ROM2:9FD3 LDA #0
ROM2:9FD4 STA active_game_mode_task ; Set to 0
ROM2:9FD5 STA task_state ; Set to 0
 
Subroutine create_delete_save_helper
ROM2:9FDE create_delete_save_helper:
ROM2:9FDE STA enemy_projectile_speed_x
ROM2:9FDF STA enemy_projectile_speed_x_1
ROM2:9FE0 STA byte_421
ROM2:9FE1 RTS
 
Function chunk for task1_DeleteSave
ROM2:9FE8 loc_9FE8:
ROM2:9FE8 LDA #Sound3_Pickup
ROM2:9FE9 STA play_sound_0 ; Play Sound3_Pickup
ROM2:9FEA LDY current_save_slot
ROM2:9FEB LDX byte_9E08,Y
ROM2:9FEC LDY #4
 
ROM2:9FF4 loc_9FF4:
ROM2:9FF4 LDA byte_9DE8,X
ROM2:9FF5 STA ppu_command_buffer,Y
ROM2:9FF6 DEX
ROM2:9FF7 DEY
ROM2:9FF8 BPL loc_9FF4
 
ROM2:9FFE loc_9FFE:
ROM2:9FFE JSR sub_106DF1
ROM2:9FFF JSR sub_A35D
ROM2:A000 JSR sub_A80C
ROM2:A001 LDY #7
 
ROM2:A009 loc_A009:
ROM2:A009 LDA #$24
ROM2:A00A STA (var_12),Y
ROM2:A00B DEY
ROM2:A00C BPL loc_A009
ROM2:A00D RTS
 
Subroutine create_save_handle_dpad
; This is related to moving the cursor around in the save creation menu.
ROM2:A011 create_save_handle_dpad:
ROM2:A011 LDA controller_1_cur ; P1 buttons being held
ROM2:A012 AND #$F
ROM2:A013 BNE buttons_held
 
ROM2:A017 loc_A017: ; Set to 0.
ROM2:A017 STA byte_426
ROM2:A018 STA byte_428 ; Set to 0.
ROM2:A019 STA byte_429 ; Set to 0.
ROM2:A01A RTS
 
ROM2:A01B buttons_held:
ROM2:A01B TAY
ROM2:A01C LDA byte_426
ROM2:A01D BNE loc_A02D
ROM2:A01E STY byte_427
ROM2:A01F INC byte_426
 
ROM2:A02D loc_A02D: ; P1 buttons being held
ROM2:A02D LDA controller_1_cur
ROM2:A02E AND #$F
ROM2:A02F CMP byte_427
ROM2:A030 BEQ loc_A03B
ROM2:A031 LDA #0
ROM2:A032 JSR loc_A017
 
ROM2:A03B loc_A03B:
ROM2:A03B LDA byte_429
ROM2:A03C BEQ loc_A044
ROM2:A03D DEC byte_429
ROM2:A03E RTS
 
ROM2:A044 loc_A044:
ROM2:A044 LDY #8
ROM2:A045 LDA byte_428
ROM2:A046 BNE loc_A04D
ROM2:A047 LDY #$10
 
ROM2:A04D loc_A04D:
ROM2:A04D STY byte_429
ROM2:A04E LDA controller_1_cur ; P1 buttons being held
ROM2:A04F AND #$F
ROM2:A050 CMP #ControllerBits_Dpad_Right
ROM2:A051 BNE loc_A07C
ROM2:A052 INC enemy_projectile_speed_x
ROM2:A053 LDA object_x_1 ; Move the cursor right
ROM2:A054 CLC
ROM2:A055 ADC #$10
ROM2:A056 STA object_x_1
ROM2:A057 CMP #$E0
ROM2:A058 BNE loc_A079
ROM2:A059 LDA #$30 ; Wrap the cursor to the left
ROM2:A05A STA object_x_1
ROM2:A05B LDX #0
ROM2:A05C JSR create_save_handle_dpad_helper
ROM2:A05D LDA byte_42A
ROM2:A05E BEQ loc_A079
ROM2:A05F LDA #0
ROM2:A060 STA enemy_projectile_speed_x
 
ROM2:A079 loc_A079:
ROM2:A079 JMP loc_A0E7
 
ROM2:A07C loc_A07C:
ROM2:A07C CMP #ControllerBits_Dpad_Left
ROM2:A07D BNE loc_A0A4
ROM2:A07E DEC enemy_projectile_speed_x
ROM2:A07F LDA object_x_1
ROM2:A080 SEC
 
ROM2:A086 loc_A086:
ROM2:A086 SBC #$10
ROM2:A087 STA object_x_1
ROM2:A088 CMP #$20
ROM2:A089 BNE loc_A0A1
ROM2:A08A LDA #$D0
ROM2:A08B STA object_x_1
ROM2:A08C LDX #3
ROM2:A08D JSR create_save_handle_dpad_helper
ROM2:A08E LDA byte_42A
ROM2:A08F BEQ loc_A0A1
ROM2:A090 LDA #$2B
ROM2:A091 STA enemy_projectile_speed_x
 
ROM2:A0A1 loc_A0A1:
ROM2:A0A1 JMP loc_A0E7
 
ROM2:A0A4 loc_A0A4:
ROM2:A0A4 CMP #ControllerBits_Dpad_Down
ROM2:A0A5 BNE loc_A0C7
ROM2:A0A6 LDA enemy_projectile_speed_x ; Move the cursor down
ROM2:A0A7 CLC
ROM2:A0A8 ADC #$B
ROM2:A0A9 STA enemy_projectile_speed_x
ROM2:A0AA LDX #0
ROM2:A0AB JSR create_save_handle_dpad_helper
ROM2:A0AC LDA byte_42A
ROM2:A0AD BEQ loc_A0C4
ROM2:A0AE LDA enemy_projectile_speed_x
ROM2:A0AF SEC
ROM2:A0B0 SBC #$2C
ROM2:A0B1 STA enemy_projectile_speed_x
 
ROM2:A0C4 loc_A0C4:
ROM2:A0C4 JMP loc_A0E7
 
ROM2:A0C7 loc_A0C7:
ROM2:A0C7 CMP #ControllerBits_Dpad_Up
ROM2:A0C8 BNE ret
ROM2:A0C9 LDA enemy_projectile_speed_x ; Move the cursor up
ROM2:A0CA SEC
ROM2:A0CB SBC #$B
ROM2:A0CC STA enemy_projectile_speed_x
ROM2:A0CD LDX #3
ROM2:A0CE JSR create_save_handle_dpad_helper
ROM2:A0CF LDA byte_42A
ROM2:A0D0 BEQ loc_A0E7
ROM2:A0D1 LDA enemy_projectile_speed_x
ROM2:A0D2 CLC
ROM2:A0D3 ADC #$2C
ROM2:A0D4 STA enemy_projectile_speed_x
 
ROM2:A0E7 loc_A0E7:
ROM2:A0E7 LDA #Sound1_Rupee
ROM2:A0E8 STA byte_428
ROM2:A0E9 STA play_sound_1 ; Play Sound1_Rupee
 
ROM2:A0EA ret:
ROM2:A0EA RTS
 
Subroutine create_save_handle_dpad_helper
ROM2:A0F0 create_save_handle_dpad_helper:
ROM2:A0F0 LDY #0
ROM2:A0F1 LDA object_y_1
ROM2:A0F2 CLC
ROM2:A0F3 ADC byte_9E02,X
ROM2:A0F4 STA object_y_1
ROM2:A0F5 INX
ROM2:A0F6 CMP byte_9E02,X
ROM2:A0F7 BNE loc_A107
ROM2:A0F8 INX
ROM2:A0F9 LDA byte_9E02,X
ROM2:A0FA STA object_y_1
ROM2:A0FB INY
 
ROM2:A107 loc_A107:
ROM2:A107 STY byte_42A
 
ROM2:A10A locret_A10A:
ROM2:A10A RTS
 
Function chunk for task1_CreateSave
ROM2:A10B loc_A10B:
ROM2:A10B LDA enemy_projectile_speed_x_1
ROM2:A10C BNE loc_A12E
ROM2:A10D LDY current_save_slot
ROM2:A10E CPY #3
ROM2:A10F BEQ locret_A10A
ROM2:A110 LDA byte_9E0B,Y
ROM2:A111 STA byte_421
ROM2:A112 LDX byte_9E0E,Y
ROM2:A113 LDY #2
 
ROM2:A121 loc_A121:
ROM2:A121 LDA byte_9DDF,X
ROM2:A122 STA store_item,Y
ROM2:A123 DEX
ROM2:A124 DEY
ROM2:A125 BPL loc_A121
ROM2:A126 INC enemy_projectile_speed_x_1
 
ROM2:A12E loc_A12E: ; P1 buttons pressed on this frame
ROM2:A12E LDA controller_1_pressed
ROM2:A12F AND #ControllerBits_B|ControllerBits_A
ROM2:A130 BEQ loc_A18B
ROM2:A131 CMP #ControllerBits_A
ROM2:A132 BNE loc_A15A
ROM2:A133 LDY #Sound3_PlaceBomb
ROM2:A134 STY play_sound_3 ; Play Sound3_PlaceBomb
ROM2:A135 LDY #2
 
ROM2:A13F loc_A13F:
ROM2:A13F LDA store_item,Y
ROM2:A140 STA ppu_command_buffer,Y
ROM2:A141 DEY
ROM2:A142 BPL loc_A13F
ROM2:A143 STY ppu_command_buffer_04
ROM2:A144 LDX byte_421
ROM2:A145 LDY enemy_projectile_speed_x
ROM2:A146 LDA byte_9DB3,Y
ROM2:A147 STA ppu_command_buffer_03
ROM2:A148 STA byte_638,X
 
ROM2:A15A loc_A15A:
ROM2:A15A LDA object_x
ROM2:A15B CLC
ROM2:A15C ADC #8
ROM2:A15D STA object_x
ROM2:A15E INC byte_421
ROM2:A15F INC byte_423
ROM2:A160 LDA byte_423
ROM2:A161 AND #$F
ROM2:A162 CMP #6
ROM2:A163 BNE loc_A18B
ROM2:A164 LDA byte_423
ROM2:A165 SEC
ROM2:A166 SBC #8
ROM2:A167 STA byte_423
ROM2:A168 LDY current_save_slot
ROM2:A169 LDA byte_9E0B,Y
ROM2:A16A STA byte_421
ROM2:A16B LDA object_x
ROM2:A16C CMP #$B0
ROM2:A16D BNE loc_A18B
ROM2:A16E LDA #$70
ROM2:A16F STA object_x
 
ROM2:A18B loc_A18B:
ROM2:A18B JMP loc_A1D7
 
Subroutine task0_CreateDeleteSave_setup_some_sprite
ROM2:A18E task0_CreateDeleteSave_setup_some_sprite:
ROM2:A18E LDY #$A
 
ROM2:A18F loop:
ROM2:A18F LDA byte_9DF7,Y
ROM2:A190 STA sprite_oam_data.tile,Y
ROM2:A191 DEY
ROM2:A192 BPL loop
ROM2:A193 LDY current_save_slot
ROM2:A194 LDA byte_9DAF,Y
ROM2:A195 STA object_y
ROM2:A196 STA sprite_oam_data.y_pos
ROM2:A197 LDA game_mode
ROM2:A198 CMP #$F
ROM2:A199 BEQ ret
ROM2:A19A LDA #$F3
ROM2:A19B STA sprite_oam_data.tile
ROM2:A19C LDA object_y
ROM2:A19D SEC
ROM2:A19E SBC #8
ROM2:A19F STA sprite_oam_data_04
ROM2:A1A0 LDA #$70
ROM2:A1A1 STA object_x
ROM2:A1A2 LDA #$87
ROM2:A1A3 STA object_y_1
ROM2:A1A4 LDA #$30
ROM2:A1A5 STA object_x_1
 
ROM2:A1A6 ret:
ROM2:A1A6 RTS
 
Subroutine create_save_update_sprites_1
ROM2:A1C3 create_save_update_sprites_1:
ROM2:A1C3 LDA object_y
ROM2:A1C4 CMP #$77
ROM2:A1C5 BNE loc_A1CF
ROM2:A1C6 LDA #$F8
ROM2:A1C7 STA sprite_oam_data_04
ROM2:A1C8 RTS
 
ROM2:A1CF loc_A1CF:
ROM2:A1CF LDA object_y
ROM2:A1D0 JSR create_save_update_sprites_1a
ROM2:A1D1 STY sprite_oam_data_04
 
ROM2:A1D7 loc_A1D7:
ROM2:A1D7 LDA object_x
ROM2:A1D8 STA sprite_oam_data_07
ROM2:A1D9 RTS
 
Subroutine create_save_update_sprites_2
ROM2:A1DD create_save_update_sprites_2:
ROM2:A1DD LDA object_y
ROM2:A1DE CMP #$77
ROM2:A1DF BNE loc_A1E9
ROM2:A1E0 LDA #$F8
ROM2:A1E1 STA sprite_oam_data_08
ROM2:A1E2 RTS
 
ROM2:A1E9 loc_A1E9:
ROM2:A1E9 LDA object_y_1
ROM2:A1EA JSR create_save_update_sprites_1a
ROM2:A1EB STY sprite_oam_data_08
ROM2:A1EC LDA object_x_1
ROM2:A1ED STA sprite_oam_data_0B
ROM2:A1EE RTS
 
Subroutine create_save_update_sprites_1a
ROM2:A1F7 create_save_update_sprites_1a:
ROM2:A1F7 SEC
ROM2:A1F8 SBC #8
ROM2:A1F9 TAY
ROM2:A1FA LDA frame_counter
ROM2:A1FB AND #8
ROM2:A1FC BNE ret
ROM2:A1FD LDY #$F8
 
ROM2:A1FE ret:
ROM2:A1FE RTS
 
Subroutine create_delete_save_handle_changing_items
ROM2:A204 create_delete_save_handle_changing_items:
ROM2:A204 LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:A205 AND #ControllerBits_Select
ROM2:A206 BEQ locret_A253
 
ROM2:A207 go_to_next_main_menu_item:
ROM2:A207 LDA #Sound1_Rupee
ROM2:A208 STA play_sound_1 ; Main menu change
ROM2:A209 INC current_save_slot
ROM2:A20A LDY current_save_slot
ROM2:A20B CPY #4
ROM2:A20C BNE loc_A21B
ROM2:A20D LDY #0
ROM2:A20E STY current_save_slot
 
ROM2:A21B loc_A21B:
ROM2:A21B LDA byte_9DAF,Y
ROM2:A21C STA sprite_oam_data.y_pos
ROM2:A21D LDA game_mode
ROM2:A21E CMP #$F
ROM2:A21F BEQ locret_A253
ROM2:A220 LDA object_y
ROM2:A221 CLC
ROM2:A222 ADC #$18
ROM2:A223 STA object_y
ROM2:A224 CMP #$8F
ROM2:A225 BNE loc_A236
ROM2:A226 LDA #$2F
ROM2:A227 STA object_y
 
ROM2:A236 loc_A236:
ROM2:A236 STA sprite_oam_data.y_pos
ROM2:A237 LDA #$70
ROM2:A238 STA sprite_oam_data_07
ROM2:A239 STA object_x
ROM2:A23A LDA #0
ROM2:A23B STA enemy_projectile_speed_x_1
ROM2:A23C STA byte_421
ROM2:A23D LDY current_save_slot
ROM2:A23E CPY #3
ROM2:A23F BEQ locret_A253
ROM2:A240 LDA $633,Y
ROM2:A241 BNE go_to_next_main_menu_item
 
ROM2:A253 locret_A253:
ROM2:A253 RTS
 
ROM2:A254 byte_A254: .BYTE $21
ROM2:A255   .BYTE 9
ROM2:A256   .BYTE $11
ROM2:A257   .BYTE $24
ROM2:A258   .BYTE $24
ROM2:A259   .BYTE $24
ROM2:A25A   .BYTE $24
ROM2:A25B   .BYTE $24
ROM2:A25C   .BYTE $24
ROM2:A25D   .BYTE $24
ROM2:A25E   .BYTE $24
ROM2:A25F   .BYTE $62
ROM2:A260   .BYTE 0
ROM2:A261   .BYTE 0
ROM2:A262   .BYTE 0
ROM2:A263   .BYTE 0
ROM2:A264   .BYTE 0
ROM2:A265   .BYTE 0
ROM2:A266   .BYTE 0
ROM2:A267   .BYTE 0
ROM2:A268   .BYTE $21
ROM2:A269   .BYTE $32
ROM2:A26A   .BYTE 8
ROM2:A26B   .BYTE 0
ROM2:A26C   .BYTE 0
ROM2:A26D   .BYTE 0
ROM2:A26E   .BYTE 0
ROM2:A26F   .BYTE 0
ROM2:A270   .BYTE 0
ROM2:A271   .BYTE 0
ROM2:A272   .BYTE 0
ROM2:A273   .BYTE $FF
ROM2:A274 byte_A274: .BYTE $21
ROM2:A275   .BYTE $89
ROM2:A276   .BYTE 3
ROM2:A277   .BYTE $24
ROM2:A278   .BYTE $24
ROM2:A279   .BYTE 1
ROM2:A27A   .BYTE $21
ROM2:A27B   .BYTE $E9
ROM2:A27C   .BYTE 3
ROM2:A27D   .BYTE $24
ROM2:A27E   .BYTE $24
ROM2:A27F   .BYTE 1
ROM2:A280   .BYTE $22
ROM2:A281   .BYTE $49
ROM2:A282   .BYTE 3
ROM2:A283   .BYTE $24
ROM2:A284   .BYTE $24
ROM2:A285   .BYTE 1
ROM2:A286   .BYTE $FF
ROM2:A287 byte_A287: .BYTE $29
ROM2:A288   .BYTE $32
ROM2:A289   .BYTE $16
 
Subroutine task0_MainMenu_main
ROM2:A28A task0_MainMenu_main:
ROM2:A28A JSR clear_ppumask
ROM2:A28B LDA task_state
ROM2:A28C JSR call_jump_table
 
ROM2:A28D   .WORD task0_MainMenu_0_and_task1_Title_state_1
ROM2:A28F   .WORD task0_MainMenu_1
ROM2:A291   .WORD task0_MainMenu_2
ROM2:A293   .WORD task0_MainMenu_3
ROM2:A295   .WORD task0_MainMenu_3
ROM2:A297   .WORD task0_MainMenu_3
ROM2:A299   .WORD task0_MainMenu_6
 
Subroutine task0_MainMenu_0_and_task1_Title_state_1
ROM2:A2A0 task0_MainMenu_0_and_task1_Title_state_1:
ROM2:A2A0 JSR clear_ppumask
ROM2:A2A1 LDA #0
ROM2:A2A2 STA current_save_slot
 
ROM2:A2A7 loc_A2A7:
ROM2:A2A7 LDY current_save_slot
ROM2:A2A8 LDA byte_2652A,Y
ROM2:A2A9 BNE loc_A2CD
ROM2:A2AA JSR sub_9D2A
ROM2:A2AB JSR sub_A3E1
ROM2:A2AC LDA current_save_slot
ROM2:A2AD ASL A
ROM2:A2AE TAY
ROM2:A2AF LDA loc_106D9C,Y
ROM2:A2B0 CMP byte_CE
ROM2:A2B1 BNE loc_A2CD
ROM2:A2B2 INY
ROM2:A2B3 LDA loc_106D9C,Y
ROM2:A2B4 CMP byte_CF
ROM2:A2B5 BNE loc_A2CD
ROM2:A2B6 JSR sub_A764
ROM2:A2B7 JMP loc_A2FC
 
ROM2:A2CD loc_A2CD:
ROM2:A2CD JSR sub_106DF1
ROM2:A2CE JSR sub_A307
ROM2:A2CF LDY current_save_slot
ROM2:A2D0 LDA byte_2651E,Y
ROM2:A2D1 CMP #$5A
ROM2:A2D2 BNE loc_A2F6
ROM2:A2D3 LDA byte_26521,Y
ROM2:A2D4 CMP #$A5
ROM2:A2D5 BNE loc_A2F6
ROM2:A2D6 LDA current_save_slot
ROM2:A2D7 ASL A
ROM2:A2D8 TAY
ROM2:A2D9 LDA byte_26524,Y
ROM2:A2DA CMP var_14
ROM2:A2DB BNE loc_A2F6
ROM2:A2DC INY
ROM2:A2DD LDA byte_26524,Y
ROM2:A2DE CMP var_15
ROM2:A2DF BEQ loc_A2FC
 
ROM2:A2F6 loc_A2F6:
ROM2:A2F6 JSR sub_106DF1
ROM2:A2F7 JSR sub_A35D
 
ROM2:A2FC loc_A2FC:
ROM2:A2FC INC current_save_slot
ROM2:A2FD LDA current_save_slot
ROM2:A2FE CMP #3
ROM2:A2FF BNE loc_A2A7
ROM2:A300 INC task_state
ROM2:A301 RTS
 
Subroutine sub_A307
ROM2:A307 sub_A307:
ROM2:A307 LDA #0
ROM2:A308 STA var_14
ROM2:A309 STA var_15 ; Set to 0
ROM2:A30A LDY #7
 
ROM2:A30B loop1:
ROM2:A30B LDA (var_4),Y
ROM2:A30C JSR sub_A351
ROM2:A30D DEY
ROM2:A30E BPL loop1
ROM2:A30F LDY #$27
 
ROM2:A319 loc_A319:
ROM2:A319 LDA (var_0),Y
ROM2:A31A JSR sub_A351
ROM2:A31B DEY
ROM2:A31C BPL loc_A319
ROM2:A31D LDA #$80
ROM2:A31E STA var_1
ROM2:A31F LDA #1
ROM2:A320 STA var_0
ROM2:A321 LDY #0
 
ROM2:A32B loc_A32B:
ROM2:A32B LDA (var_2),Y
ROM2:A32C JSR sub_A351
ROM2:A32D INC var_2
ROM2:A32E BNE loc_A336
ROM2:A32F INC var_3
 
ROM2:A336 loc_A336:
ROM2:A336 DEC var_1
ROM2:A337 BNE loc_A32B
ROM2:A338 DEC var_0
ROM2:A339 LDA var_0
ROM2:A33A BPL loc_A32B
ROM2:A33B LDA (var_6),Y
ROM2:A33C JSR sub_A351
ROM2:A33D LDA (var_8),Y
ROM2:A33E JSR sub_A351
ROM2:A33F LDA (var_10),Y
ROM2:A340 JSR sub_A351
ROM2:A341 LDA (var_12),Y
 
Subroutine sub_A351
ROM2:A351 sub_A351:
ROM2:A351 CLC
ROM2:A352 ADC var_15
ROM2:A353 STA var_15
ROM2:A354 LDA var_14
ROM2:A355 ADC #0
ROM2:A356 STA var_14
ROM2:A357 RTS
 
Subroutine sub_A35D
ROM2:A35D sub_A35D:
ROM2:A35D LDY #7
ROM2:A35E LDA #$24
 
ROM2:A35F loop1:
ROM2:A35F STA (var_4),Y
ROM2:A360 DEY
ROM2:A361 BPL loop1
ROM2:A362 LDY #$27
ROM2:A363 LDA #0
 
ROM2:A364 loop2:
ROM2:A364 STA (var_0),Y
ROM2:A365 DEY
ROM2:A366 BPL loop2
ROM2:A367 LDA #$80
ROM2:A368 STA var_1
ROM2:A369 LDA #1
ROM2:A36A STA var_0
ROM2:A36B LDY #0
 
ROM2:A36C loop3:
ROM2:A36C LDA #0
ROM2:A36D STA (2),Y
ROM2:A36E INC var_2
ROM2:A36F BNE loc_A383
ROM2:A370 INC var_3
 
ROM2:A383 loc_A383:
ROM2:A383 DEC var_1
ROM2:A384 BNE loop3
ROM2:A385 DEC var_0
ROM2:A386 LDA var_0
ROM2:A387 BPL loop3
ROM2:A388 LDA #0
ROM2:A389 STA (var_6),Y
ROM2:A38A STA (var_8),Y
ROM2:A38B STA (var_10),Y
ROM2:A38C STA (var_12),Y
ROM2:A38D JSR sub_106DF1
ROM2:A38E JSR sub_A307
ROM2:A38F LDY current_save_slot
ROM2:A390 LDA #0
ROM2:A391 STA byte_633,Y
ROM2:A392 STA quest_no,Y
ROM2:A393 STA deaths_per_save_slot,Y
ROM2:A394 LDA #$FF
ROM2:A395 STA byte_2652A,Y
ROM2:A396 LDA #$5A
ROM2:A397 STA byte_2651E,Y
ROM2:A398 LDA #$A5
ROM2:A399 STA byte_26521,Y
ROM2:A39A TYA
ROM2:A39B ASL A
ROM2:A39C TAY
ROM2:A39D LDA var_14
ROM2:A39E STA byte_26524,Y
ROM2:A39F INY
ROM2:A3A0 LDA var_15
ROM2:A3A1 STA byte_26524,Y ; Store walking_state
ROM2:A3A2 RTS
 
Subroutine sub_A3C8
ROM2:A3C8 sub_A3C8:
ROM2:A3C8 JSR sub_A3E1
ROM2:A3C9 LDY current_save_slot
ROM2:A3CA LDA #0
ROM2:A3CB STA byte_2652A,Y ; Set to 0.
ROM2:A3CC TYA ; Y = current_save_slot << 1
ROM2:A3CD ASL A
ROM2:A3CE TAY
ROM2:A3CF LDA byte_CE ; This clobbers data in the SRAM CODE region. It's reinitialized
  ; by task0_LoadDungeon's call to init_sram_code.
ROM2:A3D0 STA loc_106D9C,Y
ROM2:A3D1 INY
ROM2:A3D2 LDA byte_CF
ROM2:A3D3 STA loc_106D9C,Y
ROM2:A3D4 RTS
 
Subroutine sub_A3E1
ROM2:A3E1 sub_A3E1:
ROM2:A3E1 LDA #0
ROM2:A3E2 STA byte_CE ; Set to 0.
ROM2:A3E3 STA byte_CF ; Set to 0.
ROM2:A3E4 LDY #7
 
ROM2:A3E5 loop1:
ROM2:A3E5 LDA (object_knockback_4),Y
ROM2:A3E6 JSR add_16bit_to_byte_CE
ROM2:A3E7 DEY
ROM2:A3E8 BPL loop1
ROM2:A3E9 LDY #$27
 
ROM2:A3EA loop2:
ROM2:A3EA LDA (object_knockback),Y
ROM2:A3EB JSR add_16bit_to_byte_CE
ROM2:A3EC DEY
ROM2:A3ED BPL loop2
ROM2:A3EE LDA #$80
ROM2:A3EF STA object_knockback_1
ROM2:A3F0 LDA #1
ROM2:A3F1 STA object_knockback
ROM2:A3F2 LDY #0
 
ROM2:A3F3 loop3:
ROM2:A3F3 LDA (object_knockback_2),Y
ROM2:A3F4 JSR add_16bit_to_byte_CE
ROM2:A3F5 INC object_knockback_2
ROM2:A3F6 BNE loc_A410
ROM2:A3F7 INC object_knockback_3
 
ROM2:A410 loc_A410:
ROM2:A410 DEC object_knockback_1
ROM2:A411 BNE loop3
ROM2:A412 DEC object_knockback
ROM2:A413 LDA object_knockback
ROM2:A414 BPL loop3
ROM2:A415 LDA (object_knockback_6),Y
ROM2:A416 JSR add_16bit_to_byte_CE
ROM2:A417 LDA (object_knockback_8),Y
ROM2:A418 JSR add_16bit_to_byte_CE
ROM2:A419 LDA (object_knockback_10),Y
ROM2:A41A JSR add_16bit_to_byte_CE
ROM2:A41B LDA (object_knockback_12),Y
 
Subroutine add_16bit_to_byte_CE
ROM2:A42B add_16bit_to_byte_CE:
ROM2:A42B CLC
ROM2:A42C ADC byte_CF
ROM2:A42D STA byte_CF
ROM2:A42E LDA byte_CE
ROM2:A42F ADC #0
ROM2:A430 STA byte_CE
ROM2:A431 RTS
 
Subroutine sub_A437
ROM2:A437 sub_A437:
ROM2:A437 LDY #7
ROM2:A438 LDA #$24
 
ROM2:A43B loc_A43B:
ROM2:A43B STA (object_knockback_4),Y
ROM2:A43C DEY
ROM2:A43D BPL loc_A43B
ROM2:A43E LDY #$27
ROM2:A43F LDA #0
 
ROM2:A444 loc_A444:
ROM2:A444 STA (object_knockback),Y
ROM2:A445 DEY
ROM2:A446 BPL loc_A444
ROM2:A447 LDA #$80
ROM2:A448 STA object_knockback_1
ROM2:A449 LDA #1
ROM2:A44A STA object_knockback
ROM2:A44B LDY #0
 
ROM2:A453 loc_A453: ; Clear scratch area for new save data?
ROM2:A453 LDA #0
ROM2:A454 STA (object_knockback_2),Y
ROM2:A455 INC object_knockback_2
ROM2:A456 BNE loc_A45D
ROM2:A457 INC object_knockback_3
 
ROM2:A45D loc_A45D:
ROM2:A45D DEC object_knockback_1
ROM2:A45E BNE loc_A453
ROM2:A45F DEC object_knockback
ROM2:A460 LDA object_knockback
ROM2:A461 BPL loc_A453
ROM2:A462 LDA #0
ROM2:A463 STA (object_knockback_6),Y
ROM2:A464 STA (object_knockback_8),Y
ROM2:A465 STA (object_knockback_10),Y
ROM2:A466 STA (object_knockback_12),Y
ROM2:A467 JSR sub_9D2A
ROM2:A468 JSR sub_A3E1
ROM2:A469 LDA #$FF
ROM2:A46A LDY current_save_slot
ROM2:A46B STA byte_2652A,Y
ROM2:A46C RTS
 
Subroutine task0_MainMenu_1
ROM2:A47F task0_MainMenu_1:
ROM2:A47F LDA #0
ROM2:A480 STA current_save_slot
ROM2:A481 JSR sub_106DF1
ROM2:A482 LDY #$B
ROM2:A483 LDX #0
 
ROM2:A484 loop:
ROM2:A484 TYA
ROM2:A485 PHA
ROM2:A486 LDA (var_0),Y
ROM2:A487 TAY
ROM2:A488 LDA byte_A287,Y
ROM2:A489 STA byte_26804,X
ROM2:A48A PLA
ROM2:A48B CLC
ROM2:A48C ADC #$28
ROM2:A48D TAY
ROM2:A48E TXA
ROM2:A48F CLC
ROM2:A490 ADC #4
ROM2:A491 TAX
ROM2:A492 CPX #$C
ROM2:A493 BCC loop
ROM2:A494 JSR clear_overworld_room_object_info
ROM2:A495 LDA #PPUCommandIndices_MainMenu_1
ROM2:A496 STA current_ppu_command_index ; Set to PPUCommandIndices_MainMenu_1.
ROM2:A497 INC task_state
ROM2:A498 JSR clear_nametables
ROM2:A499 LDY #4
ROM2:A49A LDA #0
ROM2:A49B STA force_beam_sword ; Set to 0
 
ROM2:A4B6 loc_A4B6:
ROM2:A4B6 STA screen_history_0,Y
ROM2:A4B7 DEY
ROM2:A4B8 BPL loc_A4B6
ROM2:A4B9 RTS
 
Subroutine task0_MainMenu_2
ROM2:A4BD task0_MainMenu_2:
ROM2:A4BD LDA #PPUCommandIndices_MainMenu_2
ROM2:A4BE STA current_ppu_command_index ; Set to PPUCommandIndices_MainMenu_2.
ROM2:A4BF INC task_state
ROM2:A4C0 RTS
 
Subroutine task0_MainMenu_3
ROM2:A4C4 task0_MainMenu_3:
ROM2:A4C4 LDY #$1F
 
ROM2:A4C6 loc_A4C6:
ROM2:A4C6 LDA byte_A254,Y
ROM2:A4C7 STA ppu_command_buffer,Y
ROM2:A4C8 DEY
ROM2:A4C9 BPL loc_A4C6
ROM2:A4CA LDY current_save_slot
 
ROM2:A4D1 loc_A4D1:
ROM2:A4D1 LDA ppu_command_buffer_01
ROM2:A4D2 CLC
ROM2:A4D3 ADC #$60
ROM2:A4D4 STA ppu_command_buffer_01
ROM2:A4D5 LDA ppu_command_buffer_15
ROM2:A4D6 CLC
ROM2:A4D7 ADC #$60
ROM2:A4D8 STA ppu_command_buffer_15
ROM2:A4D9 LDA ppu_command_buffer
ROM2:A4DA ADC #0
ROM2:A4DB STA ppu_command_buffer
ROM2:A4DC STA ppu_command_buffer_14
ROM2:A4DD DEY
ROM2:A4DE BPL loc_A4D1
ROM2:A4DF LDA current_save_slot
ROM2:A4E0 ASL A
ROM2:A4E1 ASL A
ROM2:A4E2 ASL A
ROM2:A4E3 TAX
ROM2:A4E4 LDY #3
 
ROM2:A4F9 loc_A4F9:
ROM2:A4F9 LDA byte_638,X
ROM2:A4FA STA ppu_command_buffer,Y
ROM2:A4FB INX
ROM2:A4FC INY
ROM2:A4FD CPY #$B
ROM2:A4FE BNE loc_A4F9
ROM2:A4FF LDA current_save_slot
ROM2:A500 ASL A
ROM2:A501 TAY
ROM2:A502 LDA saved_hearts_slot_0,Y
ROM2:A503 STA var_14
ROM2:A504 INY
ROM2:A505 LDA saved_hearts_slot_0,Y
ROM2:A506 STA var_15
ROM2:A507 LDY #$C
ROM2:A508 JSR update_hud_hearts
ROM2:A509 INC current_save_slot
ROM2:A50A INC task_state
ROM2:A50B RTS
 
Subroutine task0_MainMenu_6
ROM2:A51E task0_MainMenu_6:
ROM2:A51E LDY #$12
 
ROM2:A51F loop1:
ROM2:A51F LDA byte_A274,Y
ROM2:A520 STA ppu_command_buffer,Y
ROM2:A521 DEY
ROM2:A522 BPL loop1
ROM2:A523 LDA #0
ROM2:A524 STA var_10
ROM2:A525 LDA #3
ROM2:A526 STA var_11
 
ROM2:A527 loop2:
ROM2:A527 LDY var_10
ROM2:A528 LDA deaths_per_save_slot,Y
ROM2:A529 JSR convert_number_to_string ; Convert A to digits in var_1, var_2 and var_3. Leading
  ; zeroes are set to 0x24. A = var_2 (tens digit), Y = var_1 (hundreds digit).
ROM2:A52A LDX var_11
ROM2:A52B LDA var_1
ROM2:A52C STA ppu_command_buffer,X
ROM2:A52D LDA var_2
ROM2:A52E STA ppu_command_buffer_01,X
ROM2:A52F LDA var_3
ROM2:A530 BNE loc_A562
ROM2:A531 LDA var_1
ROM2:A532 CMP #$24
ROM2:A533 BNE loc_A560
ROM2:A534 LDA var_2
ROM2:A535 CMP #$24
ROM2:A536 BNE loc_A560
ROM2:A537 LDY var_10
ROM2:A538 LDA byte_633,Y
ROM2:A539 BNE loc_A560
ROM2:A53A LDA #$24
ROM2:A53B BNE loc_A562
 
ROM2:A560 loc_A560:
ROM2:A560 LDA #0
 
ROM2:A562 loc_A562:
ROM2:A562 STA ppu_command_buffer_02,X
ROM2:A563 TXA
ROM2:A564 CLC
ROM2:A565 ADC #6
ROM2:A566 STA var_11
ROM2:A567 INC var_10
ROM2:A568 LDA var_10
ROM2:A569 CMP #3
ROM2:A56A BNE loop2
ROM2:A56B LDY #$FF
ROM2:A56C STY current_save_slot
ROM2:A56D STY overworld_return_pos
 
ROM2:A56E loop3:
ROM2:A56E INY
ROM2:A56F INC current_save_slot
ROM2:A570 LDA byte_633,Y
ROM2:A571 BEQ loop3
ROM2:A572 LDA #0
ROM2:A573 STA task_state ; Set to 0
ROM2:A574 INC active_game_mode_task ; Set to 1
ROM2:A575 RTS
 
ROM2:A589 byte_A589: .BYTE $F3
ROM2:A58A   .BYTE 3
ROM2:A58B   .BYTE $28
ROM2:A58C byte_A58C: .BYTE $5C
ROM2:A58D   .BYTE $74
ROM2:A58E   .BYTE $8C
ROM2:A58F   .BYTE $A8
ROM2:A590   .BYTE $B8
 
Subroutine task1_MainMenu
ROM2:A591 task1_MainMenu:
ROM2:A591 LDA task_state
ROM2:A592 JSR call_jump_table
 
ROM2:A593   .WORD task1_MainMenu_state_0
ROM2:A595   .WORD task1_MainMenu_state_1
 
Subroutine task1_MainMenu_state_0
ROM2:A59A task1_MainMenu_state_0:
 
ROM2:A59A LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:A59B AND #ControllerBits_Start
ROM2:A59C BNE loc_A5DC
ROM2:A59D LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:A59E AND #ControllerBits_Select
ROM2:A59F BEQ loc_A5B7
 
ROM2:A5A6 loc_A5A6:
ROM2:A5A6 LDA #Sound1_Rupee
ROM2:A5A7 STA play_sound_1 ; Main menu change
ROM2:A5A8 INC current_save_slot
ROM2:A5A9 LDA current_save_slot
ROM2:A5AA CMP #5
ROM2:A5AB BNE loc_A5B7
ROM2:A5AC LDA #0
ROM2:A5AD STA current_save_slot
 
ROM2:A5B7 loc_A5B7:
ROM2:A5B7 LDY current_save_slot
ROM2:A5B8 LDA byte_633,Y
ROM2:A5B9 BEQ loc_A5A6
ROM2:A5BA LDY #2
 
ROM2:A5C0 loc_A5C0:
ROM2:A5C0 LDA byte_A589,Y
ROM2:A5C1 STA sprite_oam_data.tile,Y
ROM2:A5C2 DEY
ROM2:A5C3 BPL loc_A5C0
ROM2:A5C4 LDY current_save_slot
ROM2:A5C5 LDA byte_A58C,Y
ROM2:A5C6 STA sprite_oam_data.y_pos
ROM2:A5C7 LDA #$58
ROM2:A5C8 STA var_1
ROM2:A5C9 LDA #$30
ROM2:A5CA STA var_0
ROM2:A5CB JMP loc_A638
 
ROM2:A5DC loc_A5DC:
ROM2:A5DC INC task_state
ROM2:A5DD RTS
 
Subroutine task1_MainMenu_state_1
ROM2:A5DF task1_MainMenu_state_1:
ROM2:A5DF LDA #0
ROM2:A5E0 STA audio_misc_0607
ROM2:A5E1 LDA #0
ROM2:A5E2 STA dungeon_idx ; set dungeon_idx = overworld
ROM2:A5E3 STA current_item
ROM2:A5E4 JSR clear_ppumask
ROM2:A5E5 LDA current_save_slot
ROM2:A5E6 CMP #3
ROM2:A5E7 BCC loc_A5FE ; save slot <= 2
ROM2:A5E8 LDA current_save_slot
ROM2:A5E9 CLC
ROM2:A5EA ADC #11 ; slot 3 = E (create save), 4 = F (delete save)
ROM2:A5EB STA game_mode ; set GameMode_CreateSave or GameMode_DeleteSave
ROM2:A5EC JMP clear_game_mode_task_and_state
 
ROM2:A5FE loc_A5FE:
ROM2:A5FE JSR clear_ppumask
ROM2:A5FF JSR sub_106DF1
ROM2:A600 LDY #$27
 
ROM2:A606 loc_A606:
ROM2:A606 LDA (0),Y
ROM2:A607 STA sword_type,Y
ROM2:A608 DEY
ROM2:A609 BPL loc_A606
ROM2:A60A LDA #0
ROM2:A60B STA sword_disabled_by_bubble ; set to 0
ROM2:A60C STA walk_state_and_weapon_state ; set to 0
ROM2:A60D STA clock_active ; set to 0
ROM2:A60E TAY
 
ROM2:A619 loc_A619:
ROM2:A619 LDA (2),Y
ROM2:A61A STA (var_14),Y
ROM2:A61B INC var_2
ROM2:A61C BNE loc_A623
ROM2:A61D INC var_3
 
ROM2:A623 loc_A623:
ROM2:A623 INC var_14
ROM2:A624 BNE loc_A629
ROM2:A625 INC var_15
 
ROM2:A629 loc_A629:
ROM2:A629 LDA var_14
ROM2:A62A CMP #$FF
ROM2:A62B BNE loc_A619
ROM2:A62C LDA var_15
ROM2:A62D CMP #7
ROM2:A62E BNE loc_A619
ROM2:A62F JMP increment_game_mode
 
Function chunk for task1_MainMenu_state_0
ROM2:A638 loc_A638:
ROM2:A638 LDA #8
ROM2:A639 STA var_2
ROM2:A63A LDA #$A
ROM2:A63B STA var_3
ROM2:A63C LDA #0
ROM2:A63D JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM2:A63E LDA #8
ROM2:A63F STA updating_oam_sprite_id_1
 
ROM2:A64A loc_A64A:
ROM2:A64A LDA updating_oam_sprite_id_1
ROM2:A64B CLC
ROM2:A64C ADC #8
ROM2:A64D STA updating_oam_sprite_id_1
ROM2:A64E CLC
ROM2:A64F ADC #4
ROM2:A650 STA updating_oam_sprite_id_2
ROM2:A651 LDA #1
ROM2:A652 STA var_7 ; Set to 1
ROM2:A653 LDA #8
ROM2:A654 STA var_10
ROM2:A655 LDA var_0
ROM2:A656 PHA
ROM2:A657 JSR simple_update_sprite ; Update a sprite.
 
  ; updating_oam_sprite_id_1: the sprite_oam_data offset
  ; to update (always a multiple of 4).
  ; updating_oam_sprite_id_2: If updating two sprite, the
  ; second sprite_oam_data offset to update.
  ; var_0: X position
  ; var_1: Y position
  ; var_7: number of sprites to update (1 or 2)
  ; var_2[n]: tile number for sprite n
  ; var_4[n]: tile attributes for sprite n
  ; var_10: distance from first sprite X to second sprite X
ROM2:A658 TAX
ROM2:A659 PLA
ROM2:A65A STA var_0
ROM2:A65B LDY var_4
ROM2:A65C LDA quest_no,Y
ROM2:A65D BEQ loc_A68F
ROM2:A65E LDY updating_oam_sprite_id_1
ROM2:A65F LDA var_1
ROM2:A660 SEC
ROM2:A661 SBC #3
ROM2:A662 STA sprite_oam_data_80,Y
ROM2:A663 LDA #$20
ROM2:A664 STA sprite_oam_data_81,Y
ROM2:A665 LDA #3
ROM2:A666 STA sprite_oam_data_82,Y
ROM2:A667 LDA var_0
ROM2:A668 CLC
ROM2:A669 ADC #$C
ROM2:A66A STA sprite_oam_data_83,Y
 
ROM2:A68F loc_A68F:
ROM2:A68F LDA var_1
ROM2:A690 CLC
ROM2:A691 ADC #$18
ROM2:A692 STA var_1
ROM2:A693 INC var_4
ROM2:A694 INC var_5
ROM2:A695 LDA var_4
ROM2:A696 CMP #3
ROM2:A697 BNE loc_A64A
ROM2:A698 RTS
 
ROM2:A6A1 save_slot_idxs_lo: .BYTE $50 ; Low and high byte of pointers to save slot data, 0x0650, 0x0652, 0x0652
ROM2:A6A2   .BYTE $52
ROM2:A6A3 byte_A6A3: .BYTE $54
ROM2:A6A4 save_slot_idxs_high: .BYTE 6
ROM2:A6A5   .BYTE 6
ROM2:A6A6   .BYTE 6
ROM2:A6A7   .BYTE $38
ROM2:A6A8   .BYTE $40
ROM2:A6A9   .BYTE $48
ROM2:A6AA   .BYTE 6
ROM2:A6AB   .BYTE 6
ROM2:A6AC   .BYTE 6
 
Subroutine task1_EndCredits
ROM2:A6AD task1_EndCredits:
ROM2:A6AD LDA task_state
ROM2:A6AE JSR call_jump_table
 
ROM2:A6AF   .WORD task1_EndCredits_0
ROM2:A6B1   .WORD task1_EndCredits_1
ROM2:A6B3   .WORD set_game_mode_title_state_1 ; Set game_mode to the title screen, state 1. This actually
  ; skips the title screen and goes to the main menu.
 
Subroutine task1_EndCredits_0
ROM2:A6B8 task1_EndCredits_0:
ROM2:A6B8 JSR sub_9D2A
ROM2:A6B9 JSR sub_A437
ROM2:A6BA JSR sub_9D2A
ROM2:A6BB JSR $6DF1
ROM2:A6BC LDY #$27
 
ROM2:A6C6 loc_A6C6:
ROM2:A6C6 LDA sword_type,Y
ROM2:A6C7 STA (object_knockback),Y
ROM2:A6C8 DEY
ROM2:A6C9 BPL loc_A6C6
ROM2:A6CA LDY current_save_slot
ROM2:A6CB LDA deaths_per_save_slot,Y
ROM2:A6CC LDY #0
ROM2:A6CD STA (object_knockback_10),Y
ROM2:A6CE LDA #1
ROM2:A6CF STA (object_knockback_6),Y
ROM2:A6D0 LDY current_save_slot
ROM2:A6D1 STA byte_633,Y
ROM2:A6D2 LDA quest_no,Y
ROM2:A6D3 LDY #0
ROM2:A6D4 STA (object_knockback_12),Y
ROM2:A6D5 JSR sub_A80C
ROM2:A6D6 LDY #7
 
ROM2:A6EC loc_A6EC:
ROM2:A6EC LDA (var_12),Y
ROM2:A6ED STA (object_knockback_4),Y
ROM2:A6EE DEY
ROM2:A6EF BPL loc_A6EC
ROM2:A6F0 LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM2:A6F1 AND #$F0 ; (hearts & 0xF) >> 4: get max hearts
ROM2:A6F2 PHA
ROM2:A6F3 LSR A
ROM2:A6F4 LSR A
ROM2:A6F5 LSR A
ROM2:A6F6 LSR A
ROM2:A6F7 STA var_10
ROM2:A6F8 PLA ; pop original A
ROM2:A6F9 ORA var_10 ; set current hearts to max hearts
ROM2:A6FA STA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM2:A6FB LDA #$FF ; fill partial heart
ROM2:A6FC STA partial_heart ; Half heart if < 0x80, and a timer for potion refills
ROM2:A6FD JSR copy_hearts ; Copy hearts and partial_hearts to 0x0650, 0x0652 or 0x0654 depending on save slot
ROM2:A6FE LDY #0
 
ROM2:A70F loc_A70F: ; Copy state to save data scratch space
ROM2:A70F LDA (var_14),Y
ROM2:A710 STA (object_knockback_2),Y ; (Is this alternating buffers for atomic writes?)
ROM2:A711 INC object_knockback_2
ROM2:A712 BNE loc_A719
ROM2:A713 INC object_knockback_3
 
ROM2:A719 loc_A719:
ROM2:A719 INC var_14
ROM2:A71A BNE loc_A71F
ROM2:A71B INC var_15
 
ROM2:A71F loc_A71F:
ROM2:A71F LDA var_14
ROM2:A720 CMP #$FF
ROM2:A721 BNE loc_A70F
ROM2:A722 LDA var_15
ROM2:A723 CMP #7
ROM2:A724 BNE loc_A70F
ROM2:A725 JSR sub_9D2A
ROM2:A726 JSR sub_A3C8
ROM2:A727 INC task_state
ROM2:A728 RTS
 
Subroutine task1_EndCredits_1
ROM2:A734 task1_EndCredits_1:
ROM2:A734 LDY current_save_slot
ROM2:A735 LDA byte_2652A,Y
ROM2:A736 BNE loc_A757
ROM2:A737 JSR sub_9D2A
ROM2:A738 JSR sub_A3E1
ROM2:A739 LDA current_save_slot
ROM2:A73A ASL A
ROM2:A73B TAY
ROM2:A73C LDA loc_106D9C,Y
ROM2:A73D CMP byte_CE
ROM2:A73E BNE loc_A75A
ROM2:A73F INY
ROM2:A740 LDA loc_106D9C,Y
ROM2:A741 CMP byte_CF
ROM2:A742 BNE loc_A75A
ROM2:A743 JSR sub_A764
 
ROM2:A757 loc_A757:
ROM2:A757 INC task_state
ROM2:A758 RTS
 
ROM2:A75A loc_A75A:
ROM2:A75A LDY current_save_slot
ROM2:A75B LDA #$FF
ROM2:A75C STA byte_2652A,Y
ROM2:A75D INC task_state
ROM2:A75E RTS
 
Subroutine sub_A764
ROM2:A764 sub_A764:
ROM2:A764 LDY current_save_slot
ROM2:A765 LDA #0
ROM2:A766 STA byte_2651E,Y
ROM2:A767 STA byte_26521,Y
ROM2:A768 TYA
ROM2:A769 ASL A
ROM2:A76A TAY
ROM2:A76B LDA #0
ROM2:A76C STA byte_26524,Y
ROM2:A76D INY
ROM2:A76E STA byte_26524,Y
ROM2:A76F JSR sub_9D2A
ROM2:A770 JSR sub_106DF1
ROM2:A771 LDY #$27
 
ROM2:A782 loc_A782:
ROM2:A782 LDA (object_knockback),Y
ROM2:A783 STA (0),Y
ROM2:A784 DEY
ROM2:A785 BPL loc_A782
ROM2:A786 LDY #0
ROM2:A787 LDA (object_knockback_6),Y
ROM2:A788 STA (var_6),Y
ROM2:A789 LDA (object_knockback_8),Y
ROM2:A78A STA (var_8),Y
ROM2:A78B LDA (object_knockback_10),Y
ROM2:A78C STA (var_10),Y
ROM2:A78D LDA (object_knockback_12),Y
ROM2:A78E STA (var_12),Y
ROM2:A78F LDA (var_6),Y
ROM2:A790 PHA
ROM2:A791 LDA (var_10),Y
ROM2:A792 PHA
ROM2:A793 LDA (var_12),Y
ROM2:A794 PHA
ROM2:A795 LDY current_save_slot
ROM2:A796 PLA
ROM2:A797 STA quest_no,Y
ROM2:A798 PLA
ROM2:A799 STA deaths_per_save_slot,Y
ROM2:A79A PLA
ROM2:A79B STA byte_633,Y
ROM2:A79C LDY #7
 
ROM2:A7B4 loc_A7B4:
ROM2:A7B4 LDA (object_knockback_4),Y
ROM2:A7B5 STA (var_4),Y
ROM2:A7B6 DEY
ROM2:A7B7 BPL loc_A7B4
ROM2:A7B8 LDY #0
 
ROM2:A7BD loc_A7BD:
ROM2:A7BD LDA (object_knockback_2),Y
ROM2:A7BE STA (var_2),Y
ROM2:A7BF INC var_2
ROM2:A7C0 BNE loc_A7C7
ROM2:A7C1 INC var_3
 
ROM2:A7C7 loc_A7C7:
ROM2:A7C7 INC object_knockback_2
ROM2:A7C8 BNE loc_A7CD
ROM2:A7C9 INC object_knockback_3
 
ROM2:A7CD loc_A7CD:
ROM2:A7CD INC var_14
ROM2:A7CE BNE loc_A7D3
ROM2:A7CF INC var_15
 
ROM2:A7D3 loc_A7D3:
ROM2:A7D3 LDA var_14
ROM2:A7D4 CMP #$FF
ROM2:A7D5 BNE loc_A7BD
ROM2:A7D6 LDA var_15
ROM2:A7D7 CMP #7
ROM2:A7D8 BNE loc_A7BD
ROM2:A7D9 LDY current_save_slot
ROM2:A7DA LDA #$5A
ROM2:A7DB STA byte_2651E,Y
ROM2:A7DC LDA #$A5
ROM2:A7DD STA byte_26521,Y
ROM2:A7DE TYA
ROM2:A7DF ASL A
ROM2:A7E0 TAY
ROM2:A7E1 LDA loc_106D9C,Y
ROM2:A7E2 STA byte_26524,Y
ROM2:A7E3 INY
ROM2:A7E4 LDA loc_106D9C,Y
ROM2:A7E5 STA byte_26524,Y
ROM2:A7E6 LDY current_save_slot
ROM2:A7E7 LDA #$FF
ROM2:A7E8 STA byte_2652A,Y
ROM2:A7E9 RTS
 
Subroutine set_game_mode_title_state_1
; Set game_mode to the title screen, state 1. This actually ; skips the title screen and goes to the main menu.
ROM2:A803 set_game_mode_title_state_1:
ROM2:A803 LDA #GameMode_Title
ROM2:A804 STA game_mode ; set GameMode_Title
ROM2:A805 LDA #1
ROM2:A806 STA task_state
ROM2:A807 RTS
 
Subroutine sub_A80C
ROM2:A80C sub_A80C:
ROM2:A80C LDY current_save_slot
ROM2:A80D LDA $A6A7,Y
ROM2:A80E STA var_12
ROM2:A80F LDA $A6AA,Y
ROM2:A810 STA var_13
ROM2:A811 RTS
 
Subroutine copy_hearts
; Copy hearts and partial_hearts to 0x0650, 0x0652 or 0x0654 depending on save slot
ROM2:A819 copy_hearts:
ROM2:A819 LDY current_save_slot
ROM2:A81A LDA save_slot_idxs_lo,Y
ROM2:A81B STA var_12
ROM2:A81C LDA save_slot_idxs_high,Y
ROM2:A81D STA var_13
ROM2:A81E LDY #1
 
ROM2:A81F copy_hearts_loop: ; 0xF0 = max hearts, 0x0F = current hearts
ROM2:A81F LDA hearts,Y
ROM2:A820 STA (var_12),Y
ROM2:A821 DEY
ROM2:A822 BPL copy_hearts_loop
ROM2:A823 RTS
 
ROM2:A824 Skipped empty chunk
Function chunk for task0_FoundZelda
ROM2:A824 secondary_FoundZelda_main:
ROM2:A824 LDA task_state
ROM2:A825 JSR call_jump_table
 
ROM2:A826   .WORD task0_FoundZelda_0
ROM2:A828   .WORD task0_FoundZelda_1
ROM2:A82A   .WORD task0_FoundZelda_2
ROM2:A82C   .WORD task0_FoundZelda_3
ROM2:A82E   .WORD task0_FoundZelda_4
 
Subroutine task0_FoundZelda_0
ROM2:A90F task0_FoundZelda_0:
ROM2:A90F JSR loc_A921
ROM2:A910 LDA task_state
ROM2:A911 BEQ locret_A958
ROM2:A912 JSR clear_oam ; Clear the OAM buffer.
ROM2:A913 JSR reset_animation_frame_update_link_sprite_and_check_ladder ; Like update_link_sprite_and_check_ladder, but reset the animation
  ; timer first.
ROM2:A914 LDX #1
ROM2:A915 JMP update_sprite_zelda_wall_trap
 
ROM2:A921 loc_A921:
ROM2:A921 LDA enemy_action_timers
ROM2:A922 BNE ret
ROM2:A923 LDA current_music ; Setting to 0 stops the music in place, leaving any note that was playing running
ROM2:A924 BNE ret
ROM2:A925 JSR call_update_curtain_from_rom2 ; Call update_curtain, and return to ROM2.
ROM2:A926 LDA object_x_12
ROM2:A927 CMP #$11
ROM2:A928 BCS ret
ROM2:A929 LDA #$80
ROM2:A92A STA enemy_action_timers
ROM2:A92B INC task_state
 
ROM2:A92C ret:
ROM2:A92C RTS
 
ROM2:A92D   .BYTE $23
ROM2:A92E   .BYTE $D8
ROM2:A92F   .BYTE $68
ROM2:A930   .BYTE 0
ROM2:A931   .BYTE $FF
 
Subroutine task0_FoundZelda_1
ROM2:A93F task0_FoundZelda_1:
ROM2:A93F LDY #4
 
ROM2:A941 loc_A941:
ROM2:A941 LDA $A93A,Y
ROM2:A942 STA $302,Y
ROM2:A943 DEY
ROM2:A944 BPL loc_A941
ROM2:A945 LDA #$A4
ROM2:A946 STA enemy_state_2_1
ROM2:A947 LDA #0
ROM2:A948 STA byte_416
ROM2:A949 STA global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM2:A94A INC task_state
 
Function chunk for task0_FoundZelda
ROM2:A958 locret_A958:
ROM2:A958 RTS
 
ROM2:A959
Subroutine task0_FoundZelda_2
ROM2:A97F task0_FoundZelda_2:
ROM2:A97F JSR task0_FoundZelda_2_0
ROM2:A980 LDA global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM2:A981 BEQ ret
ROM2:A982 LDA #80
ROM2:A983 STA npc_action_timer_1 ; Set to 80.
ROM2:A984 INC task_state
 
ROM2:A985 ret:
ROM2:A985 RTS
 
ROM2:A98D byte_A98D: .BYTE $21
ROM2:A98E   .BYTE $A4
ROM2:A98F   .BYTE 1
ROM2:A990   .BYTE $24
ROM2:A991   .BYTE $FF
ROM2:A992 byte_A992: .BYTE $C4
ROM2:A993   .BYTE $E4
ROM2:A994   .BYTE $A4
 
Subroutine task0_FoundZelda_2_0
ROM2:A995 task0_FoundZelda_2_0:
ROM2:A995 JSR reset_animation_frame_update_link_sprite_and_check_ladder ; Like update_link_sprite_and_check_ladder, but reset the animation
  ; timer first.
ROM2:A996 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM2:A997 BNE locret_A9F4
ROM2:A998 LDA #6
ROM2:A999 STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM2:A99A LDY #4
 
ROM2:A99B loop:
ROM2:A99B LDA byte_A98D,Y
ROM2:A99C STA ppu_command_buffer,Y
ROM2:A99D DEY
ROM2:A99E BPL loop
 
ROM2:A99F loop2:
ROM2:A99F LDA enemy_state_2_1
ROM2:A9A0 STA ppu_command_buffer_01
ROM2:A9A1 INC enemy_state_2_1
ROM2:A9A2 LDA #$59
ROM2:A9A3 STA var_0
ROM2:A9A4 LDA #$A9
ROM2:A9A5 STA var_1
ROM2:A9A6 LDY byte_416
ROM2:A9A7 INC byte_416
ROM2:A9A8 LDA (var_0),Y
ROM2:A9A9 AND #$3F
ROM2:A9AA CMP #$25
ROM2:A9AB BEQ loop2
ROM2:A9AC STA ppu_command_buffer_03
ROM2:A9AD LDA #Sound3_GainRupee
ROM2:A9AE STA play_sound_3 ; Play Sound3_GainRupee
ROM2:A9AF LDA (0),Y
ROM2:A9B0 AND #$C0
ROM2:A9B1 BEQ locret_A9F4
ROM2:A9B2 LDY #2
ROM2:A9B3 CMP #$C0
ROM2:A9B4 BEQ loc_A9E4
ROM2:A9B5 DEY
ROM2:A9B6 CMP #$40
ROM2:A9B7 BEQ loc_A9E4
ROM2:A9B8 DEY
 
ROM2:A9E4 loc_A9E4:
ROM2:A9E4 LDA byte_A992,Y
ROM2:A9E5 STA enemy_state_2_1
ROM2:A9E6 CPY #2
ROM2:A9E7 BNE locret_A9F4
ROM2:A9E8 INC global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM2:A9E9 LDA #0
ROM2:A9EA STA walk_state_and_weapon_state
 
ROM2:A9F4 locret_A9F4:
ROM2:A9F4 RTS
 
Subroutine task0_FoundZelda_3
ROM2:A9F5 task0_FoundZelda_3:
ROM2:A9F5 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM2:A9F6 BNE locret_A9F4
ROM2:A9F7 JSR stop_sounds
ROM2:A9F8 INC task_state
ROM2:A9F9 RTS
 
Subroutine task0_FoundZelda_4
ROM2:A9FF task0_FoundZelda_4:
ROM2:A9FF LDA #8
ROM2:AA00 STA found_zelda_cutscene_state_1 ; Set to 8.
ROM2:AA01 JSR start_task1 ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
ROM2:AA02 STA enemy_state_0 ; Set to 0.
ROM2:AA03 STA byte_413 ; Set to 0.
ROM2:AA04 JMP clear_oam ; Clear the OAM buffer.
 
Subroutine task1_FoundZelda
ROM2:AA10 task1_FoundZelda:
ROM2:AA10 LDA task_state
ROM2:AA11 JSR call_jump_table
 
ROM2:AA12   .WORD task1_FoundZelda_0
ROM2:AA14   .WORD task1_FoundZelda_1
ROM2:AA16   .WORD task1_FoundZelda_1
ROM2:AA18   .WORD task1_FoundZelda_3
ROM2:AA1A   .WORD task1_FoundZelda_4
 
ROM2:AA1F byte_AA1F: .BYTE $F
ROM2:AA20   .BYTE $12
ROM2:AA21   .BYTE $16
ROM2:AA22   .BYTE $2A
 
Subroutine task1_FoundZelda_0
ROM2:AA23 task1_FoundZelda_0:
ROM2:AA23 JSR clear_oam ; Clear the OAM buffer.
ROM2:AA24 INC picking_up_item_timer
ROM2:AA25 LDA picking_up_item_timer
ROM2:AA26 CMP #$C0
ROM2:AA27 BEQ loc_AA50
ROM2:AA28 JSR task1_FoundZelda_0_0
 
ROM2:AA33 loc_AA33:
ROM2:AA33 LDX picking_up_item_timer
ROM2:AA34 CPX #$40
ROM2:AA35 BCC locret_AA4F
ROM2:AA36 LDY #$23
 
ROM2:AA37 loop:
ROM2:AA37 LDA ppu_data_for_current_dungeon,Y
ROM2:AA38 STA ppu_command_buffer,Y
ROM2:AA39 DEY
ROM2:AA3A BPL loop
ROM2:AA3B TXA
ROM2:AA3C AND #3
ROM2:AA3D TAX
ROM2:AA3E LDA byte_AA1F,X
ROM2:AA3F STA ppu_command_buffer_13
 
ROM2:AA4F locret_AA4F:
ROM2:AA4F RTS
 
ROM2:AA50 loc_AA50:
ROM2:AA50 LDA #Music_Dead
ROM2:AA51 STA play_music ; Play Music_Dead
ROM2:AA52 LDA #$40
ROM2:AA53 STA enemy_action_timers
ROM2:AA54 LDA #$40
ROM2:AA55 STA leever_timer
ROM2:AA56 INC task_state
ROM2:AA57 JMP loc_AA33
 
Subroutine task1_FoundZelda_0_0
ROM2:AA62 task1_FoundZelda_0_0:
ROM2:AA62 LDA object_x
ROM2:AA63 STA floor_item_x
ROM2:AA64 LDA object_y
ROM2:AA65 SEC
ROM2:AA66 SBC #$10
ROM2:AA67 STA floor_item_y
ROM2:AA68 LDX #0
ROM2:AA69 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM2:AA6A JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM2:AA6B STA var_12
ROM2:AA6C LDA #$48
ROM2:AA6D STA updating_oam_sprite_id_1
ROM2:AA6E LDA #$4C
ROM2:AA6F STA updating_oam_sprite_id_2
ROM2:AA70 LDY #$21
ROM2:AA71 JSR loc_10792C
ROM2:AA72 LDA #$1B
ROM2:AA73 LDX #$13
ROM2:AA74 JSR setup_sprite
ROM2:AA75 LDX #1
ROM2:AA76 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM2:AA77 TXA
ROM2:AA78 JSR update_object_sprite_vertical
ROM2:AA79 LDA object_x_1
ROM2:AA7A STA object_x_2
ROM2:AA7B LDA object_y_1
ROM2:AA7C SEC
ROM2:AA7D SBC #$10
ROM2:AA7E STA object_y_2
ROM2:AA7F LDX #2
ROM2:AA80 LDA #$1B
ROM2:AA81 JSR setup_sprite
ROM2:AA82 RTS
 
Subroutine task1_FoundZelda_1
ROM2:AAA9 task1_FoundZelda_1:
ROM2:AAA9 LDA leever_timer
ROM2:AAAA BEQ switch_palette_and_advance_task_state
ROM2:AAAB JSR clear_oam ; Clear the OAM buffer.
ROM2:AAAC LDA leever_timer
ROM2:AAAD CMP #4
ROM2:AAAE BCC ret
ROM2:AAAF JSR task1_FoundZelda_0_0
ROM2:AAB0 LDA task_state
ROM2:AAB1 CMP #1
ROM2:AAB2 BNE ret
ROM2:AAB3 LDA enemy_action_timers
ROM2:AAB4 BNE ret
ROM2:AAB5 JSR task1_FoundZelda_1_0
 
ROM2:AAB6 ret:
ROM2:AAB6 RTS
 
ROM2:AAB7 switch_palette_and_advance_task_state:
ROM2:AAB7 LDA #PPUCommandIndices_FoundZeldaPalette
ROM2:AAB8 STA current_ppu_command_index ; Set to PPUCommandIndices_FoundZeldaPalette.
ROM2:AAB9 INC task_state
ROM2:AABA RTS
 
ROM2:AACE byte_AACE: .BYTE $22
ROM2:AACF   .BYTE $A4
ROM2:AAD0   .BYTE 1
ROM2:AAD1   .BYTE $24
ROM2:AAD2   .BYTE $FF
ROM2:AAD3 byte_AAD3: .BYTE $AC
ROM2:AAD4   .BYTE $AD
ROM2:AAD5   .BYTE $AE
ROM2:AAD6   .BYTE $AF
ROM2:AAD7   .BYTE $B0
ROM2:AAD8   .BYTE $B1
ROM2:AAD9   .BYTE $B2
ROM2:AADA   .BYTE $B3
ROM2:AADB   .BYTE $E4
ROM2:AADC   .BYTE $E5
ROM2:AADD   .BYTE $E6
ROM2:AADE   .BYTE $E7
ROM2:AADF   .BYTE $E8
ROM2:AAE0   .BYTE $E9
ROM2:AAE1   .BYTE $EA
ROM2:AAE2   .BYTE $EB
ROM2:AAE3   .BYTE $EC
ROM2:AAE4   .BYTE $ED
ROM2:AAE5   .BYTE $EE
ROM2:AAE6   .BYTE $EF
ROM2:AAE7   .BYTE $F0
ROM2:AAE8   .BYTE $F1
ROM2:AAE9   .BYTE $F2
ROM2:AAEA   .BYTE $F3
ROM2:AAEB   .BYTE $F4
ROM2:AAEC   .BYTE $F5
ROM2:AAED   .BYTE $F6
ROM2:AAEE   .BYTE $F7
ROM2:AAEF   .BYTE $F8
ROM2:AAF0   .BYTE $F9
ROM2:AAF1   .BYTE $FA
ROM2:AAF2   .BYTE $FB
ROM2:AAF3   .BYTE $46
ROM2:AAF4   .BYTE $47
ROM2:AAF5   .BYTE $48
ROM2:AAF6   .BYTE $49
ROM2:AAF7   .BYTE $4A
ROM2:AAF8   .BYTE $4B
ROM2:AAF9   .BYTE $4C
ROM2:AAFA   .BYTE $4D
ROM2:AAFB   .BYTE $4E
ROM2:AAFC   .BYTE $4F
ROM2:AAFD   .BYTE $50
ROM2:AAFE   .BYTE $51
ROM2:AAFF   .BYTE $52
ROM2:AB00   .BYTE $53
ROM2:AB01   .BYTE $54
ROM2:AB02   .BYTE $55
ROM2:AB03   .BYTE $56
ROM2:AB04   .BYTE $57
ROM2:AB05   .BYTE $58
ROM2:AB06   .BYTE $59
ROM2:AB07 byte_AB07: .BYTE $F
ROM2:AB08   .BYTE $12
ROM2:AB09   .BYTE $17
ROM2:AB0A   .BYTE $A
ROM2:AB0B   .BYTE $15
ROM2:AB0C   .BYTE $15
ROM2:AB0D   .BYTE $22
ROM2:AB0E   .BYTE $28
ROM2:AB0F   .BYTE $19
ROM2:AB10   .BYTE $E
ROM2:AB11   .BYTE $A
ROM2:AB12   .BYTE $C
ROM2:AB13   .BYTE $E
ROM2:AB14   .BYTE $24
ROM2:AB15   .BYTE $1B
ROM2:AB16   .BYTE $E
ROM2:AB17   .BYTE $1D
ROM2:AB18   .BYTE $1E
ROM2:AB19   .BYTE $1B
ROM2:AB1A   .BYTE $17
ROM2:AB1B   .BYTE $1C
ROM2:AB1C   .BYTE $24
ROM2:AB1D   .BYTE $1D
ROM2:AB1E   .BYTE $18
ROM2:AB1F   .BYTE $24
ROM2:AB20   .BYTE $11
ROM2:AB21   .BYTE $22
ROM2:AB22   .BYTE $1B
ROM2:AB23   .BYTE $1E
ROM2:AB24   .BYTE $15
ROM2:AB25   .BYTE $E
ROM2:AB26   .BYTE $2C
ROM2:AB27   .BYTE $1D
ROM2:AB28   .BYTE $11
ROM2:AB29   .BYTE $12
ROM2:AB2A   .BYTE $1C
ROM2:AB2B   .BYTE $24
ROM2:AB2C   .BYTE $E
ROM2:AB2D   .BYTE $17
ROM2:AB2E   .BYTE $D
ROM2:AB2F   .BYTE $1C
ROM2:AB30   .BYTE $24
ROM2:AB31   .BYTE $1D
ROM2:AB32   .BYTE $11
ROM2:AB33   .BYTE $E
ROM2:AB34   .BYTE $24
ROM2:AB35   .BYTE $1C
ROM2:AB36   .BYTE $1D
ROM2:AB37   .BYTE $18
ROM2:AB38   .BYTE $1B
ROM2:AB39   .BYTE $22
ROM2:AB3A   .BYTE $2C
ROM2:AB3B   .BYTE $FF
 
Subroutine task1_FoundZelda_1_0
ROM2:AB3C task1_FoundZelda_1_0:
ROM2:AB3C INC enemy_state_0
ROM2:AB3D LDA enemy_state_0
ROM2:AB3E AND #7
ROM2:AB3F CMP #4
ROM2:AB40 BNE ret
ROM2:AB41 LDY #4
 
ROM2:AB42 loop:
ROM2:AB42 LDA byte_AACE,Y
ROM2:AB43 STA ppu_command_buffer,Y
ROM2:AB44 DEY
ROM2:AB45 BPL loop
ROM2:AB46 LDY byte_413
ROM2:AB47 LDA byte_AB07,Y
ROM2:AB48 CMP #$FF
ROM2:AB49 BEQ increase_task_state_and_return
ROM2:AB4A STA ppu_command_buffer_03
ROM2:AB4B CMP #$24
ROM2:AB4C BEQ skip_playing_sound
ROM2:AB4D LDA #Sound3_GainRupee
ROM2:AB4E STA play_sound_3 ; Play Sound3_GainRupee
 
ROM2:AB4F skip_playing_sound:
ROM2:AB4F INC byte_413
ROM2:AB50 LDA byte_AAD3,Y
ROM2:AB51 STA ppu_command_buffer_01
ROM2:AB52 CMP #$A0
ROM2:AB53 BCS ret
ROM2:AB54 LDA #$23
ROM2:AB55 STA ppu_command_buffer
 
ROM2:AB56 ret:
ROM2:AB56 RTS
 
ROM2:AB57 increase_task_state_and_return:
ROM2:AB57 INC task_state
 
ROM2:AB7E locret_AB7E:
ROM2:AB7E RTS
 
Subroutine task1_FoundZelda_4
ROM2:AB7F task1_FoundZelda_4:
 
ROM2:AB7F JSR clear_oam ; Clear the OAM buffer.
ROM2:AB80 LDX #2
ROM2:AB81 LDA #120
ROM2:AB82 STA object_x,X
ROM2:AB83 LDA #136
ROM2:AB84 STA object_y,X
ROM2:AB85 LDA #$E
ROM2:AB86 JSR setup_sprite
ROM2:AB87 LDX #2
ROM2:AB88 LDA #ObjectType_Ganon
ROM2:AB89 STA object_type,X ; Set to ObjectType_Ganon
ROM2:AB8A JSR sub_ABB8
ROM2:AB8B LDA enemy_action_timers
ROM2:AB8C BNE locret_AB7E
ROM2:AB8D LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM2:AB8E AND #ControllerBits_Start
ROM2:AB8F BEQ locret_AB7E
ROM2:AB90 JSR clear_game_mode_task_and_state
ROM2:AB91 LDA #GameMode_EndCredits
ROM2:AB92 STA game_mode ; Set GameMode_EndCredits after we found Zelda.
ROM2:AB93 JSR clear_ppumask
ROM2:AB94 JSR clear_nametables
ROM2:AB95 JSR stop_sounds
ROM2:AB96 JMP switch_save_slot_to_2nd_quest
 
Subroutine sub_ABB8
ROM2:ABB8 sub_ABB8:
ROM2:ABB8 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM2:ABB9 LDA #$B
ROM2:ABBA JMP update_object_sprite_horizontal
 
ROM2:ABC0 byte_ABC0: .BYTE 2
ROM2:ABC1   .BYTE 3
ROM2:ABC2 byte_ABC2: .BYTE $78
ROM2:ABC3   .BYTE 0
 
Subroutine task1_FoundZelda_3
ROM2:ABC4 task1_FoundZelda_3:
ROM2:ABC4 LDA found_zelda_cutscene_state_1
ROM2:ABC5 CMP #8
ROM2:ABC6 BMI loc_ABD6
ROM2:ABC7 LDA found_zelda_cutscene_state_1
ROM2:ABC8 SBC #8
ROM2:ABC9 STA found_zelda_cutscene_state_1
ROM2:ABCA JSR task1_FoundZelda_3_0
 
ROM2:ABD6 loc_ABD6:
ROM2:ABD6 LDA byte_58
ROM2:ABD7 CLC
ROM2:ABD8 ADC #$80
ROM2:ABD9 STA byte_58
ROM2:ABDA BCC loc_ABE2
ROM2:ABDB INC found_zelda_cutscene_state_1
 
ROM2:ABE2 loc_ABE2:
ROM2:ABE2 LDA desired_ppuscroll_y
ROM2:ABE3 ADC #0
ROM2:ABE4 STA desired_ppuscroll_y
ROM2:ABE5 CMP #$F0
ROM2:ABE6 LDA #0
ROM2:ABE7 BCC loc_ABF3
ROM2:ABE8 STA desired_ppuscroll_y
ROM2:ABE9 INC byte_E2
 
ROM2:ABF3 loc_ABF3:
ROM2:ABF3 ROL A
ROM2:ABF4 STA alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
ROM2:ABF5 LDY #0
ROM2:ABF6 LDX current_save_slot
ROM2:ABF7 LDA quest_no,X
ROM2:ABF8 BEQ loc_AC00
ROM2:ABF9 INY
 
ROM2:AC00 loc_AC00:
ROM2:AC00 LDA byte_E2
ROM2:AC01 CMP byte_ABC0,Y
ROM2:AC02 BCC locret_AC15
ROM2:AC03 LDA desired_ppuscroll_y
ROM2:AC04 CMP byte_ABC2,Y
ROM2:AC05 BCC locret_AC15
ROM2:AC06 INC task_state
ROM2:AC07 LDA #$40
ROM2:AC08 STA enemy_action_timers
 
ROM2:AC15 locret_AC15:
ROM2:AC15 RTS
 
ROM2:AC16 byte_AC16: .BYTE $28
ROM2:AC17   .BYTE $29
ROM2:AC18   .BYTE $2A
ROM2:AC19   .BYTE $2B
ROM2:AC1A   .BYTE $20
ROM2:AC1B   .BYTE $21
ROM2:AC1C   .BYTE $22
ROM2:AC1D   .BYTE $23
ROM2:AC1E   .BYTE $28
ROM2:AC1F   .BYTE $29
ROM2:AC20   .BYTE $2A
ROM2:AC21   .BYTE $2B
ROM2:AC22 byte_AC22: .BYTE $46
ROM2:AC23   .BYTE $10
ROM2:AC24   .BYTE $90
ROM2:AC25   .BYTE $84
ROM2:AC26   .BYTE $24
ROM2:AC27   .BYTE $30
ROM2:AC28   .BYTE 1
ROM2:AC29   .BYTE $48
ROM2:AC2A   .BYTE 3
ROM2:AC2B   .BYTE $25
ROM2:AC2C   .BYTE 5
ROM2:AC2D   .BYTE $40
ROM2:AC2E byte_AC2E: .BYTE $5C
ROM2:AC2F   .BYTE $65
ROM2:AC30   .BYTE $70
ROM2:AC31   .BYTE $88
ROM2:AC32   .BYTE $A0
ROM2:AC33   .BYTE $B8
ROM2:AC34   .BYTE $C8
ROM2:AC35   .BYTE $E0
ROM2:AC36   .BYTE $F8
ROM2:AC37   .BYTE 6
ROM2:AC38   .BYTE $14
ROM2:AC39   .BYTE $1B
ROM2:AC3A   .BYTE $33
ROM2:AC3B   .BYTE $4D
ROM2:AC3C   .BYTE $59
ROM2:AC3D   .BYTE $72
ROM2:AC3E   .BYTE $82
ROM2:AC3F   .BYTE $92
ROM2:AC40   .BYTE $A1
ROM2:AC41   .BYTE $B6
ROM2:AC42   .BYTE $C9
ROM2:AC43   .BYTE $D1
ROM2:AC44   .BYTE $EA
ROM2:AC45 byte_AC45:
ROM2:ADFA unk_ADFA: .BYTE 0
ROM2:ADFB   .BYTE $AA
ROM2:ADFC   .BYTE $FF
ROM2:ADFD   .BYTE $FF
ROM2:ADFE   .BYTE $55
ROM2:ADFF   .BYTE $AA
ROM2:AE00   .BYTE $AA
ROM2:AE01   .BYTE $FF
ROM2:AE02   .BYTE $FF
ROM2:AE03   .BYTE $FF
ROM2:AE04   .BYTE $55
ROM2:AE05   .BYTE 0
ROM2:AE06   .BYTE 0
ROM2:AE07   .BYTE 0
ROM2:AE08   .BYTE 0
ROM2:AE09   .BYTE 0
ROM2:AE0A   .BYTE 0
ROM2:AE0B   .BYTE 0
ROM2:AE0C   .BYTE $50
ROM2:AE0D   .BYTE 0
ROM2:AE0E   .BYTE 0
ROM2:AE0F   .BYTE 0
ROM2:AE10   .BYTE $AA
ROM2:AE11   .BYTE 0
ROM2:AE12   .BYTE 0
 
Subroutine task1_FoundZelda_3_0
ROM2:AE13 task1_FoundZelda_3_0:
ROM2:AE13 LDY #$1F
ROM2:AE14 LDA #$24
 
ROM2:AE17 loc_AE17:
ROM2:AE17 STA ppu_command_buffer_03,Y
ROM2:AE18 DEY
ROM2:AE19 BPL loc_AE17
ROM2:AE1A LDA found_zelda_cutscene_state_0
ROM2:AE1B BEQ loc_AE3E
ROM2:AE1C CMP #1
ROM2:AE1D BEQ loc_AE2C
ROM2:AE1E CMP #$2E
ROM2:AE1F BCC loc_AE36
ROM2:AE20 BNE loc_AE3E
 
ROM2:AE2C loc_AE2C:
ROM2:AE2C LDY #$19
ROM2:AE2D LDA #$FA
 
ROM2:AE30 loc_AE30:
ROM2:AE30 STA ppu_command_buffer_06,Y
ROM2:AE31 DEY
ROM2:AE32 BPL loc_AE30
 
ROM2:AE36 loc_AE36:
ROM2:AE36 LDA #$FA
ROM2:AE37 STA ppu_command_buffer_06
ROM2:AE38 STA byte_321
 
ROM2:AE3E loc_AE3E:
ROM2:AE3E LDA #$FF
ROM2:AE3F STA byte_325
ROM2:AE40 STA byte_330
ROM2:AE41 LDA #$20
ROM2:AE42 STA ppu_command_buffer_02
ROM2:AE43 LDX found_zelda_cutscene_state_2
ROM2:AE44 LDA byte_AC16,X
ROM2:AE45 STA ppu_command_buffer
ROM2:AE46 LDA found_zelda_cutscene_state_3
ROM2:AE47 TAY
ROM2:AE48 ASL A ; A *= 32
ROM2:AE49 ASL A
ROM2:AE4A ASL A
ROM2:AE4B ASL A
ROM2:AE4C ASL A
ROM2:AE4D STA ppu_command_buffer_01
ROM2:AE4E LDA byte_AC22,X
 
ROM2:AE63 loc_AE63:
ROM2:AE63 ASL A
ROM2:AE64 DEY
ROM2:AE65 BPL loc_AE63
ROM2:AE66 BCC loc_AEE2
ROM2:AE67 LDY found_zelda_cutscene_state_4
ROM2:AE68 CPY #$17
ROM2:AE69 BCS loc_AEE2
ROM2:AE6A LDX current_save_slot
ROM2:AE6B LDA quest_no,X
ROM2:AE6C BNE loc_AE7B
ROM2:AE6D CPY #$10
ROM2:AE6E BCS loc_AEDF
 
ROM2:AE7B loc_AE7B:
ROM2:AE7B LDX current_save_slot
ROM2:AE7C LDA quest_no,X
ROM2:AE7D BEQ loc_AE8A
ROM2:AE7E CPY #$C
ROM2:AE7F BCC loc_AE8A
ROM2:AE80 CPY #$10
ROM2:AE81 BCC loc_AEDF
 
ROM2:AE8A loc_AE8A:
ROM2:AE8A LDA byte_AC2E,Y
ROM2:AE8B STA var_0
ROM2:AE8C LDA byte_AC45,Y
ROM2:AE8D STA var_1
ROM2:AE8E LDY #0
ROM2:AE8F LDA (var_0),Y
ROM2:AE90 STA var_2
ROM2:AE91 INY
ROM2:AE92 LDA (var_0),Y
ROM2:AE93 TAX
ROM2:AE94 INY
 
ROM2:AE95 loop:
ROM2:AE95 LDA (var_0),Y
ROM2:AE96 STA ppu_command_buffer_03,X
ROM2:AE97 INY
ROM2:AE98 INX
ROM2:AE99 DEC var_2
ROM2:AE9A BNE loop
ROM2:AE9B LDY found_zelda_cutscene_state_4
ROM2:AE9C CPY #$C
ROM2:AE9D BCC loc_AEDF
ROM2:AE9E CPY #$11
ROM2:AE9F BNE loc_AEDF
ROM2:AEA0 LDA current_save_slot
ROM2:AEA1 ASL A
ROM2:AEA2 ASL A
ROM2:AEA3 ASL A
ROM2:AEA4 TAY
ROM2:AEA5 LDX #0
 
ROM2:AEA6 loop2:
ROM2:AEA6 LDA byte_638,Y
ROM2:AEA7 STA ppu_command_buffer_0C,X
ROM2:AEA8 INY
ROM2:AEA9 INX
ROM2:AEAA CPX #8
ROM2:AEAB BCC loop2
ROM2:AEAC LDY current_save_slot
ROM2:AEAD LDA deaths_per_save_slot,Y
ROM2:AEAE JSR convert_number_to_string ; Convert A to digits in var_1, var_2 and var_3. Leading
  ; zeroes are set to 0x24. A = var_2 (tens digit), Y = var_1 (hundreds digit).
ROM2:AEAF LDX #2
 
ROM2:AED4 loc_AED4:
ROM2:AED4 LDA var_1,X
ROM2:AED5 STA ppu_command_buffer_16,X
ROM2:AED6 DEX
ROM2:AED7 BPL loc_AED4
ROM2:AED8 LDY found_zelda_cutscene_state_4
 
ROM2:AEDF loc_AEDF:
ROM2:AEDF INC found_zelda_cutscene_state_4
 
ROM2:AEE2 loc_AEE2:
ROM2:AEE2 INC found_zelda_cutscene_state_3
ROM2:AEE3 LDA found_zelda_cutscene_state_2
ROM2:AEE4 AND #3
ROM2:AEE5 CMP #3
ROM2:AEE6 LDA #8
ROM2:AEE7 BCC loc_AEF2
ROM2:AEE8 LDA #6
 
ROM2:AEF2 loc_AEF2:
ROM2:AEF2 CMP found_zelda_cutscene_state_3
ROM2:AEF3 BNE loc_AF08
ROM2:AEF4 LDA #0
ROM2:AEF5 STA found_zelda_cutscene_state_3
ROM2:AEF6 LDY found_zelda_cutscene_state_2
ROM2:AEF7 INY
ROM2:AEF8 CPY #$C
ROM2:AEF9 BCC loc_AF05
ROM2:AEFA TAY
 
ROM2:AF05 loc_AF05:
ROM2:AF05 STY found_zelda_cutscene_state_2
 
ROM2:AF08 loc_AF08:
ROM2:AF08 LDA found_zelda_cutscene_state_0
ROM2:AF09 LSR A
ROM2:AF0A BCS loc_AF43
ROM2:AF0B LSR A
ROM2:AF0C BCS loc_AF43
ROM2:AF0D LDX #0
ROM2:AF0E STX byte_328
ROM2:AF0F STX byte_32F
ROM2:AF10 TAY
ROM2:AF11 LDA unk_ADFA,Y
ROM2:AF12 LDY #5
 
ROM2:AF1F loc_AF1F:
ROM2:AF1F STA $329,Y
ROM2:AF20 DEY
ROM2:AF21 BPL loc_AF1F
ROM2:AF22 LDY #$23
ROM2:AF23 LDA ppu_command_buffer
ROM2:AF24 AND #8
ROM2:AF25 BEQ loc_AF30
ROM2:AF26 LDY #$2B
 
ROM2:AF30 loc_AF30:
ROM2:AF30 STY byte_325
ROM2:AF31 LDA found_zelda_cutscene_state_0
ROM2:AF32 AND #$1F
ROM2:AF33 ASL A
ROM2:AF34 ADC #$C0
ROM2:AF35 STA byte_326
ROM2:AF36 LDA #8
ROM2:AF37 STA byte_327
 
ROM2:AF43 loc_AF43:
ROM2:AF43 LDY found_zelda_cutscene_state_0
ROM2:AF44 INY
ROM2:AF45 TYA
ROM2:AF46 AND #$1F
ROM2:AF47 CMP #$1E
ROM2:AF48 BCC loc_AF50
ROM2:AF49 INY
ROM2:AF4A INY
 
ROM2:AF50 loc_AF50:
ROM2:AF50 STY found_zelda_cutscene_state_0
ROM2:AF51 RTS
 
ROM2:AF54 pointers_to_clear_for_2nd_quest: .WORD screen_status_0
ROM2:AF56   .WORD room_data
ROM2:AF58   .WORD byte_77F
 
Function chunk for task1_FoundZelda_4
ROM2:AF5A switch_save_slot_to_2nd_quest:
ROM2:AF5A LDX #4
 
ROM2:AF5B loop: ; Set 0x80 bytes at screen_status_0, room_data and 0x077F to
ROM2:AF5B LDA pointers_to_clear_for_2nd_quest,X ; 0.
ROM2:AF5C STA var_0
ROM2:AF5D LDA pointers_to_clear_for_2nd_quest+1,X
ROM2:AF5E STA var_1
ROM2:AF5F LDY #$7F ; Y = 0x7F
ROM2:AF60 LDA #0 ; A = 0
 
ROM2:AF61 loop2: ; Set to 0.
ROM2:AF61 STA (var_0),Y
ROM2:AF62 DEY
ROM2:AF63 BPL loop2
ROM2:AF64 DEX ; X -= 2
ROM2:AF65 DEX
ROM2:AF66 BPL loop
ROM2:AF67 LDY #$27
 
ROM2:AF68 loop3: ; Set 0x0679-0x067E to 0.
ROM2:AF68 STA sword_type,Y
ROM2:AF69 DEY
ROM2:AF6A BPL loop3
ROM2:AF6B LDA #$22 ; Set hearts back to 3.
ROM2:AF6C STA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM2:AF6D DEC partial_heart ; Half heart if < 0x80, and a timer for potion refills
ROM2:AF6E LDA #8 ; Reset max_bombs to 8.
ROM2:AF6F STA max_bombs
ROM2:AF70 LDY current_save_slot ; Set this save slot to 2nd quest.
ROM2:AF71 LDA #1
ROM2:AF72 STA quest_no,Y
ROM2:AF73 RTS
 
ROM2:AF74 Skipped empty chunk
Subroutine rom2_OnReset
Subroutine rom2_set_mmc_control_register
Subroutine rom2_set_prg_bank
ROM2:BFAC Skipped empty chunk
 
Segment: ROM3
ROM3:8000 dungeon_ppu_data_0_ptrs: .WORD dungeon_ppu_data_0_1 ; Overworld
ROM3:8002   .WORD dungeon_ppu_data_0_1 ; Dungeon 1
ROM3:8004   .WORD dungeon_ppu_data_0_1 ; Dungeon 2
ROM3:8006 off_C006: .WORD dungeon_ppu_data_0_2 ; Dungeon 3
ROM3:8008   .WORD dungeon_ppu_data_0_3 ; Dungeon 4
ROM3:800A   .WORD dungeon_ppu_data_0_2 ; Dungeon 5
ROM3:800C   .WORD dungeon_ppu_data_0_3 ; Dungeon 6
ROM3:800E   .WORD dungeon_ppu_data_0_1 ; Dungeon 7
ROM3:8010   .WORD dungeon_ppu_data_0_2 ; Dungeon 8
ROM3:8012   .WORD dungeon_ppu_data_0_3 ; Dungeon 9
ROM3:8014 dungeon_ppu_data_1_ptrs: .WORD dungeon_ppu_data_1_1 ; Overworld
ROM3:8016   .WORD dungeon_ppu_data_1_1 ; Dungeon 1
ROM3:8018   .WORD dungeon_ppu_data_1_1 ; Dungeon 2
ROM3:801A   .WORD dungeon_ppu_data_1_2 ; Dungeon 3
ROM3:801C   .WORD dungeon_ppu_data_1_2 ; Dungeon 4
ROM3:801E   .WORD dungeon_ppu_data_1_1 ; Dungeon 5
ROM3:8020   .WORD dungeon_ppu_data_1_2 ; Dungeon 6
ROM3:8022   .WORD dungeon_ppu_data_1_1 ; Dungeon 7
ROM3:8024   .WORD dungeon_ppu_data_1_2 ; Dungeon 8
ROM3:8026   .WORD dungeon_ppu_data_1_3 ; Dungeon 9
ROM3:8028 rom3_ppu_data_0_ptrs: .WORD rom3_ppu_data_0_0
ROM3:802A   .WORD rom3_ppu_data_0_1
ROM3:802C rom3_ppu_data_1_ptrs: .WORD rom3_ppu_data_1_0
ROM3:802E   .WORD rom3_ppu_data_1_1
ROM3:8030 dungeon_ppu_data_ppu_addresses: .WORD $17 ; rom3_ppu_data_0 PPU address
ROM3:8032   .WORD $E008 ; rom3_ppu_data_1 PPU address
ROM3:8034   .WORD $E009 ; dungeon_ppu_data_0 PPU address
ROM3:8036   .WORD $C ; dungeon_ppu_data_1 PPU address
ROM3:8038 rom3_ppu_data_1_sizes: .WORD $2008 ; rom3_ppu_data_1[0] size: 0x0820
ROM3:803A   .WORD $2007 ; rom3_ppu_data_1[1] size: 0x0720
ROM3:803C rom3_ppu_data_sizes: .WORD $2008 ; rom3_ppu_data_0[0] size: 0x0820
ROM3:803E   .WORD 1 ; rom3_ppu_data_0[1] size: 0x0x0100
ROM3:8040   .WORD $2002 ; dungeon_ppu_data_0 size: 0x0220
ROM3:8042   .WORD 4 ; dungeon_ppu_data_1 size: 0x0400
 
Subroutine task0_LoadDungeon_0
ROM3:8044 task0_LoadDungeon_0:
ROM3:8044 JSR clear_ppumask
ROM3:8045 LDA PPUSTATUS
ROM3:8046 JSR clear_usually_zero
ROM3:8047 LDA dungeon_idx
ROM3:8048 BNE copy_next_ppu_data
 
ROM3:8049 loop: ; Get the ppu_data_4[X] pointer in var_0/var_1.
ROM3:8049 JSR rom3_get_ppu_data_1_ptr_and_size
ROM3:804A JSR rom3_copy_data_to_ppu_with_size ; Like copy_dungeon_ppu_data_to_ppu, but the data size is
  ; already set in var_2/var_3.
ROM3:804B LDA usually_zero
ROM3:804C CMP #2
ROM3:804D BNE loop
 
ROM3:805E clear_usually_zero:
ROM3:805E LDA #0
ROM3:805F STA usually_zero ; Set to 0
ROM3:8060 RTS
 
ROM3:8061 copy_next_ppu_data: ; Get the ppu_data_3[X] pointer in var_0/var_1.
ROM3:8061 JSR rom3_get_ppu_data_0_ptr
ROM3:8062 JSR rom3_copy_data_to_ppu ; Copy data to the PPU.
 
  ; In var_0/var_1: A pointer to the data to copy.
  ; In X: the current dungeon (or 0 for the overworld).
  ; The data size will be set from dungeon_ppu_data_sizes[X].
 
ROM3:8063 LDA usually_zero
ROM3:8064 CMP #2
ROM3:8065 BNE copy_next_ppu_data
ROM3:8066 JSR get_dungeon_ppu_data_0_ptr ; Get the dungeon_ppu_data_0 pointer for the current dungeon in var_0/var_1.
ROM3:8067 JSR rom3_copy_data_to_ppu ; Copy data to the PPU.
 
  ; In var_0/var_1: A pointer to the data to copy.
  ; In X: the current dungeon (or 0 for the overworld).
  ; The data size will be set from dungeon_ppu_data_sizes[X].
 
ROM3:8068 JSR get_dungeon_ppu_data_1_ptr ; Get the dungeon_ppu_data_1 pointer for the current dungeon in var_0/var_1.
ROM3:8069 JSR rom3_copy_data_to_ppu ; Copy data to the PPU.
 
  ; In var_0/var_1: A pointer to the data to copy.
  ; In X: the current dungeon (or 0 for the overworld).
  ; The data size will be set from dungeon_ppu_data_sizes[X].
 
ROM3:806A JMP clear_usually_zero
 
ROM3:806B rom3_get_ppu_data_0_ptr: ; Get the ppu_data_3[X] pointer in var_0/var_1.
ROM3:806B LDA usually_zero
ROM3:806C ASL A
ROM3:806D TAX
ROM3:806E LDA rom3_ppu_data_0_ptrs,X
ROM3:806F STA var_0
ROM3:8070 INX
ROM3:8071 LDA rom3_ppu_data_0_ptrs,X
ROM3:8072 STA var_1
ROM3:8073 RTS
 
Subroutine rom3_get_ppu_data_1_ptr_and_size
; Get the ppu_data_4[X] pointer in var_0/var_1.
ROM3:8091 rom3_get_ppu_data_1_ptr_and_size:
ROM3:8091 LDA usually_zero
ROM3:8092 ASL A
ROM3:8093 TAX
ROM3:8094 LDA rom3_ppu_data_1_ptrs,X
ROM3:8095 STA var_0
ROM3:8096 LDA rom3_ppu_data_1_sizes,X
ROM3:8097 STA var_2
ROM3:8098 INX
ROM3:8099 LDA rom3_ppu_data_1_ptrs,X
ROM3:809A STA var_1
ROM3:809B LDA rom3_ppu_data_1_sizes,X
ROM3:809C STA var_3
ROM3:809D RTS
 
Subroutine get_dungeon_ppu_data_0_ptr
; Get the dungeon_ppu_data_0 pointer for the current dungeon in var_0/var_1.
ROM3:80AC get_dungeon_ppu_data_0_ptr:
ROM3:80AC LDA dungeon_idx
ROM3:80AD ASL A
ROM3:80AE TAX
ROM3:80AF LDA dungeon_ppu_data_0_ptrs,X
ROM3:80B0 STA var_0
ROM3:80B1 INX
ROM3:80B2 LDA dungeon_ppu_data_0_ptrs,X
ROM3:80B3 STA var_1
ROM3:80B4 RTS
 
Subroutine get_dungeon_ppu_data_1_ptr
; Get the dungeon_ppu_data_1 pointer for the current dungeon in var_0/var_1.
ROM3:80BC get_dungeon_ppu_data_1_ptr:
ROM3:80BC LDA dungeon_idx
ROM3:80BD ASL A
ROM3:80BE TAX
ROM3:80BF LDA dungeon_ppu_data_1_ptrs,X
ROM3:80C0 STA var_0
ROM3:80C1 INX
ROM3:80C2 LDA dungeon_ppu_data_1_ptrs,X
ROM3:80C3 STA var_1
ROM3:80C4 RTS
 
Subroutine rom3_copy_data_to_ppu
; Copy data to the PPU. ; ; In var_0/var_1: A pointer to the data to copy. ; In X: the current dungeon (or 0 for the overworld). ; The data size will be set from dungeon_ppu_data_sizes[X].
ROM3:80CC rom3_copy_data_to_ppu:
ROM3:80CC LDA usually_zero
ROM3:80CD ASL A
ROM3:80CE TAX
ROM3:80CF LDA rom3_ppu_data_sizes,X
ROM3:80D0 STA var_2
ROM3:80D1 INX
ROM3:80D2 LDA rom3_ppu_data_sizes,X
ROM3:80D3 STA var_3
 
ROM3:80DC rom3_copy_data_to_ppu_with_size: ; Like copy_dungeon_ppu_data_to_ppu, but the data size is
ROM3:80DC LDA usually_zero ; already set in var_2/var_3.
ROM3:80DD ASL A
ROM3:80DE TAX
ROM3:80DF LDA dungeon_ppu_data_ppu_addresses,X
ROM3:80E0 STA PPUADDR
ROM3:80E1 INX
ROM3:80E2 LDA dungeon_ppu_data_ppu_addresses,X
ROM3:80E3 STA PPUADDR
ROM3:80E4 LDY #0
 
ROM3:80E5 loop: ; Read a byte of PPU data.
ROM3:80E5 LDA (var_0),Y
ROM3:80E6 STA PPUDATA ; Write a byte of PPU data.
ROM3:80E7 LDA var_0 ; Increment the 16-bit source pointer.
ROM3:80E8 CLC
ROM3:80E9 ADC #1
ROM3:80EA STA var_0
ROM3:80EB LDA var_1
ROM3:80EC ADC #0
ROM3:80ED STA var_1
ROM3:80EE LDA var_3 ; Decrement the 16-bit size.
ROM3:80EF SEC
ROM3:80F0 SBC #1
ROM3:80F1 STA var_3
ROM3:80F2 LDA var_2
ROM3:80F3 SBC #0
ROM3:80F4 STA var_2
ROM3:80F5 LDA var_2 ; Loop if the 16-bit size isn't 0.
ROM3:80F6 BNE loop
ROM3:80F7 LDA var_3
ROM3:80F8 BNE loop
ROM3:80F9 INC usually_zero
ROM3:80FA RTS
 
ROM3:811B rom3_ppu_data_0_0:
ROM3:893B rom3_ppu_data_1_0:
ROM3:915B rom3_ppu_data_1_1:
ROM3:987B dungeon_ppu_data_0_2:
ROM3:98AF byte_D8AF: .BYTE 2
ROM3:98B0   .BYTE $F8
ROM3:98B1   .BYTE $40
ROM3:98B2   .BYTE 0
ROM3:98B3 byte_D8B3: .BYTE $3F
ROM3:98B4   .BYTE $3F
ROM3:98B5   .BYTE $1F
ROM3:98B6   .BYTE 7
ROM3:98B7 byte_D8B7: .BYTE $1F
ROM3:98B8   .BYTE 7
ROM3:98B9   .BYTE $7F
ROM3:98BA   .BYTE $FF
ROM3:98BB byte_D8BB:
ROM3:9A9B dungeon_ppu_data_0_3:
ROM3:9CBB rom3_ppu_data_0_1:
ROM3:9DBB dungeon_ppu_data_0_1:
ROM3:A3DB dungeon_ppu_data_1_2:
ROM3:A7DB dungeon_ppu_data_1_3:
ROM3:A7DB Skipped empty chunk
Subroutine rom3_OnReset
Subroutine rom3_set_mmc_control_register
Subroutine rom3_set_prg_bank
; Map the ROM bank specified in A to $8000-$BFFF.
ROM3:BFAC Skipped empty chunk
 
 
Segment: ROM4
 
Subroutine play_boss_pain_sound_after_hit
; If the current enemy was just hit (has 16 invincibility ; frames), play Sound0_BossPainSound.
ROM4:8000 play_boss_pain_sound_after_hit:
ROM4:8000 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:8001 CMP #$10
ROM4:8002 BNE locret_1000C
ROM4:8003 LDA #Sound0_BossPainSound
ROM4:8004 STA play_sound_0 ; Play Sound0_BossSound1
 
ROM4:800C locret_1000C:
ROM4:800C RTS
 
Subroutine play_boss_sound_1_if_not_state_0
ROM4:800D play_boss_sound_1_if_not_state_0:
ROM4:800D LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:800E BEQ locret_1000C
ROM4:800F JMP play_boss_sound_1 ; Play the boss sound if the state isn't 0.
 
Subroutine spawn_projectile
ROM4:8015 spawn_projectile:
ROM4:8015 LDA #$C0 ; Projectile speed
ROM4:8016 BNE skip
 
ROM4:8019 spawn_unknown_0x54: ; Projectile speed 2
ROM4:8019 LDA #$E0
 
ROM4:801A skip: ; Store projectile speed as walk speed
ROM4:801A STA object_walk_speed,X
ROM4:801B JMP set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
 
ROM4:801C LDA #$80 ; Is this code reachable?
ROM4:801D STA enemy_action_timers,X
 
Subroutine spawn_monster_basic
; This is the common setup for most monsters. It just picks ; an initial walking direction, based on the enemy's spawn ; position and the player seek position (enemy_behavior_seek_x, ; enemy_behavior_seek_y).
ROM4:8025 spawn_monster_basic:
ROM4:8025 LDA object_direction,X
ROM4:8026 BNE direction_already_set
ROM4:8027 LDY #ControllerBits_Dpad_Left ; Y = 2 (left)
ROM4:8028 LDA enemy_behavior_seek_x
ROM4:8029 SEC
ROM4:802A SBC object_x,X ; enemy_behavior_seek_x - object_x[X]
ROM4:802B BCS seek_left ; Branch if seek x > object x, so we move away from the target.
ROM4:802C DEY ; Y = 1 (right)
 
ROM4:802D seek_left: ; Store enemy_behavior_seek_x - object_x[X]
ROM4:802D STA var_0
ROM4:802E STY var_1 ; Store the horizontal direction we decided above
ROM4:802F STY object_direction,X ; Store our initial horizontal movement direction. (This seems to always be overwritten below.)
ROM4:8030 LDY #ControllerBits_Dpad_Down ; Y = 4 (down)
ROM4:8031 LDA enemy_behavior_seek_y
ROM4:8032 SEC
ROM4:8033 SBC object_y,X
ROM4:8034 BCS seek_down ; Branch if seek y > object y, so we move towards the target.
ROM4:8035 LDY #ControllerBits_Dpad_Up ; Y = 8 (up)
 
ROM4:8036 seek_down: ; Store the vertical movement direction.
ROM4:8036 STY object_direction,X
ROM4:8037 CMP var_0 ; Compare y distance (A) to x distance (var_0)
ROM4:8038 BCC direction_already_set ; branch if y distance >= x distance
ROM4:8039 LDA var_1 ; The X distance to the target is greater than the Y distance.
ROM4:803A STA object_direction,X ; Store the horizontal movement direction if the horizontal distance is greater than the vertical distance.
 
ROM4:803B direction_already_set:
ROM4:803B RTS
 
Subroutine update_monster_flame_unkillable
ROM4:804F update_monster_flame_unkillable:
ROM4:804F JSR check_link_hit_by_enemy ; Check if Link was hit by an enemy. X is the enemy we're
  ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM4:8050 LDA #OAMAttributes_Palette_2
ROM4:8051 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:8052 LDA #8
ROM4:8053 STA object_direction,X
ROM4:8054 JSR update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
ROM4:8055 LDA object_type,X ; check if ObjectType_Unknown_40
ROM4:8056 CMP #ObjectType_Flame_Unkillable
ROM4:8057 BEQ loc_10069
ROM4:8058 LDA #0
ROM4:8059 STA var_15
 
ROM4:8069 loc_10069:
ROM4:8069 LDA #0
ROM4:806A JMP update_object_sprite_horizontal
 
Subroutine store_speed_and_update_movement
; On entry, A is the current enemy's walking speed.
ROM4:806E store_speed_and_update_movement:
ROM4:806E STA enemy_projectile_speed_x,X
ROM4:806F LDA object_knockback,X
ROM4:8070 BEQ no_knockback
ROM4:8071 JMP update_object_knockback
 
ROM4:8072 no_knockback:
ROM4:8072 LDA clock_active
ROM4:8073 ORA enemy_stun,X
ROM4:8074 BNE locret_100A3 ; Stop if the clock is active.
ROM4:8075 JMP update_movement_or_fire_projectile_if_zero_timer
 
Subroutine sub_10082
; XXX: Find the jump to this. It looks like it should be called ; from the Goriya update somewhere.
ROM4:8082 sub_10082:
ROM4:8082 LDA #$70 ; Projectile speed
ROM4:8083 LDY object_type,X ; check if ObjectType_BlueGoriya
ROM4:8084 CPY #ObjectType_BlueGoriya
ROM4:8085 BEQ blue_goriya
ROM4:8086 LDA #$A0 ; Projectile speed
 
ROM4:8087 blue_goriya:
ROM4:8087 STA enemy_projectile_speed_x,X
ROM4:8088 LDA walk_state_and_weapon_state,X
ROM4:8089 BMI locret_100A3
 
ROM4:8094 update_movement_or_fire_projectile_if_zero_timer:
ROM4:8094 LDA enemy_blind_projectile_timer,X
ROM4:8095 BEQ enemy_blind_projectile_timer_already_0
ROM4:8096 DEC enemy_blind_projectile_timer,X ; Decrement if not already 0
 
ROM4:8097 enemy_blind_projectile_timer_already_0: ; Handle walking. X = 0 for Link, X > 0 for enemies.
ROM4:8097 JSR update_object_movement
ROM4:8098 LDA object_knockback,X ; Don't fire a projectile during knockback.
ROM4:8099 BEQ check_fire_projectile ; See if we're aligned on the X or Y axis with our seek target.
  ; If we are, mark that we should fire a projectile, and the
  ; axis direction towards the target.
 
ROM4:80A3 locret_100A3:
ROM4:80A3 RTS
 
Subroutine check_fire_projectile
; See if we're aligned on the X or Y axis with our seek target. ; If we are, mark that we should fire a projectile, and the ; axis direction towards the target.
ROM4:80A4 check_fire_projectile:
ROM4:80A4 LDA object_walk_speed,X
ROM4:80A5 BEQ done
ROM4:80A6 LDA object_tile_offset_whole,X
ROM4:80A7 AND #$F
ROM4:80A8 BNE done
ROM4:80A9 STA object_tile_offset_whole,X
ROM4:80AA LDA enemy_projectile_speed_x,X
ROM4:80AB CMP prng_1,X
ROM4:80AC BCC skip_fire_projectile
ROM4:80AD LDA walk_state_and_weapon_state
ROM4:80AE CMP #$FF
ROM4:80AF BEQ skip_fire_projectile
ROM4:80B0 LDA enemy_behavior_seek_x ; Subtract the object's seek X position from its own X position.
ROM4:80B1 SEC
ROM4:80B2 SBC object_x,X
ROM4:80B3 BPL x_is_positive ; Compare the distance from the seek X position.
ROM4:80B4 EOR #$FF ; x = -x
ROM4:80B5 CLC
ROM4:80B6 ADC #1
 
ROM4:80B7 x_is_positive: ; Compare the distance from the seek X position.
ROM4:80B7 CMP #9
ROM4:80B8 BCS too_far_on_x ; Jump if we're >= 9 pixels from the seek X position.
 
ROM4:80B9 fire_vertically:
ROM4:80B9 LDY #ControllerBits_Dpad_Up
ROM4:80BA LDA enemy_behavior_seek_y
ROM4:80BB CMP object_y,X
ROM4:80BC BCC set_about_to_fire_projectile
ROM4:80BD LDY #ControllerBits_Dpad_Down
ROM4:80BE BNE set_about_to_fire_projectile
 
ROM4:80BF too_far_on_x: ; Subtract the object's seek Y position from its own Y position.
ROM4:80BF LDA enemy_behavior_seek_y
ROM4:80C0 SEC
ROM4:80C1 SBC object_y,X
ROM4:80C2 BPL y_is_positive ; Compare the distance from the seek Y position.
ROM4:80C3 EOR #$FF ; y = -y
ROM4:80C4 CLC
ROM4:80C5 ADC #1
 
ROM4:80C6 y_is_positive: ; Compare the distance from the seek Y position.
ROM4:80C6 CMP #9
ROM4:80C7 BCS skip_fire_projectile ; If we're too far on this axis too, don't fire.
 
ROM4:80C8 fire_horizontally:
ROM4:80C8 LDY #ControllerBits_Dpad_Right
ROM4:80C9 LDA enemy_behavior_seek_x
ROM4:80CA CMP object_x,X
ROM4:80CB BCS set_about_to_fire_projectile
ROM4:80CC INY ; ControllerBits_Dpad_Left
 
ROM4:80CD set_about_to_fire_projectile: ; Y is the direction to fire the projectile.
ROM4:80CD STY object_direction,X
ROM4:80CE LDA prng_0,X
ROM4:80CF STA enemy_blind_projectile_timer,X
ROM4:80D0 LDA #1
ROM4:80D1 STA enemy_state_0,X ; Set to 1
ROM4:80D2 JMP loc_10190
 
ROM4:80D3 skip_fire_projectile:
ROM4:80D3 LDA #0
ROM4:80D4 STA enemy_state_0,X ; Set to 0
ROM4:80D5 LDA enemy_blind_projectile_timer,X ; Check the blind projectile timer. If this reaches 0, fire
  ; anyway even if we don't see the seek target.
ROM4:80D6 BNE done
ROM4:80D7 LDA object_direction,X ; If the enemy is moving horizontally, fire horizontally in
  ; whichever direction is towards the seek target. Otherwise,
  ; fire vertically.
ROM4:80D8 AND #$C ; Left|Right
ROM4:80D9 BNE fire_horizontally
ROM4:80DA BEQ fire_vertically
 
ROM4:80DB done:
ROM4:80DB JMP loc_10190
 
Subroutine update_monster_goriya
; Armos and Lynel updates also jump here.
ROM4:8119 update_monster_goriya:
ROM4:8119 LDA object_type_1,X
ROM4:811A CMP #ObjectType_Armos
ROM4:811B BEQ armos
ROM4:811C LDA walk_state_and_weapon_state,X
ROM4:811D BMI ret
 
ROM4:811E armos: ; Handle walking. X = 0 for Link, X > 0 for enemies.
ROM4:811E JSR update_object_movement
ROM4:811F LDA object_knockback,X
ROM4:8120 BEQ no_knockback
 
ROM4:8121 ret:
ROM4:8121 RTS
 
ROM4:8122 no_knockback:
ROM4:8122 LDA object_walk_speed,X
ROM4:8123 BEQ loc_10190
ROM4:8124 LDA object_tile_offset_whole,X
ROM4:8125 AND #$F
ROM4:8126 BNE loc_10190
ROM4:8127 STA object_tile_offset_whole,X
ROM4:8128 LDA walk_state_and_weapon_state
ROM4:8129 CMP #$FF
ROM4:812A BEQ loc_10190
ROM4:812B LDA #ControllerBits_Dpad_Down
ROM4:812C STA var_2 ; Set to ControllerBits_Dpad_Down
ROM4:812D LDA enemy_behavior_seek_y ; A = seek Y
ROM4:812E LDY object_y,X ; Y = enemy Y
ROM4:812F CMP object_y,X ; Compare our Y position to the seek Y position.
ROM4:8130 BCS seek_right ; Branch if seek Y >= enemy Y.
ROM4:8131 LDA object_y,X ; A = enemy Y
ROM4:8132 LDY enemy_behavior_seek_y ; Y = seek Y
ROM4:8133 ASL var_2 ; Set to ControllerBits_Dpad_Up.
 
ROM4:8134 seek_right:
ROM4:8134 STY var_14
ROM4:8135 SEC
ROM4:8136 SBC var_14
ROM4:8137 STA var_0
ROM4:8138 LDA #ControllerBits_Dpad_Right
ROM4:8139 STA var_3 ; Set to ControllerBits_Dpad_Right.
ROM4:813A LDA enemy_behavior_seek_x ; A = seek Y
ROM4:813B LDY object_x,X ; Y = enemy X
ROM4:813C CMP object_x,X ; Compare our X position to the seek X position.
ROM4:813D BCS seek_down ; Branch if seek X >= enemy X.
ROM4:813E LDA object_x,X ; A = enemy X
ROM4:813F LDY enemy_behavior_seek_x ; Y = seek X
ROM4:8140 ASL var_3 ; Set to ControllerBits_Dpad_Left.
 
ROM4:8141 seek_down:
ROM4:8141 STY var_14
ROM4:8142 SEC
ROM4:8143 SBC var_14
ROM4:8144 STA var_1
ROM4:8145 LDY #0
ROM4:8146 LDA var_0
ROM4:8147 CMP var_1
ROM4:8148 BCS loc_1017C
ROM4:8149 INY
 
ROM4:817C loc_1017C:
ROM4:817C LDA #0
ROM4:817D STA enemy_state_0,X
ROM4:817E LDA var_0,Y
ROM4:817F CMP #$51
ROM4:8180 BCS loc_10190
ROM4:8181 INC enemy_state_0,X
ROM4:8182 LDA var_2,Y
ROM4:8183 STA object_direction,X
 
ROM4:8190 loc_10190:
ROM4:8190 LDA object_direction,X
ROM4:8191 STA walking_directions,X
ROM4:8192 LDA #ObjectType_Goriya_Boomerang
ROM4:8193 LDY object_type,X ; Check if this is a Goriya.
ROM4:8194 CPY #ObjectType_BlueGoriya
ROM4:8195 BEQ blue_goriya
ROM4:8196 CPY #ObjectType_RedGoriya
ROM4:8197 BNE ret2
ROM4:8198 LDA prng_0,X ; Red goriya only throws boomerang if prng == 0x23 || prng == 0x77?
ROM4:8199 CMP #$23
ROM4:819A BEQ do_throw_boomerang
ROM4:819B CMP #$77
ROM4:819C BNE ret2
 
ROM4:819D do_throw_boomerang:
ROM4:819D LDA #ObjectType_Goriya_Boomerang
 
ROM4:819E blue_goriya:
ROM4:819E LDY enemy_action_timers,X
ROM4:819F BNE ret2
ROM4:81A0 STA var_0
ROM4:81A1 LDA clock_active
ROM4:81A2 ORA enemy_stun,X
ROM4:81A3 BNE ret2 ; Stop if the clock is active or the enemy is stunned.
ROM4:81A4 LDA var_0 ; Reload the projectile type. This is always ObjectType_Goriya_Boomerang.
ROM4:81A5 JSR create_object_at_another_object_2 ; Create ObjectType_Goriya_Boomerang.
ROM4:81A6 BCC ret2
ROM4:81A7 LDA #$80
ROM4:81A8 STA walk_state_and_weapon_state,X
ROM4:81A9 LDA #0
ROM4:81AA STA enemy_state_0,X
ROM4:81AB TXA
ROM4:81AC STA enemy_state_4,Y
ROM4:81AD TYA
ROM4:81AE STA enemy_state_4,X
ROM4:81AF LDA #$10
ROM4:81B0 STA walk_state_and_weapon_state,Y
ROM4:81B1 LDA #$A0
ROM4:81B2 STA object_walk_speed,Y
ROM4:81B3 LDA #$51
ROM4:81B4 STA enemy_state_11,Y
ROM4:81B5 LDA #0
ROM4:81B6 STA enemy_spawn_state,Y ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:81B7 LDA #3
ROM4:81B8 STA object_animation_frame_timer,Y
ROM4:81B9 LDA prng_0,X
ROM4:81BA AND #63
ROM4:81BB STA enemy_action_timers,X
 
ROM4:81BC ret2:
ROM4:81BC RTS
 
ROM4:81F3 byte_101F3: .BYTE 8
ROM4:81F4   .BYTE 4
ROM4:81F5   .BYTE 2
ROM4:81F6   .BYTE 1
 
Subroutine update_monster_dungeon_secret_push_block
ROM4:81F7 update_monster_dungeon_secret_push_block:
ROM4:81F7 LDA walk_state_and_weapon_state,X
ROM4:81F8 AND #3
ROM4:81F9 JSR call_jump_table
 
ROM4:81FA   .WORD update_monster_dungeon_secret_push_block_0
ROM4:81FC   .WORD update_monster_dungeon_secret_push_block_1
ROM4:81FE   .WORD locret_10289
 
Subroutine update_monster_dungeon_secret_push_block_0
ROM4:8204 update_monster_dungeon_secret_push_block_0:
 
ROM4:8204 LDA room_clear ; Stop if all enemies on the screen aren't dead.
ROM4:8205 BEQ loc_1025D
ROM4:8206 LDA object_x
ROM4:8207 CMP object_x,X
ROM4:8208 BNE loc_1021C
ROM4:8209 LDY #0
ROM4:820A LDA object_y
ROM4:820B CLC
ROM4:820C ADC #3
ROM4:820D SEC
ROM4:820E SBC object_y,X
ROM4:820F JMP loc_1022C
 
ROM4:821C loc_1021C:
ROM4:821C LDA object_y
ROM4:821D CLC
ROM4:821E ADC #3
ROM4:821F CMP object_y,X
ROM4:8220 BNE loc_1025D
ROM4:8221 LDY #2
ROM4:8222 LDA object_x
ROM4:8223 SEC
ROM4:8224 SBC object_x,X
 
ROM4:822C loc_1022C:
ROM4:822C BPL loc_10232
ROM4:822D INY
ROM4:822E JSR inverse
 
ROM4:8232 loc_10232:
ROM4:8232 CMP #$11
ROM4:8233 BCS loc_1025D
ROM4:8234 LDA walking_directions
ROM4:8235 CMP byte_101F3,Y
ROM4:8236 BNE loc_1025D
ROM4:8237 INC enemy_state_0,X
ROM4:8238 LDY enemy_state_0,X
ROM4:8239 CPY #$10
ROM4:823A BCC locret_10262
ROM4:823B STA object_direction,X
ROM4:823C INC walk_state_and_weapon_state,X
ROM4:823D INC ppu_unknown_task_returns_to_ROM4
ROM4:823E LDA #$74
ROM4:823F JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
 
Subroutine update_push_block_sprite
ROM4:8253 update_push_block_sprite:
ROM4:8253 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8254 DEC var_1 ; var_1 is the object's Y position. Draw it one pixel higher.
ROM4:8255 LDA #0
ROM4:8256 JMP update_object_sprite_horizontal
 
Function chunk for update_monster_dungeon_secret_push_block_0
ROM4:825D loc_1025D:
ROM4:825D LDA #0
ROM4:825E STA enemy_state_0,X
 
ROM4:8262 locret_10262:
ROM4:8262 RTS
 
Subroutine update_monster_dungeon_secret_push_block_1
ROM4:8263 update_monster_dungeon_secret_push_block_1:
ROM4:8263 LDA object_direction,X
ROM4:8264 STA var_15
ROM4:8265 JSR process_movement
ROM4:8266 JSR update_push_block_sprite
ROM4:8267 LDA object_tile_offset_whole,X
ROM4:8268 CMP #$10
ROM4:8269 BEQ push_block_finished_moving
ROM4:826A CMP #$F0
ROM4:826B BNE locret_10289
 
ROM4:826C push_block_finished_moving:
ROM4:826C LDA #Sound1_Secret
ROM4:826D STA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
ROM4:826E INC ppu_unknown_task_returns_to_ROM4
ROM4:826F LDA #$B0
ROM4:8270 JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
ROM4:8271 INC walk_state_and_weapon_state,X
ROM4:8272 INC pushed_dungeon_push_block
 
ROM4:8289 locret_10289:
ROM4:8289 RTS
 
Subroutine remove_like_like_or_wall_master_holding_link_sprite
ROM4:828A remove_like_like_or_wall_master_holding_link_sprite:
ROM4:828A LDA #$F8
ROM4:828B STA sprite_oam_data_40
ROM4:828C STA sprite_oam_data_44
ROM4:828D RTS
 
Subroutine update_sprite_wall_master
ROM4:8293 update_sprite_wall_master:
ROM4:8293 LDY #0
ROM4:8294 BEQ skip ; Always branches
 
ROM4:8297 update_sprite_like_like:
ROM4:8297 LDY #1
 
ROM4:8298 skip:
ROM4:8298 STY var_12
ROM4:8299 LDY object_type,X ; Load to update sprite.
ROM4:829A INY
ROM4:829B STA var_13
ROM4:829C STY var_14
ROM4:829D STX var_8
ROM4:829E LDA #$40
ROM4:829F STA updating_oam_sprite_id_1
ROM4:82A0 LDA #$44
ROM4:82A1 JMP update_sprite_from_wall_master_or_like_like
 
Subroutine create_fireball_near_object
; Create an object near the current object. This is only used to create fireballs. ; ; In A = new object's type ; In X = current object ID ; Out Y = new object ID
ROM4:82AF create_fireball_near_object:
ROM4:82AF STA var_0 ; Stash the object type to create
ROM4:82B0 JSR find_last_available_object_idx ; Result is returned in tmp_result.
ROM4:82B1 BEQ ret ; Stop if there are no available object slots.
ROM4:82B2 TXA
ROM4:82B3 PHA ; Push A (caller's object ID)
ROM4:82B4 TYA
ROM4:82B5 TAX ; X = new object's ID
ROM4:82B6 LDA var_0 ; Restore the object type to create
ROM4:82B7 JSR create_enemy
ROM4:82B8 TXA ; Move the new object's ID into Y
ROM4:82B9 TAY
ROM4:82BA PLA ; Pop A
ROM4:82BB TAX ; Restore caller's object ID
ROM4:82BC LDA object_x,X ; Spawn the new object at (X+4,Y) relative to the original object.
ROM4:82BD CLC
ROM4:82BE ADC #4
ROM4:82BF STA object_x,Y
ROM4:82C0 LDA object_y,X
ROM4:82C1 STA object_y,Y
 
ROM4:82C2 ret:
ROM4:82C2 RTS
 
ROM4:82D1 projectile_deflection_movement_x: .BYTE 1
ROM4:82D2   .BYTE $FF
ROM4:82D3 projectile_deflection_movement_y: .BYTE $FE
ROM4:82D4   .BYTE 2
ROM4:82D5   .BYTE $FF
ROM4:82D6   .BYTE $FF
 
Subroutine update_monster_projectile
ROM4:82D7 update_monster_projectile:
ROM4:82D7 LDA object_direction,X
ROM4:82D8 STA var_15
ROM4:82D9 LDA walk_state_and_weapon_state,X
ROM4:82DA AND #$F0
ROM4:82DB CMP #$10 ; Check if this projectile has been deflected.
ROM4:82DC BNE update_deflected_projectile ; Update a projectile that's been blocked by Link's shield
  ; and is flying off diagonally.
ROM4:82DD LDA object_type,X ; check if ObjectType_Homing_Fireball_1
ROM4:82DE CMP #ObjectType_Homing_Fireball_1
ROM4:82DF BCS check_against_screen_bounds ; >= ObjectType_Homing_Fireball_1
ROM4:82E0 LDA enemy_action_timers,X
ROM4:82E1 BNE check_link_hit
ROM4:82E2 JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM4:82E3 CMP screen_first_solid_tile_id
ROM4:82E4 BCS delete_enemy_projectile ; Delete a projectile (via delete_enemy), adjusting enemy_projectile_count accordingly.
 
ROM4:82E5 check_against_screen_bounds: ; If the current object is out of the bounding box for the
ROM4:82E5 JSR check_object_against_screen_bounding_box_both ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM4:82E6 BEQ delete_enemy_projectile ; Delete a projectile (via delete_enemy), adjusting enemy_projectile_count accordingly.
ROM4:82E7 JSR process_movement
 
ROM4:82E8 check_link_hit: ; Check if Link was hit by a projectile.
ROM4:82E8 JSR check_link_hit_by_projectile ; Out var_6: If Link was hit, set to be true by check_link_hit_by_enemy.
  ; enemy_state_11[X]: Set to Link's direction if he was hit.
  ; walk_state_and_weapon_state[X] = 0x30 if Link was hit.
ROM4:82E9 LDA var_6
ROM4:82EA BNE delete_enemy_projectile ; Branch if Link was hit to delete the projectile.
 
ROM4:8305 loc_10305: ; check if ObjectType_Moblin_Arrow
ROM4:8305 LDA object_type,X
ROM4:8306 CMP #ObjectType_Moblin_Arrow
ROM4:8307 BNE not_moblin_arrow
ROM4:8308 JMP update_arrow
 
ROM4:8309 not_moblin_arrow:
ROM4:8309 CMP #ObjectType_Lynel_Sword
ROM4:830A BCC not_lynel_sword_or_unknown
ROM4:830B CMP #ObjectType_Unknown_Projectile_5A ; Does anything create this?
ROM4:830C BCS not_lynel_sword_or_unknown
ROM4:830D JMP update_lynel_sword_or_unknown ; ObjectType_Lynel_Sword, ObjectType_Unknown_Projectile_58 or ObjectType_Unknown_Projectile_59
 
ROM4:830E not_lynel_sword_or_unknown: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:830E JSR set_var_0_to_object_position
ROM4:830F STA var_13
ROM4:8310 LDA frame_counter
ROM4:8311 AND #3
ROM4:8312 LDY object_type,X
ROM4:8313 CPY #ObjectType_Homing_Fireball_1
ROM4:8314 BCS not_octorok_projectile ; >= ObjectType_Homing_Fireball_1 (not Octorok projectile)
ROM4:8315 LDY #3
 
ROM4:8316 loop: ; var_0 += 4
ROM4:8316 INC var_0
ROM4:8317 DEY
ROM4:8318 BPL loop
ROM4:8319 LDA #0
 
ROM4:831A not_octorok_projectile: ; Store A in var_4 and var_5.
ROM4:831A JSR store_A_in_tile_attributes
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:831B LDA var_13
ROM4:831C JMP update_object_sprite_horizontal
 
ROM4:831D delete_enemy_projectile: ; Delete a projectile (via delete_enemy), adjusting enemy_projectile_count accordingly.
ROM4:831D LDA object_type,X
ROM4:831E CMP #ObjectType_Homing_Fireball_1 ; Check if ObjectType_Homing_Fireball_1 or ObjectType_Homing_Fireball_2. These
  ; don't count towards enemy_projectile_count, so don't decrement it.
ROM4:831F BEQ no_projectile_decrement
ROM4:8320 CMP #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:8321 BEQ no_projectile_decrement
 
ROM4:8346 decrement_projectile_count_and_delete_enemy: ; Decrement the projectile count when deleting a projectile
ROM4:8346 DEC enemy_projectile_count
 
ROM4:8347 no_projectile_decrement: ; X = object slot
ROM4:8347 JMP delete_enemy
 
ROM4:834C update_deflected_projectile: ; Update a projectile that's been blocked by Link's shield
ROM4:834C LDA enemy_state_11,X ; and is flying off diagonally.
ROM4:834D JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM4:834E LDA object_y,X
ROM4:834F CLC
ROM4:8350 ADC projectile_deflection_movement_y,Y
ROM4:8351 STA object_y,X
ROM4:8352 LDA object_x,X
ROM4:8353 CLC
ROM4:8354 ADC projectile_deflection_movement_x,Y
ROM4:8355 STA object_x,X
ROM4:8356 LDA object_tile_offset_whole,X
ROM4:8357 CLC
ROM4:8358 ADC #2
ROM4:8359 STA object_tile_offset_whole,X
ROM4:835A CMP #$20
ROM4:835B BCS delete_enemy_projectile ; Delete a projectile (via delete_enemy), adjusting enemy_projectile_count accordingly.
ROM4:835C BCC loc_10305 ; check if ObjectType_Moblin_Arrow
 
Subroutine check_link_hit_by_projectile
; Check if Link was hit by a projectile. ; Out var_6: If Link was hit, set to be true by check_link_hit_by_enemy. ; enemy_state_11[X]: Set to Link's direction if he was hit. ; walk_state_and_weapon_state[X] = 0x30 if Link was hit.
ROM4:8371 check_link_hit_by_projectile:
ROM4:8371 LDA #0
ROM4:8372 STA object_tile_offset_whole,X
ROM4:8373 JSR check_link_hit_by_enemy ; Check if Link was hit by an enemy. X is the enemy we're
  ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM4:8374 LDA projectile_hit_link ; This is set to 1 by check_link_hit_by_enemy if a projectile
  ; hits Link even if it's deflected by the shield, so it can
  ; be despawned.
ROM4:8375 BEQ ret
ROM4:8376 LDA object_direction
ROM4:8377 STA enemy_state_11,X
ROM4:8378 LDA #$30
ROM4:8379 STA walk_state_and_weapon_state,X
 
ROM4:837A ret:
ROM4:837A RTS
 
ROM4:8388 zola_fireball_speeds_x: .BYTE $70
ROM4:8389   .BYTE $68
ROM4:838A   .BYTE $60
ROM4:838B   .BYTE $58
ROM4:838C   .BYTE $50
ROM4:838D   .BYTE $3C
ROM4:838E   .BYTE $26
ROM4:838F   .BYTE $10
ROM4:8390 zola_fireball_speeds_y: .BYTE 0
ROM4:8391   .BYTE $10
ROM4:8392   .BYTE $26
ROM4:8393   .BYTE $3C
ROM4:8394   .BYTE $50
ROM4:8395   .BYTE $58
ROM4:8396   .BYTE $60
ROM4:8397   .BYTE $68
ROM4:8398   .BYTE $70
 
Subroutine update_monster_homing_fireball
ROM4:8399 update_monster_homing_fireball:
ROM4:8399 LDA walk_state_and_weapon_state,X
ROM4:839A BNE loc_103CC
ROM4:839B STA stop_enemy_for_frames,X
ROM4:839C STA enemy_state_2,X
ROM4:839D JSR sub_10704A ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
ROM4:839E LDA var_11
ROM4:839F STA enemy_state_0,X
ROM4:83A0 LDA var_10
ROM4:83A1 STA enemy_state_5,X
ROM4:83A2 ORA var_11
ROM4:83A3 STA object_direction,X
ROM4:83A4 LDY #4
ROM4:83A5 JSR sub_10706F ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
ROM4:83A6 LDA zola_fireball_speeds_x,Y
ROM4:83A7 STA enemy_projectile_speed_x,X
ROM4:83A8 LDA zola_fireball_speeds_y,Y
ROM4:83A9 STA enemy_state_6,X
ROM4:83AA LDA #$10
ROM4:83AB STA walk_state_and_weapon_state,X
ROM4:83AC STA enemy_action_timers,X
ROM4:83AD RTS
 
ROM4:83CC loc_103CC:
ROM4:83CC LDA enemy_action_timers,X
ROM4:83CD BNE loc_103FC
ROM4:83CE LDA object_direction,X
ROM4:83CF JSR check_object_against_screen_bounding_box_both_or_walking_state ; If the current object is out of the bounding box for the
  ; current screen on either axis and is moving in the direction
  ; it's out of bounds (A), clear walking_state to stop it
  ; moving further in that direction.
 
ROM4:83D0 BNE loc_103DA
 
ROM4:83D7 loc_103D7: ; X = object slot
ROM4:83D7 JMP delete_enemy
 
ROM4:83DA loc_103DA:
ROM4:83DA LDA enemy_state_0,X
ROM4:83DB STA var_15
ROM4:83DC LDA enemy_projectile_speed_x,X
ROM4:83DD LDY stop_enemy_for_frames,X
ROM4:83DE JSR update_monster_homing_fireball_0
ROM4:83DF STA stop_enemy_for_frames,X
ROM4:83E0 LDA enemy_state_5,X
ROM4:83E1 STA var_15
ROM4:83E2 LDA enemy_state_6,X
ROM4:83E3 LDY enemy_state_2,X
ROM4:83E4 JSR update_monster_homing_fireball_0
ROM4:83E5 STA enemy_state_2,X
 
ROM4:83FC loc_103FC: ; Check if Link was hit by a projectile.
ROM4:83FC JSR check_link_hit_by_projectile ; Out var_6: If Link was hit, set to be true by check_link_hit_by_enemy.
  ; enemy_state_11[X]: Set to Link's direction if he was hit.
  ; walk_state_and_weapon_state[X] = 0x30 if Link was hit.
ROM4:83FD LDA projectile_hit_link ; This is set to 1 by check_link_hit_by_enemy if a projectile
  ; hits Link even if it's deflected by the shield, so it can
  ; be despawned.
ROM4:83FE BNE loc_103D7
ROM4:83FF JMP loc_10305 ; check if ObjectType_Moblin_Arrow
 
Subroutine update_monster_homing_fireball_0
ROM4:8407 update_monster_homing_fireball_0:
ROM4:8407 STA object_walk_speed,X
ROM4:8408 TYA
ROM4:8409 STA object_tile_offset_fraction,X
ROM4:840A JSR process_movement
ROM4:840B LDA object_tile_offset_fraction,X
ROM4:840C RTS
 
Subroutine spawn_bubble
ROM4:8415 spawn_bubble:
ROM4:8415 LDA #$40
ROM4:8416 STA object_walk_speed,X ; Set bubble speed to 0x40
ROM4:8417 JMP spawn_monster_basic
  ; This is the common setup for most monsters. It just picks
  ; an initial walking direction, based on the enemy's spawn
  ; position and the player seek position (enemy_behavior_seek_x,
  ; enemy_behavior_seek_y).
 
Subroutine spawn_blue_keese
ROM4:841D spawn_blue_keese:
ROM4:841D LDA prng_0,X
ROM4:841E AND #7
ROM4:841F TAY
ROM4:8420 LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:8421 STA object_direction,X ; Set a random direction
ROM4:8422 JSR clear_some_enemy_state
ROM4:8423 LDA #$C0
ROM4:8424 STA increase_enemy_speed_max ; Set to 0xC0.
ROM4:8425 LDA #$1F
ROM4:8426 STA enemy_projectile_speed_x,X ; Set speed for blue keese to 0x1F
ROM4:8427 RTS
 
Subroutine spawn_red_keese
ROM4:8435 spawn_red_keese:
ROM4:8435 JSR spawn_blue_keese
ROM4:8436 LDA #$7F
ROM4:8437 STA enemy_projectile_speed_x,X ; Increase speed for red keese to 0x7F
ROM4:8438 RTS
 
Subroutine update_monster_bubble
ROM4:843E update_monster_bubble:
ROM4:843E LDA #$40
ROM4:843F JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:8440 LDA object_type,X ; check if ObjectType_Bubble
ROM4:8441 CMP #ObjectType_Bubble
ROM4:8442 BEQ is_bubble
ROM4:8443 SEC
ROM4:8444 SBC #ObjectType_Bubble
ROM4:8445 JMP loc_10454
 
ROM4:8446 is_bubble:
ROM4:8446 LDA frame_counter
ROM4:8447 AND #3
 
ROM4:8454 loc_10454: ; Store A in var_4 and var_5.
ROM4:8454 JSR store_A_in_tile_attributes
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:8455 LDA #1
ROM4:8456 JSR update_sprite_bubble_stalfos_flame_patra
ROM4:8457 JSR check_link_hit_by_enemy ; Check if Link was hit by an enemy. X is the enemy we're
  ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM4:8458 LDA var_6
ROM4:8459 BEQ locret_1046E
ROM4:845A LDA object_type,X ; check if ObjectType_Bubble
ROM4:845B CMP #ObjectType_Bubble
ROM4:845C BNE not_bubble
ROM4:845D LDA #$10
ROM4:845E STA bubble_sword_timer ; hit by bubble, set sword timer to 0x10
 
ROM4:846E locret_1046E:
ROM4:846E RTS
 
ROM4:846F not_bubble:
ROM4:846F SEC
ROM4:8470 SBC #ObjectType_BlueBubble
ROM4:8471 STA sword_disabled_by_bubble ; If ObjectType_BlueBubble, set to 0. If ObjectType_RedBubble, set to 1.
ROM4:8472 RTS
 
Subroutine update_sprite_bubble_stalfos_flame_patra
ROM4:8476 update_sprite_bubble_stalfos_flame_patra:
ROM4:8476 JSR update_object_animation_frame
ROM4:8477 JSR store_animation_frame
ROM4:8478 LDA #0
ROM4:8479 JMP update_object_sprite_horizontal
 
Subroutine update_monster_keese
ROM4:8481 update_monster_keese:
ROM4:8481 LDA clock_active ; Skip update if the clock is active.
ROM4:8482 ORA picking_up_item_timer ; Skip update if currently picking up an item.
ROM4:8483 BNE skip_if_frozen
ROM4:8484 JSR call_task_for_monster_state
ROM4:8485 JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
 
ROM4:8486 skip_if_frozen: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8486 JSR set_var_0_to_object_position
ROM4:8487 LDA enemy_state_5,X
ROM4:8488 AND #2
ROM4:8489 LSR A
ROM4:848A JSR update_object_sprite_vertical
ROM4:848B JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:848C JMP clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
 
ROM4:848D call_task_for_monster_state:
ROM4:848D LDA enemy_state_6,X
ROM4:848E JSR call_jump_table
 
ROM4:848F   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:8491   .WORD update_monster_keese_select_random_state_2_3_4 ; Randomly select state 2, 3 or 4.
ROM4:8493   .WORD update_monster_diagonal_movement_relative_to_seek ; Update the current enemy's direction relative to the seek
  ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:8495   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:8497   .WORD decrease_enemy_speed ; Decrease the object's speed by one each frame. Once
  ; the speed is under 0x20, switch to state 5.
ROM4:8499   .WORD reset_monster_state_after_npc_action_timers
 
Subroutine update_monster_keese_select_random_state_2_3_4
; Randomly select state 2, 3 or 4.
ROM4:84B3 update_monster_keese_select_random_state_2_3_4:
ROM4:84B3 LDY #2
ROM4:84B4 LDA prng_1,X
ROM4:84B5 CMP #$A0 ; If random value >= 0xA0, 2
ROM4:84B6 BCS set_enemy_state_4_and_6
ROM4:84B7 INY ; Move to state 3
ROM4:84B8 CMP #$20 ; If random value >= 0x20, 3
ROM4:84B9 BCS set_enemy_state_4_and_6
ROM4:84BA INY ; Move to state 4
 
ROM4:84C1 set_enemy_state_4_and_6:
ROM4:84C1 TYA
ROM4:84C2 STA enemy_state_6,X
ROM4:84C3 LDA #6
ROM4:84C4 STA enemy_state_4,X
ROM4:84C5 RTS
 
Subroutine update_monster_zol
ROM4:84CB update_monster_zol:
ROM4:84CB JSR loc_104E1
ROM4:84CC JSR update_monster_zol_1
ROM4:84CD JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:84CE LDY #0
ROM4:84CF LDA frame_counter
ROM4:84D0 AND #8
ROM4:84D1 BNE loc_104DD
ROM4:84D2 INY
 
ROM4:84DD loc_104DD:
ROM4:84DD TYA
ROM4:84DE JMP update_object_sprite_vertical
 
ROM4:84E1 loc_104E1:
ROM4:84E1 LDA walk_state_and_weapon_state,X
ROM4:84E2 JSR call_jump_table
 
ROM4:84E3   .WORD update_monster_zol_moving
ROM4:84E5   .WORD update_monster_vire_zol_1
ROM4:84E7   .WORD update_monster_zol_split_into_keese
 
Subroutine update_monster_zol_moving
ROM4:84EC update_monster_zol_moving:
ROM4:84EC LDA #$18 ; Zol movement speed
ROM4:84ED JMP update_monster_zol_moving_main ; This shares code with Gel movement.
 
Subroutine update_monster_vire_zol_1
ROM4:84F1 update_monster_vire_zol_1:
ROM4:84F1 JSR update_vire_zol_gel_movement
ROM4:84F2 BCC locret_104F8
ROM4:84F3 INC walk_state_and_weapon_state,X ; Set to 2
 
ROM4:84F8 locret_104F8:
ROM4:84F8 RTS
 
Subroutine update_monster_zol_split_into_keese
ROM4:84F9 update_monster_zol_split_into_keese:
ROM4:84F9 INC total_enemies_spawned_in_room ; We're spawning two Keese and deleting the Zol, so increase
  ; the enemy count by one for the difference.
ROM4:84FA JSR delete_enemy ; Delete the Zol.
ROM4:84FB JSR spawn_gel_from_zol
ROM4:84FC LDA object_direction,X
ROM4:84FD CMP #ControllerBits_Dpad_Down
  ; If this enemy was moving left or right, set the
  ; new gels to left.
ROM4:84FE LDA #ControllerBits_Dpad_Left
ROM4:84FF BCS down_or_up ; Store the direction of the new enemy.
ROM4:8500 LDA #ControllerBits_Dpad_Up ; Otherwise, set them to up.
 
ROM4:8501 down_or_up: ; Store the direction of the new enemy.
ROM4:8501 STA object_direction,Y
ROM4:8502 PHA ; Stash the direction, so we can set it again below.
ROM4:8503 JSR spawn_gel_from_zol
ROM4:8504 PLA ; Restore the direction in A.
ROM4:8505 LSR A ; If the first gel is moving left, the second moves right.
  ; If the first gel is moving down, the second moves up.
ROM4:8506 STA object_direction,Y
ROM4:8507 RTS
 
Subroutine spawn_gel_from_zol
ROM4:8519 spawn_gel_from_zol:
ROM4:8519 LDA #ObjectType_Gel1
ROM4:851A STA var_0
ROM4:851B JSR create_object_at_another_object ; Create ObjectType_Gel1.
ROM4:851C LDA #0
ROM4:851D STA walk_state_and_weapon_state,Y ; Set to 0
ROM4:851E LDA object_tile_offset_whole,X
ROM4:851F STA object_tile_offset_whole,Y
ROM4:8520 RTS
 
Subroutine update_monster_zol_1
ROM4:852C update_monster_zol_1:
ROM4:852C LDA walk_state_and_weapon_state,X
ROM4:852D BNE ret
ROM4:852E JSR check_zol_or_gel_hits
ROM4:852F LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:8530 BNE ret
ROM4:8531 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:8532 BEQ ret
ROM4:8533 LDY #0
ROM4:8534 LDA object_y,X
ROM4:8535 AND #$F
ROM4:8536 CMP #$D
ROM4:8537 BNE loc_10549
ROM4:8538 LDY #3
 
ROM4:8549 loc_10549:
ROM4:8549 STY var_0
ROM4:854A LDY #0
ROM4:854B LDA object_x,X
ROM4:854C AND #$F
ROM4:854D BNE loc_10555
ROM4:854E LDY #$C
 
ROM4:8555 loc_10555:
ROM4:8555 TYA
ROM4:8556 ORA var_0
ROM4:8557 AND object_direction
ROM4:8558 BNE loc_1055E
ROM4:8559 INC walk_state_and_weapon_state,X
 
ROM4:855E loc_1055E:
ROM4:855E INC walk_state_and_weapon_state,X
 
ROM4:855F ret:
ROM4:855F RTS
 
Subroutine spawn_gel2
ROM4:8561 spawn_gel2:
ROM4:8561 LDA #2
ROM4:8562 STA walk_state_and_weapon_state,X
ROM4:8563 JMP spawn_monster_basic
  ; This is the common setup for most monsters. It just picks
  ; an initial walking direction, based on the enemy's spawn
  ; position and the player seek position (enemy_behavior_seek_x,
  ; enemy_behavior_seek_y).
 
Subroutine update_monster_gel
ROM4:8568 update_monster_gel:
ROM4:8568 JSR loc_1058F
ROM4:8569 JSR check_zol_or_gel_hits
ROM4:856A LDA object_x,X
ROM4:856B PHA
ROM4:856C CLC
ROM4:856D ADC #4
ROM4:856E STA object_x,X
ROM4:856F JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8570 LDY #0
ROM4:8571 LDA frame_counter
ROM4:8572 AND #2
ROM4:8573 BNE loc_10582
ROM4:8574 INY
 
ROM4:8582 loc_10582:
ROM4:8582 LDA #3
ROM4:8583 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:8584 TYA
ROM4:8585 JSR update_object_sprite_horizontal
ROM4:8586 PLA
ROM4:8587 STA object_x,X
ROM4:8588 RTS
 
ROM4:858F loc_1058F:
ROM4:858F LDY walk_state_and_weapon_state,X
ROM4:8590 BEQ loc_105BA
ROM4:8591 DEY
ROM4:8592 BNE loc_105C6
ROM4:8593 LDA enemy_action_timers,X
ROM4:8594 BEQ loc_1059F
ROM4:8595 JSR update_vire_zol_gel_movement
ROM4:8596 BCC locret_105B9
 
ROM4:859F loc_1059F:
ROM4:859F LDA object_x,X
ROM4:85A0 CLC
ROM4:85A1 ADC #8
ROM4:85A2 AND #$F0
ROM4:85A3 STA object_x,X
ROM4:85A4 LDA object_y,X
ROM4:85A5 ADC #8
ROM4:85A6 AND #$F0
ROM4:85A7 ORA #$D
ROM4:85A8 STA object_y,X
ROM4:85A9 LDA #0
ROM4:85AA STA object_tile_offset_whole,X
ROM4:85AB INC walk_state_and_weapon_state,X
 
ROM4:85B9 locret_105B9:
ROM4:85B9 RTS
 
ROM4:85BA loc_105BA:
ROM4:85BA LDA #$20
ROM4:85BB STA object_walk_speed,X
ROM4:85BC LDA #5
ROM4:85BD STA enemy_action_timers,X
ROM4:85BE INC walk_state_and_weapon_state,X
ROM4:85BF RTS
 
ROM4:85C6 loc_105C6: ; Gel movement speed
ROM4:85C6 LDA #$40
 
ROM4:85C8 update_monster_zol_moving_main:
ROM4:85C8 STA object_walk_speed,X
ROM4:85C9 LDA enemy_action_timers,X
ROM4:85CA CMP #5
ROM4:85CB BCS locret_105F5
ROM4:85CC LDA #$20
ROM4:85CD STA enemy_projectile_speed_x,X
ROM4:85CE JSR update_movement_or_fire_projectile_if_zero_timer
ROM4:85CF LDA object_tile_offset_whole,X
ROM4:85D0 ORA enemy_action_timers,X
ROM4:85D1 BNE locret_105F5
ROM4:85D2 LDA prng_0,X
ROM4:85D3 AND #3
ROM4:85D4 TAY
ROM4:85D5 LDA object_type,X ; check if ObjectType_Zol
ROM4:85D6 CMP #ObjectType_Zol
ROM4:85D7 BEQ loc_105F0
ROM4:85D8 INY
ROM4:85D9 INY
ROM4:85DA INY
ROM4:85DB INY
 
ROM4:85F0 loc_105F0:
ROM4:85F0 LDA byte_105F6,Y
ROM4:85F1 STA enemy_action_timers,X
 
ROM4:85F5 locret_105F5:
ROM4:85F5 RTS
 
ROM4:85F6 byte_105F6: .BYTE $18
ROM4:85F7   .BYTE $28
ROM4:85F8   .BYTE $38
ROM4:85F9   .BYTE $48
ROM4:85FA   .BYTE 8
ROM4:85FB   .BYTE $18
ROM4:85FC   .BYTE $28
ROM4:85FD   .BYTE $38
 
Subroutine update_vire_zol_gel_movement
ROM4:85FE update_vire_zol_gel_movement:
ROM4:85FE LDA #$FF
ROM4:85FF STA object_walk_speed,X
ROM4:8600 LDA object_direction,X
ROM4:8601 STA var_15
ROM4:8602 LDA object_tile_offset_whole,X
ROM4:8603 BNE not_on_tile
ROM4:8604 JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM4:8605 CMP screen_first_solid_tile_id
ROM4:8606 BCS ret ; Branch if we can't move further in this direction because
  ; we're blocked by the screen boundary or an obstacle
 
ROM4:8607 not_on_tile: ; If the current object is out of the bounding box for the
ROM4:8607 JSR check_object_against_screen_bounding_box_both ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM4:8608 SEC
ROM4:8609 BEQ ret
ROM4:860A JSR process_movement
ROM4:860B LDA object_tile_offset_whole,X
ROM4:860C AND #$F
ROM4:860D CLC
ROM4:860E BNE ret
ROM4:860F STA object_tile_offset_whole,X
 
ROM4:8610 ret:
ROM4:8610 RTS
 
Subroutine check_zol_or_gel_hits
ROM4:8629 check_zol_or_gel_hits:
ROM4:8629 LDA object_x,X
ROM4:862A STA var_2
ROM4:862B LDA object_y,X
ROM4:862C STA var_3
ROM4:862D JMP check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
 
ROM4:8634 byte_10634: .BYTE $24
ROM4:8635   .BYTE $23
ROM4:8636 byte_10636: .BYTE 3
ROM4:8637   .BYTE 1
ROM4:8638   .BYTE 1
ROM4:8639 byte_10639: .BYTE $50
ROM4:863A   .BYTE $80
ROM4:863B   .BYTE $F0
ROM4:863C   .BYTE $60
ROM4:863D byte_1063D: .BYTE 0
ROM4:863E   .BYTE 4
ROM4:863F   .BYTE 6
ROM4:8640 byte_10640: .BYTE $24
ROM4:8641   .BYTE $C8
ROM4:8642   .BYTE $24
ROM4:8643   .BYTE $C8
ROM4:8644   .BYTE $64
ROM4:8645   .BYTE $88
ROM4:8646   .BYTE $48
ROM4:8647   .BYTE $A8
ROM4:8648 byte_10648: .BYTE $C0
ROM4:8649   .BYTE $BC
ROM4:864A   .BYTE $64
ROM4:864B   .BYTE $5C
ROM4:864C   .BYTE $94
ROM4:864D   .BYTE $8C
ROM4:864E   .BYTE $82
ROM4:864F   .BYTE $86
 
Subroutine check_dungeon_shoot_fireball
ROM4:8650 check_dungeon_shoot_fireball:
ROM4:8650 LDY #2
ROM4:8651 LDA dungeon_shoots_fireballs ; Check if the room is explicitly set to shoot fireballs, eg.
  ; after attacking the old man.
ROM4:8652 BNE dungeon_can_shoot
ROM4:8653 JSR dungeon_get_screen_code ; Otherwise, see if this room is in the list of screen codes
  ; that shoots fireballs.
ROM4:8654 LDY #1
 
ROM4:8655 loop:
ROM4:8655 CMP byte_10634,Y
ROM4:8656 BEQ dungeon_can_shoot ; Branch if the screen code is 0x23 or 0x24.
ROM4:8657 DEY
ROM4:8658 BPL loop
ROM4:8659 RTS
 
ROM4:865A dungeon_can_shoot: ; Push Y
ROM4:865A TYA ; Y = 0 for screen code 23, 1 for screen code 24,
  ; or 2 for dungeon_shoots_fireballs.
ROM4:865B PHA
ROM4:865C JSR find_last_available_object_idx ; Result is returned in tmp_result.
ROM4:865D CMP #1
ROM4:865E PLA ; Pop A (from Y)
ROM4:865F BCS ret
ROM4:8660 CPY #6
ROM4:8661 BCC ret ; Return if object index < 6
ROM4:8662 STY var_10 ; Store object slot
ROM4:8663 STA var_11
ROM4:8664 TAY
ROM4:8665 LDX byte_10636,Y
 
ROM4:8666 loop2:
ROM4:8666 LDY byte_4E8,X
ROM4:8667 DEY
ROM4:8668 TYA
ROM4:8669 STA byte_4E8,X
ROM4:866A INY
ROM4:866B BNE continue
ROM4:866C LDA prng_0,X
ROM4:866D CMP #$F0
ROM4:866E BCS continue
ROM4:866F AND #3
ROM4:8670 TAY
ROM4:8671 LDA byte_10639,Y
ROM4:8672 STA byte_4E8,X
ROM4:8673 LDY var_11
ROM4:8674 TXA
ROM4:8675 CLC
ROM4:8676 ADC byte_1063D,Y
ROM4:8677 TAY
ROM4:8678 TXA ; Save X.
ROM4:8679 PHA
ROM4:867A LDX #0 ; Set X = 0 (Link).
ROM4:867B JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:867C LDX var_10
ROM4:867D LDA byte_10640,Y
ROM4:867E STA var_2
ROM4:867F STA object_x,X
ROM4:8680 LDA byte_10648,Y
ROM4:8681 STA var_3
ROM4:8682 STA object_y,X
ROM4:8683 LDA #3
ROM4:8684 STA var_4
ROM4:8685 LDY #1
 
ROM4:8686 loop3:
ROM4:8686 LDA var_0,Y
ROM4:8687 SEC
ROM4:8688 SBC var_2,Y
ROM4:8689 CMP #24
ROM4:868A BPL loc_106CB ; Branch if var_0[Y] - var_2[Y] >= 24?
ROM4:868B CMP #232
ROM4:868C BMI loc_106CB ; Branch if var_0[Y] - var_2[Y] < 232?
ROM4:868D LSR var_4 ; var_4 >>= 1
 
ROM4:86CB loc_106CB:
ROM4:86CB DEY
ROM4:86CC BPL loop3
ROM4:86CD LDA var_4
ROM4:86CE BEQ skip_create_fireball ; Branch if var_4 is 0
ROM4:86CF LDA #ObjectType_Homing_Fireball_1
ROM4:86D0 JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_1.
 
ROM4:86D1 skip_create_fireball:
ROM4:86D1 PLA
ROM4:86D2 TAX ; Restore X.
 
ROM4:86D3 continue:
ROM4:86D3 DEX
ROM4:86D4 BPL loop2
 
ROM4:86D5 ret:
ROM4:86D5 RTS
 
ROM4:86D6   .BYTE $FF
ROM4:86D7   .BYTE $FF
ROM4:86D8   .BYTE $FF
 
Subroutine check_create_zola
ROM4:86E0 check_create_zola:
ROM4:86E0 LDY map_location
ROM4:86E1 LDA dungeon_screen_data_0,Y ; See if we should create a Zola on this overworld screen
ROM4:86E2 AND #ScreenData_Overworld_0_Zola
ROM4:86E3 BEQ ret ; Stop if this screen doesn't have Zola
ROM4:86E4 LDA is_zola_spawned ; Stop if Zola is already spawned. This is also left at 1 if
  ; Zola is killed, so we don't keep spawning him.
ROM4:86E5 BNE ret
ROM4:86E6 JSR find_last_available_object_idx ; Find a slot to spawn Zola.
ROM4:86E7 BEQ ret
ROM4:86E8 LDA #13 ; Try each PRNG entry to find a valid place to put Zola.
ROM4:86E9 STA var_13
ROM4:86EA LDX tmp_result
 
ROM4:86EB loop:
ROM4:86EB LDY var_13
ROM4:86EC LDA prng_0,Y ; Pick a random X position for Zola
ROM4:86ED AND #$F0
ROM4:86EE STA object_x,X
ROM4:86EF BEQ try_again ; Try again if 0
ROM4:86F0 CMP #$F0
ROM4:86F1 BEQ try_again ; Try again if 0xFx
ROM4:86F2 LDA prng_0,Y ; Pick a random Y position for Zola
ROM4:86F3 ASL A
ROM4:86F4 ASL A
ROM4:86F5 ASL A
ROM4:86F6 ASL A
ROM4:86F7 CMP #$50 ; Try again if < 0x50
ROM4:86F8 BCC try_again
ROM4:86F9 CMP #$E0 ; Try again if >= 0xE0
ROM4:86FA BCS try_again
ROM4:86FB ORA #$D ; Nudge Zola Down
ROM4:86FC STA object_y,X
ROM4:86FD JSR set_tile_walking_onto_1 ; Set tile_walking_onto for the current object.
ROM4:86FE CMP #$8D ; Try again if tile flag < 0x8D or tile flag >= 0x99
  ; (not water tile?)
ROM4:86FF BCC try_again
ROM4:8700 CMP #$99
ROM4:8701 BCS try_again
ROM4:8702 INC is_zola_spawned
ROM4:8703 LDA #ObjectType_Zola
ROM4:8704 JMP create_enemy ; Create ObjectType_Zola.
 
ROM4:8705 try_again: ; This position wasn't a valid place to put Zola. Try
ROM4:8705 DEC var_13 ; the next PRNG value.
ROM4:8706 BNE loop
 
ROM4:8707 ret:
ROM4:8707 RTS
 
ROM4:8733 tektite_initial_directions: .BYTE ControllerBits_Dpad_Right
ROM4:8734   .BYTE ControllerBits_Dpad_Left
ROM4:8735   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
ROM4:8736   .BYTE ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
 
Subroutine spawn_falling_rocks_spawner
ROM4:8737 spawn_falling_rocks_spawner:
ROM4:8737 LDA #0
ROM4:8738 STA number_of_spawned_falling_rocks
 
ROM4:873C spawn_falling_rock:
ROM4:873C JSR spawn_monster_no_timer_no_spawn_cloud
 
ROM4:873F spawn_tektite: ; Pick a random initial direction.
ROM4:873F LDA prng_1,X
ROM4:8740 AND #3
ROM4:8741 TAY
ROM4:8742 LDA tektite_initial_directions,Y
ROM4:8743 STA object_direction,X ; Set initial direction for Tektite-like enemies
ROM4:8744 ASL A
ROM4:8745 ASL A
ROM4:8746 STA enemy_action_timers,X ; Set an initial delay based on the initial direction.
ROM4:8747 RTS
 
Subroutine spawn_leever
ROM4:874E spawn_leever:
ROM4:874E LDA #5
ROM4:874F STA leever_timer
ROM4:8750 JSR spawn_monster_no_timer_no_spawn_cloud
 
ROM4:8755 spawn_monster_octorok_or_ghini_master: ; Walk speed for Octorok and Ghini
ROM4:8755 LDA #$20
ROM4:8756 BNE not_fast_octorok ; This is always true, but BNE is smaller than JMP
 
ROM4:8759 spawn_monster_fast_octorok: ; Walk speed for fast Octorok
ROM4:8759 LDA #$30
 
ROM4:875A not_fast_octorok: ; Initialize Octorok or Ghini's walk speed
ROM4:875A STA object_walk_speed,X
ROM4:875B INX ; A = (Object ID - 1) << 4
ROM4:875C TXA
ROM4:875D DEX
ROM4:875E ASL A
ROM4:875F ASL A
ROM4:8760 ASL A
ROM4:8761 ASL A
ROM4:8762 STA enemy_action_timers,X ; Set an initial action timer based on our object ID, so all enemies don't fire at the same time
ROM4:8763 JSR clear_weapon_state ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM4:8764 STA object_animation_frame,X ; XXX: What is this?
ROM4:8765 LDA #6
ROM4:8766 STA object_animation_frame_timer,X ; Set state3[X] = 6
ROM4:8767 JMP spawn_monster_basic ; Continue with general initialization
 
Subroutine spawn_peahat
ROM4:8775 spawn_peahat:
ROM4:8775 JSR spawn_monster_no_timer_no_spawn_cloud
ROM4:8776 LDA #ControllerBits_Dpad_Up
ROM4:8777 STA object_direction,X ; Peahats always spawn facing up
 
ROM4:877C from_spawn_ghini_from_tombs:
ROM4:877C JSR clear_some_enemy_state
ROM4:877D LDA #$A0
ROM4:877E STA increase_enemy_speed_max ; Set to 0xA0.
ROM4:877F LDA #$1F
ROM4:8780 STA enemy_projectile_speed_x,X ; Set to 0x1F
ROM4:8781 RTS
 
Subroutine spawn_lake_fairy
ROM4:878A spawn_lake_fairy:
ROM4:878A LDA #Sound1_Fairy
ROM4:878B STA play_sound_1 ; Play Sound1_Fairy
ROM4:878C LDA #120 ; Set fairy position on screen
ROM4:878D STA object_x,X
ROM4:878E LDA #125
ROM4:878F STA object_y,X
 
ROM4:8797 locret_10797:
ROM4:8797 RTS
 
Subroutine update_monster_zola
ROM4:8798 update_monster_zola:
ROM4:8798 LDA clock_active
ROM4:8799 BNE locret_10797
ROM4:879A JSR update_leever_from_zola
ROM4:879B LDA walk_state_and_weapon_state,X
ROM4:879C CMP #3
ROM4:879D BNE loc_107B5
ROM4:879E LDA enemy_action_timers,X
ROM4:879F CMP #$FD
ROM4:87A0 BNE loc_107B5
ROM4:87A1 LDA #ObjectType_Homing_Fireball_1
ROM4:87A2 JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_1.
ROM4:87A3 LDA #$20
ROM4:87A4 STA enemy_action_timers,X
 
ROM4:87B5 loc_107B5:
ROM4:87B5 LDA walk_state_and_weapon_state,X
ROM4:87B6 BNE locret_10797
ROM4:87B7 DEC is_zola_spawned
ROM4:87B8 JMP delete_enemy ; X = object slot
 
Subroutine update_monster_moblin
ROM4:87BF update_monster_moblin:
ROM4:87BF LDA #$A0
ROM4:87C0 STA enemy_projectile_speed_x,X ; moblin: set to 0xA0
ROM4:87C1 JSR update_movement_or_fire_projectile_if_zero_timer
ROM4:87C2 LDY #ObjectType_Moblin_Arrow
ROM4:87C3 JMP jump_from_update_monster_moblin
 
Subroutine update_monster_lynel
ROM4:87CC update_monster_lynel:
ROM4:87CC JSR update_monster_goriya
ROM4:87CD LDY #ObjectType_Lynel_Sword
 
  ; Y is the enemy's projectile type on these branches.
 
ROM4:87D1 jump_from_update_monster_moblin: ; Lynel and Moblin movement speed
ROM4:87D1 LDA #$20
 
ROM4:87D3 jump_from_update_monster_octorok: ; We can get here with object types of moblin,
ROM4:87D3 STA var_1 ; lynel or octorok. Y is the object type of the
  ; projectile.
 
  ; Save the enemy's movement speed.
ROM4:87D4 LDA object_type,X ; Check if this is the blue version of a monster.
ROM4:87D5 CMP #ObjectType_BlueMoblin
ROM4:87D6 BEQ is_blue
ROM4:87D7 CMP #ObjectType_BlueLynel
ROM4:87D8 BEQ is_blue
ROM4:87D9 CMP #ObjectType_BlueOctorok
ROM4:87DA BEQ is_blue
ROM4:87DB CMP #ObjectType_BlueOctorokFast
ROM4:87DC BEQ is_blue
ROM4:87DD LDA stop_enemy_for_frames,X ; This is the red version of this monster.
ROM4:87DE BNE is_blue
ROM4:87DF LDA prng_0,X ; For red monsters, skip our chance to fire a projectile
  ; 0xF8/0xFF times (97%).
ROM4:87E0 CMP #$F8
ROM4:87E1 BCC locret_10831 ; A < 0xF8
 
ROM4:87E2 is_blue: ; Restore the enemy's movement speed.
ROM4:87E2 LDA var_1
ROM4:87E3 STY var_0 ; Store Y, which is the object type of this monster's projectile.
ROM4:87E4 PHA ; Push A, the enemy's movement speed.
ROM4:87E5 LDY #0
ROM4:87E6 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:87E7 BNE enemy_is_stopped
ROM4:87E8 LDY stop_enemy_for_frames,X
ROM4:87E9 DEY ; Decrement time until enemy can move
ROM4:87EA BPL enemy_is_stopped ; Branch if we still can't move
ROM4:87EB LDA enemy_state_0,X ; If we're still about to fire a projectile,
ROM4:87EC BEQ store_walking_speed ; Branch if A == 0 (not about to fire projectile)
ROM4:87ED LDY #$30 ; Don't move for 0x30 frames
 
ROM4:87EE enemy_is_stopped:
ROM4:87EE TYA
ROM4:87EF STA stop_enemy_for_frames,X ; Store decremented (or new) enemy delay
ROM4:87F0 BEQ store_walking_speed
ROM4:87F1 CPY #$10
ROM4:87F2 BNE zero_walking_speed ; XXX: not actually walking speed
ROM4:87F3 LDA clock_active
ROM4:87F4 ORA enemy_stun,X
ROM4:87F5 BNE zero_walking_speed ; XXX: not actually walking speed
ROM4:87F6 LDA var_0 ; Restore the object type of this monster's projectile.
ROM4:87F7 JSR create_moblin_octorok_lynel_projectile
ROM4:87F8 BCC store_walking_speed
ROM4:87F9 LDA #0
ROM4:87FA STA enemy_state_0,X
 
ROM4:87FB zero_walking_speed: ; Pop stored A, replace with 0, push it back
ROM4:87FB PLA
ROM4:87FC LDA #0
ROM4:87FD PHA
 
ROM4:87FE store_walking_speed: ; Pop stored A
ROM4:87FE PLA
ROM4:87FF STA object_walk_speed,X ; Walk speed for Lynel
 
ROM4:8831 locret_10831:
ROM4:8831 RTS
 
Subroutine create_moblin_octorok_lynel_projectile
ROM4:8832 create_moblin_octorok_lynel_projectile:
ROM4:8832 JSR create_object_at_another_object_2 ; Create ObjectType_Moblin_Arrow, ObjectType_Octorok_Projectile or ObjectType_Lynel_Sword.
ROM4:8833 BCC locret_1083E ; Branch if we couldn't create a projectile.
ROM4:8834 LDA #$80
ROM4:8835 STA enemy_action_timers,X ; Set enemy timer to 0x80 frames after firing a projectile.
ROM4:8836 DEC enemy_state_5,X
 
ROM4:883E locret_1083E:
ROM4:883E RTS
 
Subroutine update_monster_moblin_arrow
ROM4:883F update_monster_moblin_arrow:
ROM4:883F LDA #$80
ROM4:8840 STA object_walk_speed,X
ROM4:8841 LDA enemy_action_timers,X
ROM4:8842 BNE loc_1085C
ROM4:8843 LDA walk_state_and_weapon_state,X
ROM4:8844 AND #$F0
ROM4:8845 CMP #$20
ROM4:8846 BEQ loc_10869
ROM4:8847 CMP #$10
ROM4:8848 BNE loc_1087F
ROM4:8849 LDA object_direction,X
ROM4:884A STA var_15
ROM4:884B JMP loc_10869
 
ROM4:885C loc_1085C:
ROM4:885C LDY enemy_state_4,X
ROM4:885D LDA object_type,Y
ROM4:885E BNE loc_10866
ROM4:885F STA enemy_action_timers,X
 
ROM4:8866 loc_10866:
ROM4:8866 JMP update_arrow
 
ROM4:8869 loc_10869:
ROM4:8869 JSR update_projectile
ROM4:886A LDA walk_state_and_weapon_state,X
ROM4:886B AND #$F0
ROM4:886C CMP #$10
ROM4:886D BNE loc_1087F
ROM4:886E JSR check_link_hit_by_projectile ; Check if Link was hit by a projectile.
  ; Out var_6: If Link was hit, set to be true by check_link_hit_by_enemy.
  ; enemy_state_11[X]: Set to Link's direction if he was hit.
  ; walk_state_and_weapon_state[X] = 0x30 if Link was hit.
ROM4:886F LDA var_6 ; Check if Link was hit to delete the projectile.
ROM4:8870 BEQ locret_1083E
ROM4:8871 JMP decrement_projectile_count_and_delete_enemy ; Decrement the projectile count when deleting a projectile
 
ROM4:887F loc_1087F:
ROM4:887F CMP #$30
ROM4:8880 BNE locret_1083E
ROM4:8881 JMP update_deflected_projectile ; Update a projectile that's been blocked by Link's shield
  ; and is flying off diagonally.
 
Subroutine update_monster_falling_rock_daemon
ROM4:8886 update_monster_falling_rock_daemon:
ROM4:8886 LDA enemy_action_timers,X
ROM4:8887 BNE ret ; Skip if it's not yet time to spawn another rock.
ROM4:8888 LDA number_of_spawned_falling_rocks
ROM4:8889 CMP #3
ROM4:888A BEQ max_rocks ; Stop if there are already three falling rocks.
ROM4:888B JSR find_last_available_object_idx ; Result is returned in tmp_result.
ROM4:888C BEQ ret ; Skip if there are no available object slots.
ROM4:888D LDX tmp_result
ROM4:888E INC number_of_spawned_falling_rocks ; Increase the rock spawn count.
ROM4:888F LDA #ObjectType_FallingRock
ROM4:8890 JSR create_enemy ; Create a ObjectType_FallingRock.
ROM4:8891 LDA prng_1,X ; Load a random X position to spawn the rock.
ROM4:8892 LDY enemy_behavior_seek_x
ROM4:8893 CPY #$80
ROM4:8894 BCS seek_right_side
ROM4:8895 AND #$7F ; If we're seeking to the left side of the screen, always pick a random spot on the left side.
ROM4:8896 JMP skip_seel_right_side
 
ROM4:8897 seek_right_side: ; If we're seeking to the right side of the screen, always pick a random spot on the right side.
ROM4:8897 ORA #$80
 
ROM4:8898 skip_seel_right_side: ; Set the random X position for the new falling rock.
ROM4:8898 STA object_x,X
ROM4:8899 LDA #$40
ROM4:889A STA object_y,X ; Spawn falling rocks at the top of the screen.
ROM4:889B LDX processing_object_index ; Restore the object ID of the rock daemon (we set it to the ID of the new rock above).
ROM4:889C LDA #8
ROM4:889D CLC
ROM4:889E ADC prng_1,X
ROM4:889F AND #$1F
ROM4:88A0 STA enemy_action_timers,X ; Don't spawn another rock for 8 to 39 frames.
ROM4:88A1 RTS
 
ROM4:88A2 max_rocks: ; If there were already the max number of rocks, don't spawn more rocks for 0-255 frames. This slows down spawning after the first three rocks are spawned.
ROM4:88A2 LDA enemy_action_timers,X
ROM4:88A3 CLC
ROM4:88A4 ADC prng_1,X
ROM4:88A5 STA enemy_action_timers,X
 
ROM4:88A6 ret:
ROM4:88A6 RTS
 
ROM4:88CA tektite_data_1: .BYTE 0
ROM4:88CB   .BYTE 0 ; Right
ROM4:88CC   .BYTE 0 ; Left
ROM4:88CD   .BYTE 0 ; Right|Left
ROM4:88CE   .BYTE 0 ; Down
ROM4:88CF   .BYTE $20 ; Down|Right
ROM4:88D0   .BYTE $20 ; Down|Left
ROM4:88D1   .BYTE 0 ; Down|Left|Right
ROM4:88D2   .BYTE 0 ; Up
ROM4:88D3   .BYTE $E0 ; Up|Right
ROM4:88D4   .BYTE $E0 ; Up|Left
ROM4:88D5 tektite_data_2: .BYTE 0
ROM4:88D6   .BYTE $40
ROM4:88D7   .BYTE $40
ROM4:88D8   .BYTE 0
ROM4:88D9   .BYTE 0
ROM4:88DA   .BYTE $40
ROM4:88DB   .BYTE $40
ROM4:88DC   .BYTE 0
ROM4:88DD   .BYTE 0
ROM4:88DE   .BYTE $30
ROM4:88DF   .BYTE $30
ROM4:88E0   .BYTE 0
ROM4:88E1   .BYTE $80
ROM4:88E2   .BYTE $80
ROM4:88E3   .BYTE 0
ROM4:88E4   .BYTE 0
ROM4:88E5   .BYTE $80
ROM4:88E6   .BYTE $80
ROM4:88E7   .BYTE 0
ROM4:88E8   .BYTE 0
ROM4:88E9   .BYTE $50
ROM4:88EA   .BYTE $50
ROM4:88EB   .BYTE $60
ROM4:88EC   .BYTE $60
ROM4:88ED   .BYTE $60
ROM4:88EE   .BYTE $60
ROM4:88EF   .BYTE $60
ROM4:88F0   .BYTE $60
ROM4:88F1   .BYTE $60
ROM4:88F2 tektite_data_3: .BYTE $FD ; ObjectType_BlueTektite
ROM4:88F3   .BYTE $FC ; ObjectType_RedTektite
ROM4:88F4   .BYTE $FE ; ObjectType_FallingRock
ROM4:88F5 tektite_data_4: .BYTE 0 ; ObjectType_BlueTektite
ROM4:88F6   .BYTE $B ; ObjectType_RedTektite
ROM4:88F7   .BYTE $16 ; ObjectType_FallingRock
 
Subroutine update_monster_tektite_or_falling_rock
ROM4:88F8 update_monster_tektite_or_falling_rock:
ROM4:88F8 LDA object_knockback,X
ROM4:88F9 BEQ no_knockback
ROM4:88FA JMP update_object_knockback
 
ROM4:88FB stunned_or_clock:
ROM4:88FB JMP skip_setting_action_timer
 
ROM4:88FC no_knockback:
ROM4:88FC LDA clock_active
ROM4:88FD ORA enemy_stun,X
ROM4:88FE BNE stunned_or_clock
ROM4:88FF LDA walk_state_and_weapon_state,X
ROM4:8900 BNE loc_10959
ROM4:8901 LDA enemy_action_timers,X
ROM4:8902 BNE enemy_timer_not_expired
ROM4:8903 JSR update_monster_diagonal_movement_relative_to_seek_from_digdogger
ROM4:8904 LDA object_direction,X
ROM4:8905 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:8906 BNE not_left_or_right
ROM4:8907 LDY #ControllerBits_Dpad_Left
ROM4:8908 LDA enemy_behavior_seek_x
ROM4:8909 CMP object_x,X
ROM4:890A BCC seek_left ; Branch if seek X < object X
ROM4:890B DEY ; Y = ControllerBits_Dpad_Right
 
ROM4:890C seek_left:
ROM4:890C TYA
ROM4:890D ORA object_direction,X
ROM4:890E STA object_direction,X
 
ROM4:890F not_left_or_right:
ROM4:890F INC walk_state_and_weapon_state,X
 
ROM4:8910 bounce_at_edge_of_screen:
ROM4:8910 LDA stop_enemy_for_frames,X
ROM4:8911 CMP #2
ROM4:8912 BCC stopped_for_less_than_two_frames ; This will be 1 if we're coming from the bounce_at_edge_of_screen branch.
ROM4:8913 LDA object_direction,X
ROM4:8914 EOR #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:8915 STA object_direction,X ; Flip left/right movement.
ROM4:8916 LDA #0
ROM4:8917 STA stop_enemy_for_frames,X ; Clear the enemy being stopped.
 
ROM4:8918 stopped_for_less_than_two_frames: ; If this is a FallingRock, set its vertical direction to down. This does nothing for Tektites.
ROM4:8918 JSR set_falling_rock_moving_down
ROM4:8919 LDY object_direction,X
ROM4:891A LDA object_y,X
ROM4:891B CLC
ROM4:891C ADC tektite_data_1,Y
ROM4:891D STA enemy_state_6,X
ROM4:891E JSR get_bouncy_object_type ; If X = blue tektite, Y = 0. If red tektite, Y = 1. Otherwise (falling rock), Y = 2.
ROM4:891F LDA tektite_data_3,Y
ROM4:8920 STA enemy_state_0,X
ROM4:8921 JSR tektite_set_zero_speed
 
ROM4:8922 enemy_timer_not_expired:
ROM4:8922 JMP skip_setting_action_timer
 
ROM4:8959 loc_10959: ; If this object is walking out of the boundary of this
ROM4:8959 JSR reverse_walking_direction_if_out_of_bounds ; screen, turn around.
ROM4:895A LDA var_15
ROM4:895B BNE not_at_screen_edge
ROM4:895C INC stop_enemy_for_frames,X ; When we hit the edge of the screen, pause for a frame before bouncing.
ROM4:895D JMP bounce_at_edge_of_screen
 
ROM4:895E not_at_screen_edge: ; If this is a FallingRock, set its vertical direction to down. This does nothing for Tektites.
ROM4:895E JSR set_falling_rock_moving_down
ROM4:895F LDA #0
ROM4:8960 STA stop_enemy_for_frames,X
ROM4:8961 JSR get_bouncy_object_type ; If X = blue tektite, Y = 0. If red tektite, Y = 1. Otherwise (falling rock), Y = 2.
ROM4:8962 LDA tektite_data_4,Y
ROM4:8963 CLC
ROM4:8964 ADC object_direction,X
ROM4:8965 TAY
ROM4:8966 LDA tektite_data_2,Y
ROM4:8967 LDY #2 ; Y = 2
ROM4:8968 JSR tektite_update_position
ROM4:8969 LDY #$FF
ROM4:896A LDA object_direction,X
ROM4:896B AND #ControllerBits_Dpad_Left
ROM4:896C BNE left
ROM4:896D LDY #1 ; Y = 1
 
ROM4:896E left: ; A = Y
ROM4:896E TYA
ROM4:896F CLC
ROM4:8970 ADC object_x,X
ROM4:8971 STA object_x,X
ROM4:8972 LDA enemy_state_0,X
ROM4:8973 BMI skip_setting_action_timer
ROM4:8974 LDA object_y,X
ROM4:8975 SEC
ROM4:8976 SBC enemy_state_6,X
ROM4:8977 JSR absolute_value ; A = abs(A)
ROM4:8978 CMP #3
ROM4:8979 BCS skip_setting_action_timer
ROM4:897A JSR clear_weapon_state ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM4:897B LDY object_type,X
ROM4:897C CPY #ObjectType_FallingRock
ROM4:897D BEQ set_time_to_next_jump ; Skip ahead with A = 0 if ObjectType_FallingRock. Rocks never delay before jumping again.
ROM4:897E LDA #$10 ; A = 0x10
ROM4:897F CLC
ROM4:8980 ADC prng_1,X ; A += 0x40
ROM4:8981 CMP #$20
ROM4:8982 BCS random_delay_valid ; Branch if A >= 0x20 (minimum delay before another jump).
ROM4:8983 SEC
ROM4:8984 SBC #$40 ; The random jump time we chose is too small. Subtract 0x40, which will wrap.
 
ROM4:8985 random_delay_valid:
ROM4:8985 LDY object_type,X
ROM4:8986 CPY #ObjectType_BlueTektite
ROM4:8987 BEQ set_time_to_next_jump
ROM4:8988 AND #$7F ; ObjectType_RedTektite
ROM4:8989 LDY prng_1,X
ROM4:898A CPY #$A0
ROM4:898B BCC set_time_to_next_jump
ROM4:898C AND #$F ; For red tektites, if PRNG >= 0xA0 (37% chance), jump quickly in 0-15 frames instead.
 
ROM4:898D set_time_to_next_jump:
ROM4:898D STA enemy_action_timers,X
 
ROM4:898E skip_setting_action_timer: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:898E JSR set_var_0_to_object_position
ROM4:898F STA var_13
ROM4:8990 LDA object_type,X
ROM4:8991 CMP #ObjectType_FallingRock
ROM4:8992 BEQ is_falling_rock
ROM4:8993 LDA walk_state_and_weapon_state,X
ROM4:8994 BNE loc_109E9
ROM4:8995 LDY enemy_action_timers,X
ROM4:8996 CPY #$21
ROM4:8997 BCC loc_109E9
ROM4:8998 LDA #$10
ROM4:8999 JSR update_object_animation_frame
ROM4:899A LDA object_animation_frame,X
 
ROM4:89E9 loc_109E9:
ROM4:89E9 JMP update_sprite_and_check_hits_for_tektite
 
ROM4:89EA is_falling_rock:
ROM4:89EA LDA #6
ROM4:89EB JSR update_object_animation_frame
ROM4:89EC LDA object_animation_frame,X
ROM4:89ED JSR loc_10CAC
ROM4:89EE LDA object_y,X ; Check if this falling rock is at the bottom of the screen and needs to be despawned.
ROM4:89EF CMP #$F0
ROM4:89F0 BCC locret_10A10
ROM4:89F1 DEC number_of_spawned_falling_rocks ; We're despawning a falling rock, so decrease the spawned rock counter.
ROM4:89F2 JMP delete_enemy ; X = object slot
 
Subroutine get_bouncy_object_type
; If X = blue tektite, Y = 0. If red tektite, Y = 1. Otherwise (falling rock), Y = 2.
ROM4:8A03 get_bouncy_object_type:
ROM4:8A03 LDA object_type,X
ROM4:8A04 SEC
ROM4:8A05 SBC #ObjectType_BlueTektite
ROM4:8A06 TAY
ROM4:8A07 CPY #2
ROM4:8A08 BCC locret_10A10
ROM4:8A09 LDY #2
 
ROM4:8A10 locret_10A10:
ROM4:8A10 RTS
 
Subroutine set_falling_rock_moving_down
; If this is a FallingRock, set its vertical direction to down. This does nothing for Tektites.
ROM4:8A11 set_falling_rock_moving_down:
ROM4:8A11 LDA object_type,X
ROM4:8A12 CMP #ObjectType_FallingRock ; Falling rocks only
ROM4:8A13 BNE ret
ROM4:8A14 LDA object_direction,X
ROM4:8A15 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:8A16 ORA #ControllerBits_Dpad_Down
ROM4:8A17 STA object_direction,X
 
ROM4:8A18 ret:
ROM4:8A18 RTS
 
Subroutine tektite_update_position
ROM4:8A21 tektite_update_position:
ROM4:8A21 STA var_0
ROM4:8A22 STY var_2
ROM4:8A23 LDA enemy_state_0,X
ROM4:8A24 ADC object_y,X
ROM4:8A25 STA object_y,X
ROM4:8A26 LDA enemy_projectile_speed_x,X
ROM4:8A27 CLC
ROM4:8A28 ADC var_0
ROM4:8A29 STA enemy_projectile_speed_x,X
ROM4:8A2A LDA enemy_state_0,X
ROM4:8A2B ADC #0
ROM4:8A2C STA enemy_state_0,X
ROM4:8A2D CMP var_2
ROM4:8A2E BMI locret_10A52
ROM4:8A2F LDA enemy_projectile_speed_x,X
ROM4:8A30 CMP #$80
ROM4:8A31 BCC locret_10A52
ROM4:8A32 LDA var_2
ROM4:8A33 STA enemy_state_0,X
 
Subroutine tektite_set_zero_speed
ROM4:8A4D tektite_set_zero_speed:
ROM4:8A4D LDA #0
ROM4:8A4E STA enemy_projectile_speed_x,X
 
ROM4:8A52 locret_10A52:
ROM4:8A52 RTS
 
ROM4:8A53 byte_10A53: .BYTE 8
ROM4:8A54   .BYTE $A
ROM4:8A55   .BYTE $10
ROM4:8A56   .BYTE $20
ROM4:8A57   .BYTE $10
ROM4:8A58   .BYTE $A
ROM4:8A59 zola_leever_spawn_timers: .BYTE $80
ROM4:8A5A   .BYTE $20
ROM4:8A5B   .BYTE $F
ROM4:8A5C   .BYTE $FF
ROM4:8A5D   .BYTE $10
ROM4:8A5E   .BYTE $60
ROM4:8A5F byte_10A5F: .BYTE $10
ROM4:8A60   .BYTE $B
ROM4:8A61   .BYTE 1
ROM4:8A62   .BYTE 5
ROM4:8A63   .BYTE 1
ROM4:8A64   .BYTE $B
 
Subroutine update_monster_leever_blue
ROM4:8A65 update_monster_leever_blue:
ROM4:8A65 LDA #$A0 ; Leever walking speed
ROM4:8A66 STA enemy_projectile_speed_x,X
ROM4:8A67 JSR update_movement_or_fire_projectile_if_zero_timer
 
ROM4:8A6D update_leever_from_zola:
ROM4:8A6D LDA enemy_action_timers,X
ROM4:8A6E BNE timer_not_expired ; Skip ahead if the surfacing timer hasn't expired yet
ROM4:8A6F LDA object_type,X
ROM4:8A70 CMP #ObjectType_Zola
ROM4:8A71 BNE loc_10A88
ROM4:8A72 LDY walk_state_and_weapon_state,X ; Zola only
ROM4:8A73 DEY
ROM4:8A74 BNE loc_10A88
ROM4:8A75 LDY #3 ; Y = 3 if Zola is above Link on screen
ROM4:8A76 LDA object_y,X
ROM4:8A77 CMP object_y
ROM4:8A78 BCS above_link ; If Zola Y < Link Y
ROM4:8A79 DEY ; Y = 2 if Zola is below Link on screen
 
ROM4:8A7A above_link:
ROM4:8A7A STY object_direction,X
 
ROM4:8A88 loc_10A88: ; state = (state + 1) % 6
ROM4:8A88 LDA walk_state_and_weapon_state,X
ROM4:8A89 CLC
ROM4:8A8A ADC #1
ROM4:8A8B CMP #6
ROM4:8A8C BCC no_state_loop
ROM4:8A8D LDA #0
 
ROM4:8A8E no_state_loop:
ROM4:8A8E STA walk_state_and_weapon_state,X
ROM4:8A8F TAY
ROM4:8A90 LDA byte_10A53,Y
ROM4:8A91 STA object_walk_speed,X
ROM4:8A92 LDA zola_leever_spawn_timers,Y
ROM4:8A93 STA enemy_action_timers,X
 
ROM4:8A94 timer_not_expired:
ROM4:8A94 LDY walk_state_and_weapon_state,X
ROM4:8A95 LDA byte_10A5F,Y
 
ROM4:8AA6 loc_10AA6:
ROM4:8AA6 JSR update_object_animation_frame
ROM4:8AA7 LDA walk_state_and_weapon_state,X
ROM4:8AA8 BEQ locret_10AF6
ROM4:8AA9 LDY object_type,X
ROM4:8AAA CPY #ObjectType_Zola
ROM4:8AAB BNE not_zola
ROM4:8AAC LDY walk_state_and_weapon_state,X
ROM4:8AAD CPY #2
ROM4:8AAE BCC not_zola
ROM4:8AAF CPY #5
ROM4:8AB0 BCS not_zola
ROM4:8AB1 LDA object_direction,X
ROM4:8AB2 BNE loc_10ACA
 
ROM4:8AB3 not_zola:
ROM4:8AB3 SEC
ROM4:8AB4 SBC #1
ROM4:8AB5 ASL A
ROM4:8AB6 CLC
ROM4:8AB7 ADC object_animation_frame,X
 
ROM4:8ACA loc_10ACA:
ROM4:8ACA JSR update_object_sprite_vertical
ROM4:8ACB LDA object_type,X
ROM4:8ACC CMP #$11
ROM4:8ACD BNE loc_10ADE
ROM4:8ACE LDA walk_state_and_weapon_state,X
ROM4:8ACF CMP #2
ROM4:8AD0 BEQ loc_10AE4
ROM4:8AD1 CMP #4
ROM4:8AD2 BEQ loc_10AE4
 
ROM4:8ADE loc_10ADE:
ROM4:8ADE LDA walk_state_and_weapon_state,X
ROM4:8ADF CMP #3
ROM4:8AE0 BNE locret_10AF6
 
ROM4:8AE4 loc_10AE4: ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:8AE4 JSR check_enemy_hits
ROM4:8AE5 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:8AE6 BEQ locret_10AF6
ROM4:8AE7 LDA object_type,X
ROM4:8AE8 CMP #ObjectType_RedLeever
ROM4:8AE9 BNE locret_10AF6
ROM4:8AEA DEC number_of_spawned_red_leevers_or_gleeok_fast_step_counter ; We're despawning a red leever.
 
ROM4:8AF6 locret_10AF6:
ROM4:8AF6 RTS
 
ROM4:8AF7 byte_10AF7: .BYTE 0
ROM4:8AF8   .BYTE 0
ROM4:8AF9   .BYTE 0
ROM4:8AFA   .BYTE $20
ROM4:8AFB   .BYTE 0
ROM4:8AFC   .BYTE 0
ROM4:8AFD leever_action_timers: .BYTE 0
ROM4:8AFE   .BYTE $10
ROM4:8AFF   .BYTE 8
ROM4:8B00   .BYTE $FF
ROM4:8B01   .BYTE 8
ROM4:8B02   .BYTE $10
ROM4:8B03 leever_animation_frames: .BYTE $10
ROM4:8B04   .BYTE 8
ROM4:8B05   .BYTE 8
ROM4:8B06   .BYTE 5
ROM4:8B07   .BYTE 8
ROM4:8B08   .BYTE 8
 
Subroutine update_monster_leever_red
ROM4:8B09 update_monster_leever_red:
ROM4:8B09 LDA walk_state_and_weapon_state,X
ROM4:8B0A BEQ loc_10B10
ROM4:8B0B JMP leever_is_active
 
ROM4:8B10 loc_10B10: ; Stop if it's not time to spawn another red leever yet.
ROM4:8B10 LDA leever_timer
ROM4:8B11 BNE locret_10B4D
ROM4:8B12 LDA number_of_spawned_red_leevers_or_gleeok_fast_step_counter
ROM4:8B13 CMP #2
ROM4:8B14 BCS locret_10B4D ; Don't spawn more than two red leevers at once.
ROM4:8B15 LDA object_direction
ROM4:8B16 STA object_direction,X ; If PRNG < 0xC0, spawn red leevers moving in the same direction as Link.
ROM4:8B17 LDA prng_1,X
ROM4:8B18 CMP #$C0
ROM4:8B19 BCC loc_10B28
ROM4:8B1A JSR reverse_direction_2 ; If PRNG >= 0xC0, spawn red leevers moving in the opposite direction as Link.
 
ROM4:8B28 loc_10B28:
ROM4:8B28 LDA object_direction,X
ROM4:8B29 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM4:8B2A BEQ horizontal
ROM4:8B2B LDA object_x
ROM4:8B2C STA object_x,X
ROM4:8B2D LDY #$28
ROM4:8B2E LDA object_direction,X
ROM4:8B2F AND #ControllerBits_Dpad_Up
ROM4:8B30 BEQ down
ROM4:8B31 LDY #$D8
 
ROM4:8B32 down:
ROM4:8B32 STY var_0
ROM4:8B33 LDA object_y
ROM4:8B34 CLC
ROM4:8B35 ADC var_0
ROM4:8B36 AND #$F0
ROM4:8B37 ORA #$D
ROM4:8B38 STA object_y,X
ROM4:8B39 CMP #$5D
ROM4:8B3A BCS loc_10B84
 
ROM4:8B4D locret_10B4D:
ROM4:8B4D RTS
 
ROM4:8B4E horizontal:
ROM4:8B4E LDA object_y
ROM4:8B4F STA object_y,X
ROM4:8B50 CMP #$5D
ROM4:8B51 BCC locret_10B4D
ROM4:8B52 LDY #$28
ROM4:8B53 LDA object_direction,X
ROM4:8B54 AND #ControllerBits_Dpad_Left
ROM4:8B55 BEQ right
ROM4:8B56 LDY #$D8
 
ROM4:8B57 right:
ROM4:8B57 STY var_0
ROM4:8B58 LDA object_x
ROM4:8B59 STA var_1
ROM4:8B5A CLC
ROM4:8B5B ADC var_0
ROM4:8B5C AND #$F8
ROM4:8B5D STA object_x,X
ROM4:8B5E STA var_2
ROM4:8B5F CMP var_1
ROM4:8B60 BCC loc_10B7B
ROM4:8B61 PHA
ROM4:8B62 LDA var_1
ROM4:8B63 STA var_2
ROM4:8B64 PLA
ROM4:8B65 STA var_1
 
ROM4:8B7B loc_10B7B:
ROM4:8B7B LDA var_1
ROM4:8B7C SEC
ROM4:8B7D SBC var_2
ROM4:8B7E CMP #$30
ROM4:8B7F BCS locret_10B4D
 
ROM4:8B84 loc_10B84: ; Set tile_walking_onto for the current object.
ROM4:8B84 JSR set_tile_walking_onto_1
ROM4:8B85 CMP screen_first_solid_tile_id
ROM4:8B86 BCS locret_10B4D
ROM4:8B87 INC number_of_spawned_red_leevers_or_gleeok_fast_step_counter ; We're spawning a red leever.
ROM4:8B88 LDA #1
ROM4:8B89 STA object_animation_frame_timer,X ; Set to 1
ROM4:8B8A ASL A
ROM4:8B8B STA leever_timer
ROM4:8B8C JSR loc_10BDA
ROM4:8B8D JSR reverse_direction_2 ; Flip the current object's object_direction in the opposite
  ; direction. This seems to be the same as reverse_direction 1,
  ; except it starts with object_direction instead of var_15
  ; and also stores the result in var_15.
 
ROM4:8B8E leever_is_active:
ROM4:8B8E LDA walk_state_and_weapon_state,X
ROM4:8B8F CMP #3 ; Leever state 3: active and walking around
ROM4:8B90 BNE loc_10BD6
ROM4:8B91 LDA object_knockback,X ; The leever is moving around.
ROM4:8B92 BEQ no_knockback
ROM4:8B93 JSR update_object_knockback
ROM4:8B94 JMP loc_10BF6
 
ROM4:8B95 no_knockback:
ROM4:8B95 LDA clock_active
ROM4:8B96 ORA enemy_stun,X
ROM4:8B97 BNE loc_10BF6
ROM4:8B98 LDA object_direction,X
ROM4:8B99 STA var_15
ROM4:8B9A JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM4:8B9B CMP screen_first_solid_tile_id
ROM4:8B9C BCS loc_10BDA
ROM4:8B9D JSR check_object_against_screen_bounding_box_both ; If the current object is out of the bounding box for the
  ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM4:8B9E BEQ loc_10BDA
ROM4:8B9F JSR process_movement
ROM4:8BA0 LDA object_tile_offset_whole,X
ROM4:8BA1 AND #$F
ROM4:8BA2 BNE loc_10BD2
ROM4:8BA3 STA object_tile_offset_whole,X
 
ROM4:8BD2 loc_10BD2:
ROM4:8BD2 LDA #$FF
ROM4:8BD3 STA enemy_action_timers,X
 
ROM4:8BD6 loc_10BD6:
ROM4:8BD6 LDA enemy_action_timers,X
ROM4:8BD7 BNE loc_10BF6
 
ROM4:8BDA loc_10BDA:
ROM4:8BDA LDA walk_state_and_weapon_state,X
ROM4:8BDB CLC
ROM4:8BDC ADC #1
ROM4:8BDD CMP #6
ROM4:8BDE BCC loc_10BE8
ROM4:8BDF DEC number_of_spawned_red_leevers_or_gleeok_fast_step_counter
ROM4:8BE0 LDA #0
 
ROM4:8BE8 loc_10BE8:
ROM4:8BE8 STA walk_state_and_weapon_state,X
ROM4:8BE9 TAY
ROM4:8BEA LDA byte_10AF7,Y
ROM4:8BEB STA object_walk_speed,X
ROM4:8BEC LDA leever_action_timers,Y
ROM4:8BED STA enemy_action_timers,X
 
ROM4:8BF6 loc_10BF6:
ROM4:8BF6 LDY walk_state_and_weapon_state,X
ROM4:8BF7 LDA leever_animation_frames,Y
ROM4:8BF8 JMP loc_10AA6
 
ROM4:8BF9   .BYTE $60
 
Subroutine update_monster_octorok
ROM4:8BFF update_monster_octorok:
ROM4:8BFF LDA #$A0 ; Red Octorok projectile speed
ROM4:8C00 LDY object_type,X ; Check if ObjectType_BlueOctorok
ROM4:8C01 CPY #ObjectType_BlueOctorok
ROM4:8C02 BCS set_octorok_projectile_speed ; Set Octorok projectile speed
ROM4:8C03 LDA #$70 ; Blue Octorok projectile speed
 
ROM4:8C04 set_octorok_projectile_speed: ; Set Octorok projectile speed
ROM4:8C04 STA enemy_projectile_speed_x,X
ROM4:8C05 JSR update_movement_or_fire_projectile_if_zero_timer
ROM4:8C06 LDA #$20
ROM4:8C07 LDY object_type,X ; Check if this is the non-fast version of Octorok
ROM4:8C08 CPY #ObjectType_RedOctorok
ROM4:8C09 BEQ set_octorok_speed
ROM4:8C0A CPY #ObjectType_BlueOctorok
ROM4:8C0B BEQ set_octorok_speed
ROM4:8C0C ASL A ; Double A for "fast" enemy versions
 
ROM4:8C0D set_octorok_speed: ; Set the projectile type for the below call.
ROM4:8C0D LDY #ObjectType_Octorok_Projectile
ROM4:8C0E JSR jump_from_update_monster_octorok ; Check if we should fire a projectile
ROM4:8C0F JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8C10 LDA object_direction,X ; Load the direction this enemy is currently moving.
ROM4:8C11 TAY ; Y = object_direction[X]
ROM4:8C12 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM4:8C13 BEQ horizontal
ROM4:8C14 LDA #2 ; Up: frame 2
ROM4:8C15 CPY #ControllerBits_Dpad_Up
ROM4:8C16 BNE down ; Push A
ROM4:8C17 LDA #1 ; Down: frame 1
ROM4:8C18 BNE down ; Push A
 
ROM4:8C19 horizontal:
ROM4:8C19 CPY #ControllerBits_Dpad_Right
ROM4:8C1A BNE left
ROM4:8C1B INC var_15 ; Only increment for left. This probably flips the frame
  ; horizontally to face left instead of right.
 
ROM4:8C1C left: ; Left or right: frame 0
ROM4:8C1C LDA #0
 
ROM4:8C1D down: ; Push A
ROM4:8C1D PHA
ROM4:8C1E DEC object_animation_frame_timer,X ; Decrement to the next frame
ROM4:8C1F BNE frame_timer_not_zero ; Don't toggle the animation frame if the timer hasn't elapsed.
ROM4:8C20 LDA #6
ROM4:8C21 STA object_animation_frame_timer,X ; Set to 6. Octoroks change animation frame every 6 frames.
ROM4:8C22 LSR A ; A = 3
ROM4:8C23 EOR object_animation_frame,X ; frame ^= 0x3
ROM4:8C24 STA object_animation_frame,X ; frame ^= 0x3
 
ROM4:8C25 frame_timer_not_zero: ; Pop A, restoring the frame number.
ROM4:8C25 PLA
ROM4:8C26 CLC
ROM4:8C27 ADC object_animation_frame,X
ROM4:8C28 PHA ; Push A
ROM4:8C29 LDA object_direction,X
ROM4:8C2A AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM4:8C2B BNE vertical
ROM4:8C2C PLA ; Pop A
ROM4:8C2D JSR update_object_sprite_horizontal
ROM4:8C2E JMP check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
 
ROM4:8C2F vertical:
ROM4:8C2F PLA
 
ROM4:8C65 update_sprite_and_check_hits_for_tektite:
ROM4:8C65 JSR update_object_sprite_vertical
ROM4:8C66 JMP check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
 
Subroutine update_monster_ghini
ROM4:8C6B update_monster_ghini:
ROM4:8C6B LDA #$FF
ROM4:8C6C JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:8C6D JSR update_monster_ghini_1
ROM4:8C6E JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:8C6F LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:8C70 BEQ locret_10C8C
ROM4:8C71 LDY #$B ; For each object ID
 
ROM4:8C72 loop:
ROM4:8C72 LDA object_type,Y
ROM4:8C73 CMP #ObjectType_GhiniFromTombs ; Created by handle_spawning_armos_ghini_on_touch
ROM4:8C74 BNE skip
ROM4:8C75 LDA #$11
ROM4:8C76 STA enemy_spawn_state,Y ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
 
ROM4:8C77 skip:
ROM4:8C77 DEY
ROM4:8C78 BNE loop
 
ROM4:8C8C locret_10C8C:
ROM4:8C8C RTS
 
Subroutine update_monster_ghini_1
ROM4:8C8D update_monster_ghini_1:
ROM4:8C8D JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8C8E STA var_13 ; Set to 0
ROM4:8C8F LDA object_direction,X
ROM4:8C90 AND #ControllerBits_Dpad_Up
ROM4:8C91 BNE up
ROM4:8C92 INC var_13 ; Set to 1
ROM4:8C93 LDA object_direction,X
ROM4:8C94 AND #ControllerBits_Dpad_Right
ROM4:8C95 BEQ done_selecting_sprite
ROM4:8C96 BNE right
 
ROM4:8C97 up:
ROM4:8C97 LDA object_direction,X
ROM4:8C98 AND #ControllerBits_Dpad_Left
ROM4:8C99 BEQ done_selecting_sprite
 
ROM4:8C9A right: ; Flip the sprite horizontally when facing right
ROM4:8C9A INC var_15
 
ROM4:8C9B done_selecting_sprite:
ROM4:8C9B LDA var_13
 
ROM4:8CAC loc_10CAC:
ROM4:8CAC JSR update_object_sprite_horizontal
ROM4:8CAD JMP check_link_hit_by_enemy ; Check if Link was hit by an enemy. X is the enemy we're
  ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
 
ROM4:8CB2 armos_map_locations: .BYTE $24
ROM4:8CB3   .BYTE $B ; Level 5
ROM4:8CB4   .BYTE $1C
ROM4:8CB5   .BYTE $22
ROM4:8CB6   .BYTE $34
ROM4:8CB7   .BYTE $3D
ROM4:8CB8   .BYTE $4E
ROM4:8CB9 armos_x_positions: .BYTE $E0 ; Top-right statue (power bracelet)
ROM4:8CBA   .BYTE $B0 ; Top-right statue at level 5
ROM4:8CBB   .BYTE $B0 ; Top, second from right statue: "Secret is in the tree at the dead end"
ROM4:8CBC   .BYTE $30 ; Left statue, level 6
ROM4:8CBD   .BYTE $40 ; Blue ring shop, center statue
ROM4:8CBE   .BYTE $90 ; Forest 30 secret, right statue
ROM4:8CBF   .BYTE $A0 ; Forest 10 secret, right statue
 
Subroutine spawn_armos_or_ghini
ROM4:8CC0 spawn_armos_or_ghini:
ROM4:8CC0 LDA enemy_action_timers,X
ROM4:8CC1 STA object_slot_in_use,X
ROM4:8CC2 BNE loc_10D2B
ROM4:8CC3 LDA object_type,X ; check if ObjectType_GhiniFromTombs
ROM4:8CC4 CMP #ObjectType_GhiniFromTombs ; Created by handle_spawning_armos_ghini_on_touch
ROM4:8CC5 BEQ loc_10D2B
ROM4:8CC6 LDA #$70
ROM4:8CC7 STA var_0
ROM4:8CC8 LDY #6
 
ROM4:8CC9 loop: ; Check the map location and statue against each of the
ROM4:8CC9 LDA map_location ; six table entries.
ROM4:8CCA CMP armos_map_locations,Y
ROM4:8CCB BNE check_next
ROM4:8CCC LDA object_x,X
ROM4:8CCD CMP armos_x_positions,Y
ROM4:8CCE BNE check_next
ROM4:8CCF LDA object_y,X
ROM4:8CD0 CMP #$80 ; All Armos statues with secrets are at the same Y position
ROM4:8CD1 BNE check_next
ROM4:8CD2 CPY #0 ; This table entry matches.
 
  ; Entry 0 in the table is the power bracelet.
ROM4:8CD3 BNE not_power_bracelet
ROM4:8CD4 STA floor_item_y ; Set to object_y[X]
ROM4:8CD5 LDA object_x,X
ROM4:8CD6 STA floor_item_x ; Set to object_x[X]
ROM4:8CD7 STY current_room_floor_item_hidden ; Set to object_x[X] when spawning the power bracelet Armos item.
ROM4:8CD8 LDA #FloorItem_PowerBracelet
ROM4:8CD9 STA current_floor_item ; set to FloorItem_PowerBracelet
ROM4:8CDA JSR get_room_status_floor_item_picked_up
ROM4:8CDB BNE loc_10D05
ROM4:8CDC JSR play_secret_sound
ROM4:8CDD BNE loc_10D05
 
ROM4:8CDE check_next:
ROM4:8CDE DEY
ROM4:8CDF BPL loop
 
ROM4:8D05 loc_10D05:
ROM4:8D05 LDA #$26
ROM4:8D06 STA var_0 ; Set to 0x26 (was 0x70)
 
ROM4:8D07 not_power_bracelet:
ROM4:8D07 LDA var_0
ROM4:8D08 PHA
ROM4:8D09 CMP #$70
ROM4:8D0A BNE loc_10D13 ; If this isn't 0x70, then it's 0x26 from the PB path.
ROM4:8D0B JSR play_secret_sound
 
ROM4:8D13 loc_10D13:
ROM4:8D13 INC ppu_unknown_task_returns_to_ROM4
ROM4:8D14 PLA
ROM4:8D15 JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
ROM4:8D16 LDA #3
ROM4:8D17 STA object_tile_offset_whole,X
ROM4:8D18 LDA #$20 ; Ghini walk speed (slow)
ROM4:8D19 LDY prng_1,X ; 50% chance of fast Ghini
ROM4:8D1A CPY #$80
ROM4:8D1B BCC not_fast_ghini
ROM4:8D1C LDA #$60 ; Ghini walk speed (fast)
 
ROM4:8D1D not_fast_ghini:
ROM4:8D1D STA object_walk_speed,X
 
ROM4:8D2B loc_10D2B:
ROM4:8D2B LDA #ControllerBits_Dpad_Down
ROM4:8D2C STA walking_directions,X ; Ghini always spawns moving down
ROM4:8D2D STA object_direction,X ; Ghini always spawns facing down
ROM4:8D2E LDA enemy_action_timers,X
ROM4:8D2F LSR A ; A = 2
ROM4:8D30 BCS ret
ROM4:8D31 LDA object_type,X ; check if ObjectType_GhiniFromTombs
ROM4:8D32 CMP #ObjectType_GhiniFromTombs ; Created by handle_spawning_armos_ghini_on_touch
ROM4:8D33 BEQ is_ghini_from_tombs
ROM4:8D34 JSR armos_ghini_update_sprite_and_check_hits
 
ROM4:8D35 ret:
ROM4:8D35 RTS
 
ROM4:8D36 is_ghini_from_tombs:
ROM4:8D36 JSR update_monster_ghini_1
ROM4:8D37 LDA object_slot_in_use,X
ROM4:8D38 BNE ret
ROM4:8D39 JSR spawn_monster_no_timer_no_spawn_cloud
ROM4:8D3A JMP from_spawn_ghini_from_tombs
 
Subroutine update_monster_armos
ROM4:8D50 update_monster_armos:
ROM4:8D50 JSR update_monster_goriya
ROM4:8D51 LDA object_knockback,X
ROM4:8D52 BNE armos_ghini_update_sprite_and_check_hits
ROM4:8D53 DEC object_animation_frame_timer,X
ROM4:8D54 BNE armos_ghini_update_sprite_and_check_hits
ROM4:8D55 LDA #6
ROM4:8D56 STA object_animation_frame_timer,X ; Set to 6
ROM4:8D57 LDA object_animation_frame,X
ROM4:8D58 EOR #2
ROM4:8D59 STA object_animation_frame,X
 
ROM4:8D69 armos_ghini_update_sprite_and_check_hits: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8D69 JSR set_var_0_to_object_position
ROM4:8D6A LDY object_direction,X
ROM4:8D6B CPY #ControllerBits_Dpad_Up
ROM4:8D6C BNE facing_up
ROM4:8D6D LDA #1 ; A = 1, so we add 1 below. If we don't take this path, A = 0
  ; and the ADC below won't do anything.
 
ROM4:8D6E facing_up:
ROM4:8D6E CLC
ROM4:8D6F ADC object_animation_frame,X ; Add 0 or 1 to select an Armos or Ghini frame.
ROM4:8D70 JSR update_object_sprite_horizontal
ROM4:8D71 LDA enemy_action_timers,X ; Check if this enemy is still spawning. During the initial
  ; spawn out of a statue/tomb, Link can be hit by the enemy but
  ; the enemy can't be hit by Link.
ROM4:8D72 BNE initial_spawn
ROM4:8D73 JSR check_enemy_hits ; The enemy is fully spawned, so check hits normally.
ROM4:8D74 LDA enemy_spawn_state,X ; Check if the enemy died.
ROM4:8D75 BEQ ret
ROM4:8D76 LDA #ObjectType_EnemyDeath
ROM4:8D77 STA object_type,X ; Set to ObjectType_EnemyDeath
 
ROM4:8D78 ret:
ROM4:8D78 RTS
 
ROM4:8D79 initial_spawn: ; Check if Link was hit by an enemy. X is the enemy we're
ROM4:8D79 JMP check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
 
Subroutine update_monster_fairy
ROM4:8D90 update_monster_fairy:
ROM4:8D90 JSR update_monster_fairy_animation
ROM4:8D91 LDA global_room_state ; Skip if already begun
ROM4:8D92 BNE fairy_triggered_1
ROM4:8D93 LDA object_y
ROM4:8D94 CMP #173 ; Check if Link is standing at the bottom of the fairy lake.
ROM4:8D95 BNE ret ; y != 173
ROM4:8D96 LDA object_x
ROM4:8D97 CMP #112
ROM4:8D98 BCC ret ; x < 112
ROM4:8D99 CMP #129
ROM4:8D9A BCS ret ; x > 129
ROM4:8D9B INC global_room_state ; Increase the room state.
ROM4:8D9C LDA #WalkState_3_MovementLocked
ROM4:8D9D STA walk_state_and_weapon_state ; Lock movement during the fairy refill.
ROM4:8D9E STA health_refill ; Set to 0x40
 
ROM4:8D9F ret:
ROM4:8D9F RTS
 
ROM4:8DA0 fairy_triggered_1:
ROM4:8DA0 CMP #1
ROM4:8DA1 BNE fairy_triggered_2
ROM4:8DA2 LDA health_refill ; global_room_state == 1. Wait for health_refill to be set back to 0,
  ; which happens when life refill has finished.
ROM4:8DA3 BNE update_link_sprite_during_refill
ROM4:8DA4 INC global_room_state ; health_refill is back to 0, so health refill is finished.
  ; Increase the room state to 2.
ROM4:8DA5 LDA #$50
ROM4:8DA6 STA npc_action_timer_1 ; Fairy animation for 0x50 frames
 
ROM4:8DA7 fairy_triggered_2:
ROM4:8DA7 CMP #2
ROM4:8DA8 BNE return ; If the room state is 3, we're finished.
ROM4:8DA9 LDA npc_action_timer_1 ; The room state is 2. Check if the fairy animation is finished.
ROM4:8DAA BNE update_link_sprite_during_refill ; Wait for our timer to be 0
ROM4:8DAB INC global_room_state ; Bump to fairy state 3 (done)
ROM4:8DAC LDA #0
ROM4:8DAD STA walk_state_and_weapon_state ; Unlock movement after fairy
 
ROM4:8DAE update_link_sprite_during_refill:
ROM4:8DAE LDY #0
ROM4:8DAF STY walking_directions ; Set to 0.
ROM4:8DB0 LDA walk_state_and_weapon_state ; 0x40 = lock movement (what else?)
ROM4:8DB1 PHA ; Push walk state
ROM4:8DB2 STY walk_state_and_weapon_state ; Temporarily set Link's sprite to walk state 0.
ROM4:8DB3 JSR update_link_sprite_and_check_ladder_in_bank_4 ; Call update_link_sprite_and_check_ladder, then set bank 4 before returning.
ROM4:8DB4 PLA ; Restore walk state
ROM4:8DB5 STA walk_state_and_weapon_state
ROM4:8DB6 JSR update_fairy_lake_spinning_hearts ; Update the hearts spinning around the lake fairy.
ROM4:8DB7 LDX processing_object_index
 
ROM4:8DB8 return:
ROM4:8DB8 RTS
 
ROM4:8DE3 spawn_heart_at_first_heart_offsets: .BYTE $14 ; When the first heart (object 2) has a tile offset equal
  ; to table[X], heart X+3 is spawned.
ROM4:8DE4   .BYTE $10
ROM4:8DE5   .BYTE $C
ROM4:8DE6   .BYTE 8
ROM4:8DE7   .BYTE 4
ROM4:8DE8   .BYTE 0
ROM4:8DE9   .BYTE $1C
 
Subroutine update_fairy_lake_spinning_hearts
; Update the hearts spinning around the lake fairy.
ROM4:8DEA update_fairy_lake_spinning_hearts:
ROM4:8DEA LDX #2 ; Loop from X = 2 to 9.
 
ROM4:8DEB loop: ; Check if this heart has been spawned yet.
ROM4:8DEB LDA walk_state_and_weapon_state,X
ROM4:8DEC BNE heart_already_spawned
ROM4:8DED CPX #2
ROM4:8DEE BEQ is_object_2 ; Branch if this is the first heart
ROM4:8DEF LDA enemy_state_10_2 ; walk_state_or_enemy_state_10[2]
ROM4:8DF0 BEQ loop
ROM4:8DF1 TXA ; A = X (heart object ID, 3+)
ROM4:8DF2 SEC
ROM4:8DF3 SBC #3
ROM4:8DF4 TAY ; Y = A: 0-based heart index
ROM4:8DF5 LDA object_tile_offset_whole_2 ; Check if the first heart (X = 2) is at the position that
  ; signals this heart should be set up.
ROM4:8DF6 CMP spawn_heart_at_first_heart_offsets,Y
ROM4:8DF7 BNE ret
 
ROM4:8DF8 is_object_2: ; Mark this heart spawned
ROM4:8DF8 INC walk_state_and_weapon_state,X
ROM4:8DF9 LDA #$80 ; I'm not sure what this flag does.
ROM4:8DFA STA object_direction,X
ROM4:8DFB LDA #$18
ROM4:8DFC STA object_tile_offset_whole,X
ROM4:8DFD LDA object_x_1 ; Copy the Fairy X position to the new heart's X position
ROM4:8DFE STA object_x,X
ROM4:8DFF LDA object_y_1 ; Copy the Fairy Y position - 28 to the new heart's Y position
ROM4:8E00 SEC
ROM4:8E01 SBC #28
ROM4:8E02 STA object_y,X
 
ROM4:8E03 heart_already_spawned:
ROM4:8E03 LDA #0
ROM4:8E04 STA var_11 ; Set to 0 (no object_tile_offset_whole offset in update_spinning_hearts_patra_1)
ROM4:8E05 LDA #$60
ROM4:8E06 JSR update_spinning_hearts_patra_1 ; byte_380[X] -= 0x60
ROM4:8E07 LDA #6
ROM4:8E08 TAY
ROM4:8E09 JSR update_spinning_hearts_patra_2
ROM4:8E0A STA object_y,X
ROM4:8E0B TXA
ROM4:8E0C PHA
ROM4:8E0D JSR store_palette_2_in_tile_attributes ; Store 0x2 in var_4 and var_5, and set A to 2.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:8E0E JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8E0F LDX processing_object_index
ROM4:8E10 JSR update_object_sprite_horizontal
ROM4:8E11 PLA
ROM4:8E12 TAX
 
ROM4:8E13 ret:
ROM4:8E13 INX
ROM4:8E14 CPX #10
ROM4:8E15 BNE loop
ROM4:8E16 RTS
 
ROM4:8E42 byte_10E42: .BYTE 8
ROM4:8E43   .BYTE 4
 
Subroutine update_monster_overworld_secret_push_block
ROM4:8E44 update_monster_overworld_secret_push_block:
ROM4:8E44 LDA walk_state_and_weapon_state,X
ROM4:8E45 BNE loc_10E92
ROM4:8E46 LDA object_type,X
ROM4:8E47 CMP #ObjectType_OverworldSecret_Push_Tomb ; An overworld push block (tomb sprite).
ROM4:8E48 BEQ loc_10E54 ; Check if ObjectType_Armos_Secret_2
ROM4:8E49 LDA have_power_bracelet
ROM4:8E4A BEQ locret_10E91
 
ROM4:8E54 loc_10E54: ; Check if the secret on this overworld screen exists on the
ROM4:8E54 JSR check_if_overworld_secret_should_exist ; current quest. Clear carry if the secret exists, set it
  ; if it doesn't.
ROM4:8E55 BCS locret_10E91 ; This secret handler is inactive if it doesn't exist on this quest.
ROM4:8E56 LDA object_x
ROM4:8E57 CMP object_x,X
ROM4:8E58 BNE locret_10E91
ROM4:8E59 LDY #0
ROM4:8E5A LDA object_y
ROM4:8E5B CLC
ROM4:8E5C ADC #3
ROM4:8E5D SEC
ROM4:8E5E SBC object_y,X
ROM4:8E5F BPL loc_10E71
ROM4:8E60 INY
ROM4:8E61 EOR #$FF
ROM4:8E62 CLC
ROM4:8E63 ADC #1
 
ROM4:8E71 loc_10E71:
ROM4:8E71 CMP #$11
ROM4:8E72 BCS locret_10E91
ROM4:8E73 LDA walking_directions
ROM4:8E74 AND #$C
ROM4:8E75 BEQ locret_10E91
ROM4:8E76 CMP byte_10E42,Y
ROM4:8E77 BNE locret_10E91
ROM4:8E78 STA object_direction,X
ROM4:8E79 INC walk_state_and_weapon_state,X
ROM4:8E7A LDA map_location
ROM4:8E7B STA enemy_state_0,X
ROM4:8E7C INC ppu_unknown_task_returns_to_ROM4
ROM4:8E7D LDA #$26
ROM4:8E7E JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
 
ROM4:8E91 locret_10E91:
ROM4:8E91 RTS
 
ROM4:8E92 loc_10E92:
ROM4:8E92 LDA object_direction,X
ROM4:8E93 STA var_15
ROM4:8E94 JSR process_movement
ROM4:8E95 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8E96 DEC var_1
ROM4:8E97 JSR update_object_sprite_horizontal
ROM4:8E98 LDA object_tile_offset_whole,X
ROM4:8E99 CMP #$10
ROM4:8E9A BEQ loc_10EAC
ROM4:8E9B CMP #$F0
ROM4:8E9C BNE locret_10E91
 
ROM4:8EAC loc_10EAC:
ROM4:8EAC LDA map_location
ROM4:8EAD PHA ; save map location
ROM4:8EAE LDA enemy_state_0,X
ROM4:8EAF STA map_location
ROM4:8EB0 JSR mark_map_location_visited
ROM4:8EB1 PLA
ROM4:8EB2 STA map_location ; restore map location
ROM4:8EB3 LDA #$C8
ROM4:8EB4 LDY object_type,X ; check if ObjectType_Unknown_62
ROM4:8EB5 CPY #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM4:8EB6 BEQ loc_10ECB
ROM4:8EB7 LDA #$BC
ROM4:8EB8 CPY #$65
ROM4:8EB9 BEQ loc_10ECB
ROM4:8EBA LDA #$C0
 
ROM4:8ECB loc_10ECB:
ROM4:8ECB INC ppu_unknown_task_returns_to_ROM4
ROM4:8ECC JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
ROM4:8ECD LDA #$70
ROM4:8ECE STA var_0
ROM4:8ECF LDY enemy_state_0,X
ROM4:8ED0 JSR loc_10718C
ROM4:8ED1 STA object_x,X
ROM4:8ED2 STY object_y,X
ROM4:8ED3 LDA var_0
 
Subroutine despawn_secret_block_and_change_background_tile
; Change the background tile at the current object's position, ; despawn the object and play the secret sound.
ROM4:8EE0 despawn_secret_block_and_change_background_tile:
ROM4:8EE0 INC ppu_unknown_task_returns_to_ROM4
ROM4:8EE1 JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
ROM4:8EE2 JSR despawn_object ; Remove the object at ID X.
ROM4:8EE3 JMP play_secret_sound
 
Subroutine update_monster_overworld_secret_bomb
ROM4:8EEB update_monster_overworld_secret_bomb:
ROM4:8EEB JSR check_if_overworld_secret_should_exist ; Check if the secret on this overworld screen exists on the
  ; current quest. Clear carry if the secret exists, set it
  ; if it doesn't.
ROM4:8EEC BCS ret ; This secret handler is inactive if it doesn't exist on this quest.
ROM4:8EED LDY #$10
ROM4:8EEE LDA walk_state_and_weapon_state,Y ; This is checking if a bomb is going off.
ROM4:8EEF CMP #BombOrFireState_BombExploding|BombOrFireState_Type_Bomb
ROM4:8EF0 BEQ bomb_going_off
ROM4:8EF1 INY
ROM4:8EF2 LDA walk_state_and_weapon_state,Y
ROM4:8EF3 CMP #$13
ROM4:8EF4 BNE ret
 
ROM4:8EF5 bomb_going_off:
ROM4:8EF5 STY var_0
ROM4:8EF6 JSR check_overworld_bomb_or_fire_secret_hitbox
ROM4:8EF7 BEQ ret
ROM4:8EF8 LDA #$24
ROM4:8EF9 JSR mark_overworld_secret_opened_and_despawn_secret
 
ROM4:8EFA ret:
ROM4:8EFA RTS
 
Subroutine update_monster_overworld_secret_candle
ROM4:8F0E update_monster_overworld_secret_candle:
ROM4:8F0E JSR check_if_overworld_secret_should_exist ; Check if the secret on this overworld screen exists on the
  ; current quest. Clear carry if the secret exists, set it
  ; if it doesn't.
ROM4:8F0F BCS ret ; This secret handler is inactive if it doesn't exist on this quest.
ROM4:8F10 LDY #$10
ROM4:8F11 LDA walk_state_and_weapon_state,Y ; This is checking for fire.
ROM4:8F12 CMP #BombOrFireState_BombDelay|BombOrFireState_Type_Fire
ROM4:8F13 BEQ fire
ROM4:8F14 INY
ROM4:8F15 LDA walk_state_and_weapon_state,Y
ROM4:8F16 CMP #$22
ROM4:8F17 BNE ret
 
ROM4:8F18 fire:
ROM4:8F18 STY var_0
ROM4:8F19 LDA enemy_action_timers,Y
ROM4:8F1A CMP #2
ROM4:8F1B BCS ret
ROM4:8F1C JSR check_overworld_bomb_or_fire_secret_hitbox
ROM4:8F1D BEQ ret
 
ROM4:8F32 handle_recorder_lake_door:
ROM4:8F32 LDA #$70
 
  ; A = 0x24 from branch
 
ROM4:8F34 mark_overworld_secret_opened_and_despawn_secret: ; Change the background tile at the current object's position,
ROM4:8F34 JSR despawn_secret_block_and_change_background_tile ; despawn the object and play the secret sound.
ROM4:8F35 JSR get_screen_status ; Load to set |= ScreenStatusOverworld_SecretOpened
ROM4:8F36 ORA #ScreenStatusOverworld_SecretOpened
ROM4:8F37 STA (var_0),Y
 
ROM4:8F38 ret:
ROM4:8F38 RTS
 
Subroutine check_overworld_bomb_or_fire_secret_hitbox
ROM4:8F3F check_overworld_bomb_or_fire_secret_hitbox:
ROM4:8F3F LDA object_x,Y
ROM4:8F40 CLC
ROM4:8F41 ADC #8
ROM4:8F42 STA var_4
ROM4:8F43 LDA object_y,Y
ROM4:8F44 CLC
ROM4:8F45 ADC #8
ROM4:8F46 STA var_5
ROM4:8F47 JSR set_position_for_hitbox_check ; Set var_2/var_3 to this object's X/Y position for hit checking.
ROM4:8F48 LDA #16 ; Hitbox size: 16
ROM4:8F49 JMP check_hitbox ; In var_4/var_5: Target's X,Y position
  ; In A: Target's hitbox size
  ; Out A, var_6: 1 if hit
 
ROM4:8F57 secret_quest_numbers: .BYTE 0 ; Quest number this is used on
ROM4:8F58   .BYTE 0
ROM4:8F59   .BYTE 1
 
Subroutine check_if_overworld_secret_should_exist
; Check if the secret on this overworld screen exists on the ; current quest. Clear carry if the secret exists, set it ; if it doesn't.
ROM4:8F5A check_if_overworld_secret_should_exist:
ROM4:8F5A LDA current_screen_data_5 ; Load to check ScreenData_Overworld_5_Secret_FirstQuest and ScreenData_Overworld_5_Secret_SecondQuest
ROM4:8F5B LSR A
ROM4:8F5C LSR A
ROM4:8F5D LSR A
ROM4:8F5E LSR A
ROM4:8F5F LSR A
ROM4:8F60 LSR A
ROM4:8F61 BEQ matching_quest
ROM4:8F62 TAY
ROM4:8F63 LDA secret_quest_numbers,Y
ROM4:8F64 LDY current_save_slot
ROM4:8F65 CMP quest_no,Y
ROM4:8F66 BEQ matching_quest ; Branch if quest number matches the quest this secret is used on
ROM4:8F67 SEC
ROM4:8F68 RTS
 
ROM4:8F69 matching_quest:
ROM4:8F69 CLC
ROM4:8F6A RTS
 
ROM4:8F6B   .BYTE 4
ROM4:8F6C   .BYTE 8
 
Subroutine update_monster_overworld_secret_raft
ROM4:8F76 update_monster_overworld_secret_raft:
ROM4:8F76 LDA have_raft
ROM4:8F77 BEQ locret_10FAF
ROM4:8F78 LDA walk_state_and_weapon_state,X
ROM4:8F79 BNE loc_10FB0
ROM4:8F7A LDA #$80
ROM4:8F7B LDY map_location
ROM4:8F7C CPY #$55
ROM4:8F7D BEQ loc_10F89
ROM4:8F7E LDA #$60
 
ROM4:8F89 loc_10F89:
ROM4:8F89 CMP object_x
ROM4:8F8A BNE locret_10FAF
ROM4:8F8B STA object_x,X
ROM4:8F8C LDY #1
ROM4:8F8D LDA object_y
ROM4:8F8E CMP #$3D
ROM4:8F8F BEQ loc_10F9C
ROM4:8F90 INY
ROM4:8F91 CMP #$7D
ROM4:8F92 BNE locret_10FAF
 
ROM4:8F9C loc_10F9C:
ROM4:8F9C STY walk_state_and_weapon_state,X
ROM4:8F9D CLC
ROM4:8F9E ADC #6
ROM4:8F9F STA object_y,X
ROM4:8FA0 JSR play_secret_sound
ROM4:8FA1 LDA #$40
ROM4:8FA2 STA walk_state_and_weapon_state
ROM4:8FA3 LDA $8F73,Y
ROM4:8FA4 STA object_direction
 
ROM4:8FAF locret_10FAF:
ROM4:8FAF RTS
 
ROM4:8FB0 loc_10FB0:
ROM4:8FB0 LDY walk_state_and_weapon_state,X
ROM4:8FB1 DEY
ROM4:8FB2 BEQ loc_10FC9
ROM4:8FB3 DEC object_y,X
ROM4:8FB4 DEC object_y
ROM4:8FB5 LDA object_y
ROM4:8FB6 CMP #$3D
ROM4:8FB7 BNE loc_10FDE
ROM4:8FB8 TXA
ROM4:8FB9 PHA
ROM4:8FBA JSR start_GameMode_PrepareScroll
ROM4:8FBB PLA
ROM4:8FBC TAX
ROM4:8FBD JMP loc_10FD8
 
ROM4:8FC9 loc_10FC9:
ROM4:8FC9 INC object_y,X
ROM4:8FCA INC object_y
ROM4:8FCB LDA object_y
ROM4:8FCC CMP #$7F
ROM4:8FCD BNE loc_10FDE
ROM4:8FCE LDA #2
ROM4:8FCF STA object_tile_offset_whole
 
ROM4:8FD8 loc_10FD8:
ROM4:8FD8 LDA #0
ROM4:8FD9 STA walk_state_and_weapon_state
ROM4:8FDA STA walk_state_and_weapon_state,X
 
ROM4:8FDE loc_10FDE:
ROM4:8FDE TXA
ROM4:8FDF PHA
ROM4:8FE0 JSR update_link_sprite_and_check_ladder_in_bank_4 ; Call update_link_sprite_and_check_ladder, then set bank 4 before returning.
ROM4:8FE1 PLA
ROM4:8FE2 TAX
ROM4:8FE3 JSR update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
ROM4:8FE4 LDA #0 ; OAM attributes
ROM4:8FE5 LDY #9
ROM4:8FE6 JMP sub_10790C
 
Subroutine update_monster_ghini_from_tombs
; Ghini from tombstones. ; ; These are almost identical to Keese, but they're much more likely to be in state ; 3 than state 4 compared to Keese. This probably makes them more likely to home ; in on Link than to move in circles.
ROM4:8FEF update_monster_ghini_from_tombs:
ROM4:8FEF LDA clock_active
ROM4:8FF0 BNE skip_if_frozen
ROM4:8FF1 JSR call_task_for_monster_state
ROM4:8FF2 JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
 
ROM4:8FF3 skip_if_frozen: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:8FF3 JSR set_var_0_to_object_position
ROM4:8FF4 LDA enemy_state_5,X
ROM4:8FF5 AND #1
ROM4:8FF6 JMP update_monster_ghini_1
 
ROM4:8FF7 call_task_for_monster_state:
ROM4:8FF7 LDA enemy_state_6,X ; This is identical to the state engine for Keese, except
  ; the random chance for each state is different.
ROM4:8FF8 JSR call_jump_table
 
ROM4:8FF9   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:8FFB   .WORD update_monster_ghini_select_random_state_2_3_4 ; Randomly choose whether to go to state 2, 3 or 4.
ROM4:8FFD   .WORD update_monster_diagonal_movement_relative_to_seek ; Update the current enemy's direction relative to the seek
  ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:8FFF   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:9001   .WORD decrease_enemy_speed ; Decrease the object's speed by one each frame. Once
  ; the speed is under 0x20, switch to state 5.
ROM4:9003   .WORD reset_monster_state_after_npc_action_timers
 
Subroutine update_monster_ghini_select_random_state_2_3_4
; Randomly choose whether to go to state 2, 3 or 4.
ROM4:9017 update_monster_ghini_select_random_state_2_3_4:
ROM4:9017 LDY #2
ROM4:9018 LDA prng_0,X
ROM4:9019 CMP #$A0
ROM4:901A BCS do_save_new_monster_state_from_Y ; If random value >= 0xA0, 2
ROM4:901B INY ; Move to state 3
ROM4:901C CMP #8
ROM4:901D BCS do_save_new_monster_state_from_Y ; If random value >= 0x8, 3
ROM4:901E INY ; Move to state 4
 
ROM4:901F do_save_new_monster_state_from_Y:
ROM4:901F JMP save_new_monster_state_from_Y
 
Subroutine update_monster_peahat
ROM4:9028 update_monster_peahat:
ROM4:9028 LDA object_knockback,X
ROM4:9029 BEQ no_knockback
ROM4:902A JSR update_object_knockback
 
ROM4:902B clock_active_or_stunned:
ROM4:902B JMP update_sprite_and_check_hits
 
ROM4:902C no_knockback:
ROM4:902C LDA clock_active
ROM4:902D ORA enemy_stun,X
ROM4:902E BNE clock_active_or_stunned
ROM4:902F JSR call_task_for_monster_state
ROM4:9030 JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
 
ROM4:9031 update_sprite_and_check_hits: ; Update the Peahat sprite, and check for hits.
ROM4:9031 JSR set_var_0_to_object_position
ROM4:9032 LDA enemy_state_5,X
ROM4:9033 AND #1 ; Peahat sprite tile
ROM4:9034 JSR update_object_sprite_vertical
ROM4:9035 LDA enemy_state_6,X ; Peahats can only be hit by Link when in state 5.
ROM4:9036 CMP #5
ROM4:9037 BEQ allow_hitting_peahat
ROM4:9038 JMP check_link_hit_by_enemy ; In other states, only check if Link was hit, not if Link hit the Peahat.
 
ROM4:9039 allow_hitting_peahat: ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9039 JMP check_enemy_hits
 
ROM4:903A call_task_for_monster_state:
ROM4:903A LDA enemy_state_6,X
ROM4:903B JSR call_jump_table
 
ROM4:903C   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:903E   .WORD update_monster_peahat_select_random_state_2_3_4 ; Randomly choose whether to go to state 2, 3 or 4.
ROM4:9040   .WORD update_monster_diagonal_movement_relative_to_seek ; Update the current enemy's direction relative to the seek
  ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:9042   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:9044   .WORD decrease_enemy_speed ; Decrease the object's speed by one each frame. Once
  ; the speed is under 0x20, switch to state 5.
ROM4:9046   .WORD reset_monster_state_after_npc_action_timers ; For Peahats, this is the state where they're stopped and
  ; can be hit by Link.
 
Subroutine update_monster_peahat_select_random_state_2_3_4
; Randomly choose whether to go to state 2, 3 or 4.
ROM4:9069 update_monster_peahat_select_random_state_2_3_4:
ROM4:9069 LDY #2
ROM4:906A LDA prng_0,X
ROM4:906B CMP #$B0
ROM4:906C BCS save_new_monster_state_from_Y ; If random value >= 0xB0, 2
ROM4:906D INY ; Move to state 3
ROM4:906E CMP #$20
ROM4:906F BCS save_new_monster_state_from_Y ; If random value >= 0x20, 3
ROM4:9070 INY ; Move to state 4
 
ROM4:9077 save_new_monster_state_from_Y:
ROM4:9077 TYA
ROM4:9078 STA enemy_state_6,X
ROM4:9079 LDA #6
ROM4:907A STA enemy_state_4,X ; Set to 6
ROM4:907B RTS
 
Subroutine play_secret_sound
ROM4:9081 play_secret_sound:
ROM4:9081 LDA #Sound1_Secret
ROM4:9082 STA play_sound_1 ; Play Sound1_Secret
ROM4:9083 RTS
 
ROM4:9084   .BYTE $FF
ROM4:9085   .BYTE $FF
ROM4:9086   .BYTE $FF
ROM4:9087   .BYTE $FF
ROM4:9088   .BYTE $FF
ROM4:9089   .BYTE $FF
ROM4:908A   .BYTE $FF
ROM4:908B   .BYTE $FF
ROM4:908C   .BYTE $FF
ROM4:908D   .BYTE $FF
ROM4:908E   .BYTE $FF
ROM4:908F   .BYTE $FF
ROM4:9090   .BYTE $FF
ROM4:9091   .BYTE $FF
ROM4:9092   .BYTE $FF
ROM4:9093   .BYTE $FF
ROM4:9094   .BYTE $FF
ROM4:9095   .BYTE $FF
ROM4:9096   .BYTE $FF
ROM4:9097   .BYTE $FF
ROM4:9098   .BYTE $FF
ROM4:9099   .BYTE $FF
ROM4:909A   .BYTE $FF
ROM4:909B   .BYTE $FF
ROM4:909C   .BYTE $FF
ROM4:90A0 wall_master_directions: .BYTE 1
ROM4:90A1   .BYTE 1
ROM4:90A2   .BYTE 8
ROM4:90A3   .BYTE 8
ROM4:90A4   .BYTE 8
ROM4:90A5   .BYTE 2
ROM4:90A6   .BYTE 2
ROM4:90A7   .BYTE 2
ROM4:90A8   .BYTE $C1
ROM4:90A9   .BYTE $C1
ROM4:90AA   .BYTE $C4
ROM4:90AB   .BYTE $C4
ROM4:90AC   .BYTE $C4
ROM4:90AD   .BYTE $C2
ROM4:90AE   .BYTE $C2
ROM4:90AF   .BYTE $C2
ROM4:90B0   .BYTE $42
ROM4:90B1   .BYTE $42
ROM4:90B2   .BYTE $48
ROM4:90B3   .BYTE $48
ROM4:90B4   .BYTE $48
ROM4:90B5   .BYTE $41
ROM4:90B6   .BYTE $41
ROM4:90B7   .BYTE $41
ROM4:90B8   .BYTE $82
ROM4:90B9   .BYTE $82
ROM4:90BA   .BYTE $84
ROM4:90BB   .BYTE $84
ROM4:90BC   .BYTE $84
ROM4:90BD   .BYTE $81
ROM4:90BE   .BYTE $81
ROM4:90BF   .BYTE $81
ROM4:90C0   .BYTE $C4
ROM4:90C1   .BYTE $C4
ROM4:90C2   .BYTE $C2
ROM4:90C3   .BYTE $C2
ROM4:90C4   .BYTE $C2
ROM4:90C5   .BYTE $C8
ROM4:90C6   .BYTE $C8
ROM4:90C7   .BYTE $C8
ROM4:90C8   .BYTE $84
ROM4:90C9   .BYTE $84
ROM4:90CA   .BYTE $81
ROM4:90CB   .BYTE $81
ROM4:90CC   .BYTE $81
ROM4:90CD   .BYTE $88
ROM4:90CE   .BYTE $88
ROM4:90CF   .BYTE $88
ROM4:90D0   .BYTE $48
ROM4:90D1   .BYTE $48
ROM4:90D2   .BYTE $42
ROM4:90D3   .BYTE $42
ROM4:90D4   .BYTE $42
ROM4:90D5   .BYTE $44
ROM4:90D6   .BYTE $44
ROM4:90D7   .BYTE $44
ROM4:90D8   .BYTE 8
ROM4:90D9   .BYTE 8
ROM4:90DA   .BYTE 1
ROM4:90DB   .BYTE 1
ROM4:90DC   .BYTE 1
ROM4:90DD   .BYTE 4
ROM4:90DE   .BYTE 4
ROM4:90DF   .BYTE 4
ROM4:90E0 byte_110E0: .BYTE 0
ROM4:90E1   .BYTE $F0
ROM4:90E2 byte_110E2: .BYTE $3D
ROM4:90E3   .BYTE $DD
 
Subroutine update_monster_wall_master
ROM4:90E4 update_monster_wall_master:
ROM4:90E4 LDA walk_state_and_weapon_state,X
ROM4:90E5 BEQ state_0
ROM4:90E6 JMP state_not_0
 
ROM4:90E7 state_0: ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:90E7 LDA npc_action_timer_1
ROM4:90E8 BNE ret
ROM4:90E9 LDA walk_state_and_weapon_state
ROM4:90EA CMP #WalkState_3_MovementLocked
ROM4:90EB BNE link_not_locked
 
ROM4:90EC ret:
ROM4:90EC RTS
 
ROM4:90ED link_not_locked:
ROM4:90ED LDA object_x
ROM4:90EE CMP #41
ROM4:90EF BCC link_x_outside_41_200 ; Link X < 41
ROM4:90F0 CMP #200
ROM4:90F1 BCC link_y_inside_110_180 ; Link X < 200
 
ROM4:90F2 link_x_outside_41_200: ; Link X < 41 or X >= 200
ROM4:90F2 LDA object_y
ROM4:90F3 CMP #109 ; Link Y < 109
ROM4:90F4 BCC ret
ROM4:90F5 CMP #181 ; Link Y >= 181
ROM4:90F6 BCS ret
 
ROM4:90F7 link_y_inside_110_180: ; Link 110 <= Y < 181
ROM4:90F7 LDA object_x
ROM4:90F8 CMP #32 ; Link X == 32
ROM4:90F9 BEQ link_x_is_32_or_208
ROM4:90FA CMP #208 ; Link X == 208
ROM4:90FB BNE loc_11131
 
ROM4:90FC link_x_is_32_or_208: ; Link X == 32 or 208
ROM4:90FC LDA object_y
ROM4:90FD STA var_0
ROM4:90FE LDA object_x
ROM4:90FF STA var_1
ROM4:9100 LDA #8
ROM4:9101 STA var_2
ROM4:9102 LDY #$20
ROM4:9103 LDA #0
ROM4:9104 JSR sub_11262
ROM4:9105 LDA var_4
ROM4:9106 STA object_y,X
ROM4:9107 LDA byte_110E0,Y
ROM4:9108 JMP loc_11155
 
ROM4:9131 loc_11131:
ROM4:9131 LDA object_y
ROM4:9132 CMP #93
ROM4:9133 BEQ link_y_is_93_or_189 ; Link Y == 93
ROM4:9134 CMP #189
ROM4:9135 BNE ret ; Link Y == 189
 
ROM4:9136 link_y_is_93_or_189: ; Link Y == 93 or 189
ROM4:9136 LDA object_x
ROM4:9137 STA var_0
ROM4:9138 LDA object_y
ROM4:9139 STA var_1
ROM4:913A LDA #2
ROM4:913B STA var_2
ROM4:913C LDY #$5D
ROM4:913D LDA #$20
ROM4:913E JSR sub_11262
ROM4:913F LDA byte_110E2,Y
ROM4:9140 STA object_y,X
ROM4:9141 LDA var_4
 
ROM4:9155 loc_11155:
ROM4:9155 STA object_x,X
ROM4:9156 LDY enemy_state_0,X
ROM4:9157 LDA wall_master_directions,Y
ROM4:9158 AND #$F
ROM4:9159 STA object_direction,X
ROM4:915A LDA #$60
ROM4:915B STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:915C LDA #$18
ROM4:915D STA object_walk_speed,X
ROM4:915E LDA #8
ROM4:915F STA object_animation_frame_timer,X ; Set to 8
ROM4:9160 LDA #0
ROM4:9161 STA object_tile_offset_whole,X
ROM4:9162 STA enemy_projectile_speed_x,X
ROM4:9163 STA object_animation_frame,X
ROM4:9164 INC walk_state_and_weapon_state,X
ROM4:9165 RTS
 
ROM4:9166 state_not_0:
ROM4:9166 LDA object_knockback,X
ROM4:9167 BEQ no_knockback
ROM4:9168 JSR update_object_knockback
 
ROM4:9169 clock_is_active:
ROM4:9169 JMP wall_master_still_moving
 
ROM4:916A no_knockback: ; Check if the clock is active or the enemy is stunned
ROM4:916A LDA clock_active
ROM4:916B ORA enemy_stun,X
ROM4:916C BNE clock_is_active
ROM4:916D LDA object_direction,X
ROM4:916E STA var_15
ROM4:916F JSR process_movement
ROM4:9170 LDA object_tile_offset_whole,X
ROM4:9171 CMP #$10
ROM4:9172 BEQ reached_tile
ROM4:9173 CMP #$F0
ROM4:9174 BNE wall_master_still_moving
 
ROM4:9175 reached_tile:
ROM4:9175 LDA #0
ROM4:9176 STA object_tile_offset_whole,X
ROM4:9177 INC enemy_state_0,X ; Increment enemy_state_0 after crossing each tile
ROM4:9178 LDY enemy_state_0,X
ROM4:9179 LDA wall_master_directions,Y
ROM4:917A AND #$F
ROM4:917B STA object_direction,X ; Set the wall master's new direction
ROM4:917C INC enemy_projectile_speed_x,X ; Increment this state after crossing each tile to count the number of tiles it's
  ; crossed since it appeared. The wall master moves for 6 tiles each time it appears.
ROM4:917D LDA enemy_projectile_speed_x,X
ROM4:917E CMP #7
ROM4:917F BCC wall_master_still_moving ; If < 7, this wall master is still moving.
ROM4:9180 LDA enemy_state_4,X ; The wall master has reentered the wall. If enemy_state_4[X] is 1, this wall master is holding Link.
ROM4:9181 BEQ not_holding_link
ROM4:9182 JSR remove_like_like_or_wall_master_holding_link_sprite ; The wall master was holding Link, and has reentered the wall.
ROM4:9183 LDA #GameMode_CurtainsOpening
ROM4:9184 STA game_mode ; Set GameMode_CurtainsOpening when the wall master reaches the
  ; door while holding Link.
ROM4:9185 LDA #0
ROM4:9186 STA walk_state_and_weapon_state ; Set to 0
ROM4:9187 STA active_game_mode_task ; Set to 0
ROM4:9188 STA task_state ; Set to 0
 
ROM4:9189 not_holding_link:
ROM4:9189 STA walk_state_and_weapon_state,X
ROM4:918A RTS
 
ROM4:918B wall_master_still_moving:
ROM4:918B LDA enemy_state_4,X
ROM4:918C BNE holding_link ; The wall master has more tiles to move. Check if it's holding Link.
ROM4:918D JSR check_enemy_hits ; The wall master isn't holding Link, and is still moving outside the wall.
  ; Check for Link hitting the wall master and vice versa.
ROM4:918E LDA enemy_state_4,X ; check_enemy_hits just set this if the wall master hit Link.
ROM4:918F BEQ link_not_grabbed
ROM4:9190 LDA #WalkState_3_MovementLocked ; Lock Link's movement after being hit by a wall master.
ROM4:9191 STA walk_state_and_weapon_state
ROM4:9192 LDA #0
ROM4:9193 STA object_knockback ; Clear Link's knockback.
 
ROM4:9194 link_not_grabbed:
ROM4:9194 LDA next_sprite_index
ROM4:9195 PHA ; Save next_sprite_index
ROM4:9196 JSR update_wall_master_sprite
ROM4:9197 LDA object_animation_frame,X
ROM4:9198 JSR update_object_sprite_horizontal
ROM4:9199 PLA ; Restore next_sprite_index
ROM4:919A TAY
ROM4:919B LDA sprite_index_to_left_half,Y
ROM4:919C STA var_0 ; sprite_oam_data offset to left half
ROM4:919D LDA sprite_index_right_half,Y
 
ROM4:919E finish_updating_sprite: ; sprite_oam_data offset to right half
ROM4:919E STA var_1
ROM4:919F JSR wall_master_check_whether_to_hide_sprites
ROM4:91A0 LDX processing_object_index
ROM4:91A1 LDA object_animation_frame,X
ROM4:91A2 BEQ ret2
ROM4:91A3 LDY var_0
ROM4:91A4 LDA sprite_oam_data.tile,Y
ROM4:91A5 CMP #$9C
ROM4:91A6 BEQ loc_11217
ROM4:91A7 LDY var_1
 
ROM4:9217 loc_11217:
ROM4:9217 LDA #$AC
ROM4:9218 STA sprite_oam_data.tile,Y ; Tile ID
 
ROM4:9219 ret2:
ROM4:9219 RTS
 
ROM4:921A holding_link:
ROM4:921A LDA object_x,X
ROM4:921B STA object_x ; Move Link to the location of the wall master
ROM4:921C LDA object_y,X
ROM4:921D STA object_y
ROM4:921E JSR update_link_sprite_and_check_ladder_in_bank_4 ; Call update_link_sprite_and_check_ladder, then set bank 4 before returning.
ROM4:921F JSR update_clipping_sprites_under_wall ; Update clipping for the current object. This handles cutting
  ; off Link (and wall masters) as he goes under left/right side
  ; doors in dungeons.
ROM4:9220 LDX processing_object_index
ROM4:9221 JSR update_wall_master_sprite
ROM4:9222 LDA #1
ROM4:9223 STA object_animation_frame,X
ROM4:9224 JSR update_sprite_wall_master
ROM4:9225 LDA #$40
ROM4:9226 STA var_0
ROM4:9227 LDA #$44
ROM4:9228 JMP finish_updating_sprite
 
Subroutine update_wall_master_sprite
ROM4:9242 update_wall_master_sprite:
ROM4:9242 LDA #8
ROM4:9243 JSR update_object_animation_frame
ROM4:9244 LDY enemy_state_0,X
ROM4:9245 LDA wall_master_directions,Y
ROM4:9246 AND #$F0
ROM4:9247 ORA #OAMAttributes_Palette_1
ROM4:9248 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:9249 AND #OAMAttributes_FlipHorizontally
ROM4:924A BEQ ret
ROM4:924B LDA var_4
ROM4:924C AND #$8F ; Clear OAMAttributes_BehindBackground, OAMAttributes_FlipHorizontally and OAMAttributes_FlipVertically
ROM4:924D JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:924E INC var_15
 
ROM4:924F ret:
ROM4:924F RTS
 
Subroutine sub_11262
ROM4:9262 sub_11262:
ROM4:9262 STA enemy_state_0,X
ROM4:9263 STY var_3
ROM4:9264 LDA #$24
ROM4:9265 LDY walking_directions
ROM4:9266 BEQ loc_11270
ROM4:9267 LDA #$32
 
ROM4:9270 loc_11270:
ROM4:9270 LDY object_direction
ROM4:9271 CPY var_2
ROM4:9272 BNE loc_11286
ROM4:9273 PHA
ROM4:9274 LDA enemy_state_0,X
ROM4:9275 CLC
ROM4:9276 ADC #8
ROM4:9277 STA enemy_state_0,X
ROM4:9278 PLA
ROM4:9279 EOR #$FF
ROM4:927A CLC
ROM4:927B ADC #1
 
ROM4:9286 loc_11286:
ROM4:9286 CLC
ROM4:9287 ADC var_0
ROM4:9288 STA var_4
ROM4:9289 LDY #0
ROM4:928A LDA var_1
ROM4:928B CMP var_3
ROM4:928C BEQ locret_1129D
ROM4:928D LDA enemy_state_0,X
ROM4:928E CLC
ROM4:928F ADC #$10
ROM4:9290 STA enemy_state_0,X
ROM4:9291 INY
 
ROM4:929D locret_1129D:
ROM4:929D RTS
 
Subroutine wall_master_check_whether_to_hide_sprites
ROM4:929E wall_master_check_whether_to_hide_sprites:
ROM4:929E LDY var_0 ; Run the below with Y = var_0 and then Y = var_1, which are
  ; sprite offsets.
ROM4:929F JSR check_hide_sprite_x
ROM4:92A0 LDY var_1
 
ROM4:92A1 check_hide_sprite_x:
ROM4:92A1 LDX #1
 
ROM4:92A2 loop: ; Sprite X position
ROM4:92A2 LDA sprite_oam_data.x_pos,Y
ROM4:92A3 CLC
ROM4:92A4 ADC wall_master_hidden_under_wall_offset,X ; X = 0 for the left half of the sprite and 1 for the right half.
ROM4:92A5 CMP #$E9
ROM4:92A6 BCS hide_sprite ; A >= 0xE9
ROM4:92A7 CMP #$18 ; A >= 0x18
ROM4:92A8 BCS no_hide
 
ROM4:92A9 hide_sprite:
ROM4:92A9 LDA sprite_oam_data.attr,Y
ROM4:92AA ORA #OAMAttributes_BehindBackground ; Put the sprite behind the background (effectively hidden)
  ; if 0x18 < A > 0xEA.
ROM4:92AB STA sprite_oam_data.attr,Y
 
ROM4:92AC no_hide:
ROM4:92AC DEX
ROM4:92AD BPL loop
ROM4:92AE RTS
 
Subroutine spawn_rope
ROM4:92C2 spawn_rope:
ROM4:92C2 LDA #$10
ROM4:92C3 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM4:92C4 LDY current_save_slot
ROM4:92C5 LDA quest_no,Y
ROM4:92C6 BEQ loc_112D3
ROM4:92C7 LDA #$40
ROM4:92C8 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
 
ROM4:92D3 loc_112D3:
ROM4:92D3 JMP spawn_monster_basic ; This is the common setup for most monsters. It just picks
  ; an initial walking direction, based on the enemy's spawn
  ; position and the player seek position (enemy_behavior_seek_x,
  ; enemy_behavior_seek_y).
 
Subroutine update_monster_rope
ROM4:92D6 update_monster_rope:
ROM4:92D6 LDA object_direction,X
ROM4:92D7 STA walking_directions,X
ROM4:92D8 PHA
ROM4:92D9 LDA clock_active
ROM4:92DA ORA enemy_stun,X
ROM4:92DB BNE loc_11304
ROM4:92DC JSR update_object_movement ; Handle walking. X = 0 for Link, X > 0 for enemies.
ROM4:92DD LDA object_tile_offset_whole,X
ROM4:92DE AND #$F
ROM4:92DF BNE loc_112F0
ROM4:92E0 STA object_tile_offset_whole,X
 
ROM4:92F0 loc_112F0:
ROM4:92F0 LDA object_walk_speed,X
ROM4:92F1 CMP #$60
ROM4:92F2 BEQ loc_11304
ROM4:92F3 LDA enemy_action_timers,X
ROM4:92F4 BNE loc_11304
ROM4:92F5 LDA prng_0,X
ROM4:92F6 AND #$3F
ROM4:92F7 STA enemy_action_timers,X
ROM4:92F8 JSR rope_handle_movement_changes
 
ROM4:9304 loc_11304:
ROM4:9304 PLA
ROM4:9305 CMP object_direction,X
ROM4:9306 BEQ loc_1130E
ROM4:9307 LDA #$20
ROM4:9308 STA object_walk_speed,X
 
ROM4:930E loc_1130E:
ROM4:930E LDA object_walk_speed,X
ROM4:930F CMP #$20
ROM4:9310 BNE loc_11337
ROM4:9311 LDA object_tile_offset_whole,X
ROM4:9312 BNE loc_11337
ROM4:9313 LDA object_x
ROM4:9314 SEC
ROM4:9315 SBC object_x,X
ROM4:9316 JSR absolute_value ; A = abs(A)
ROM4:9317 CMP #8
ROM4:9318 BCS loc_1135F
ROM4:9319 LDA #8
ROM4:931A STA object_direction,X
ROM4:931B LDA object_y
ROM4:931C CMP object_y,X
ROM4:931D BCC loc_11332
 
ROM4:9330 loc_11330:
ROM4:9330 LSR object_direction,X
 
ROM4:9332 loc_11332:
ROM4:9332 LDA #$60
ROM4:9333 STA object_walk_speed,X
 
ROM4:9337 loc_11337:
ROM4:9337 LDA #$A
ROM4:9338 JSR update_object_animation_frame
ROM4:9339 LDA object_direction,X
ROM4:933A AND #2
ROM4:933B LSR A
ROM4:933C STA var_15
ROM4:933D LDA #OAMAttributes_Palette_2
ROM4:933E JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:933F LDY current_save_slot
ROM4:9340 LDA $62D,Y
ROM4:9341 BEQ loc_11356
ROM4:9342 LDA frame_counter
ROM4:9343 AND #3
ROM4:9344 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
 
ROM4:9356 loc_11356:
ROM4:9356 LDA object_animation_frame,X
ROM4:9357 JSR update_object_sprite_horizontal
ROM4:9358 JMP check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
 
ROM4:935F loc_1135F:
ROM4:935F LDA object_y
ROM4:9360 SEC
ROM4:9361 SBC object_y,X
ROM4:9362 JSR absolute_value ; A = abs(A)
ROM4:9363 CMP #8
ROM4:9364 BCS loc_11337
ROM4:9365 LDA #2
ROM4:9366 STA object_direction,X
ROM4:9367 LDA object_x
ROM4:9368 CMP object_x,X
ROM4:9369 BCS loc_11330
ROM4:936A BCC loc_11332
 
Subroutine update_monster_stalfos
ROM4:9377 update_monster_stalfos:
ROM4:9377 LDA #$80 ; Stalfos walking speed
ROM4:9378 JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:9379 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:937A LDA #8
ROM4:937B JSR update_sprite_bubble_stalfos_flame_patra
ROM4:937C LDA #$20
ROM4:937D STA var_1
ROM4:937E LDY current_save_slot
ROM4:937F LDA quest_no,Y ; Return if 1st quest.
ROM4:9380 BEQ locret_113E1
ROM4:9381 LDA stop_enemy_for_frames,X
ROM4:9382 BNE not_stopped
ROM4:9383 LDA prng_0,X ; If stop_enemy_for_frames is active, only continue with probability 8/256.
ROM4:9384 CMP #$F8
ROM4:9385 BCC locret_113E1
 
ROM4:9386 not_stopped:
ROM4:9386 LDA var_1
ROM4:9387 PHA
ROM4:9388 LDY #0
ROM4:9389 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:938A BNE loc_113B1
ROM4:938B LDY stop_enemy_for_frames,X
ROM4:938C DEY
ROM4:938D BPL loc_113B1
ROM4:938E LDA enemy_state_0,X
ROM4:938F BEQ loc_113DD
ROM4:9390 LDY #$30
 
ROM4:93B1 loc_113B1:
ROM4:93B1 TYA
ROM4:93B2 STA stop_enemy_for_frames,X
ROM4:93B3 BEQ loc_113DD
ROM4:93B4 CPY #$10
ROM4:93B5 BNE loc_113D9
ROM4:93B6 LDA clock_active
ROM4:93B7 ORA enemy_stun,X
ROM4:93B8 BNE loc_113D9
ROM4:93B9 LDA #ObjectType_Lynel_Sword
ROM4:93BA STA var_0
ROM4:93BB JSR create_object_at_another_object_2 ; Create ObjectType_Lynel_Sword.
ROM4:93BC BCC loc_113D2
ROM4:93BD LDA #128
ROM4:93BE STA enemy_action_timers,X
ROM4:93BF DEC enemy_state_5,X
 
ROM4:93D2 loc_113D2:
ROM4:93D2 BCC loc_113DD
ROM4:93D3 LDA #0
ROM4:93D4 STA enemy_state_0,X
 
ROM4:93D9 loc_113D9:
ROM4:93D9 PLA
ROM4:93DA LDA #0
ROM4:93DB PHA
 
ROM4:93DD loc_113DD:
ROM4:93DD PLA
ROM4:93DE STA object_walk_speed,X
 
ROM4:93E1 locret_113E1:
ROM4:93E1 RTS
 
Subroutine spawn_moldorm
; Create lots of Moldorm pieces
ROM4:93E2 spawn_moldorm:
ROM4:93E2 LDY #9
 
ROM4:93E3 create_next_moldorm_piece:
ROM4:93E3 LDA #$80
ROM4:93E4 STA object_x_1,Y ; Spawn Moldorm pieces at X = 0x80
ROM4:93E5 LDA #$70
ROM4:93E6 STA object_y_1,Y ; Spawn Moldorm pieces at Y = 0x70
ROM4:93E7 LDA #0
ROM4:93E8 STA object_direction_1,Y ; Set to 0
ROM4:93E9 STA object_walk_speed_1,Y ; Set to 0
ROM4:93EA STA enemy_spawn_state_1,Y ; Set to 0
ROM4:93EB STA byte_493,Y ; Set to 0
ROM4:93EC LDA enemy_state_9_1
ROM4:93ED STA enemy_state_9_1,Y
ROM4:93EE LDA enemy_health_1
ROM4:93EF STA enemy_health_1,Y
ROM4:93F0 LDA #$80
ROM4:93F1 STA enemy_projectile_speed_x_1,Y ; Set to 0x80
ROM4:93F2 LDA #2
ROM4:93F3 STA enemy_state_6_1,Y ; Set to 2
ROM4:93F4 LDA #ObjectType_Moldorm
ROM4:93F5 STA object_type_1,Y ; Set to ObjectType_Moldorm
ROM4:93F6 DEY
ROM4:93F7 BPL create_next_moldorm_piece
ROM4:93F8 LDA prng_5
ROM4:93F9 AND #7
ROM4:93FA TAY
ROM4:93FB LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:93FC STA object_direction_1+4
ROM4:93FD STA unk_385
ROM4:93FE LDA prng_A
ROM4:93FF AND #7
ROM4:9400 TAY
ROM4:9401 LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:9402 STA projectile_direction_mask+3
ROM4:9403 STA unk_38A
ROM4:9404 LDA #1
ROM4:9405 STA enemy_state_4_5
ROM4:9406 STA byte_436
ROM4:9407 LDA #$80
ROM4:9408 STA increase_enemy_speed_max ; Set to 0x80.
ROM4:9409 LDA #8
ROM4:940A STA total_enemies_spawned_in_room ; Set to 8
ROM4:940B RTS
 
Subroutine spawn_aquamentus
ROM4:9447 spawn_aquamentus:
ROM4:9447 LDA #DamageType_Boomerang|DamageType_Fire|DamageType_Unknown_40|DamageType_Unknown_80
ROM4:9448 STA damage_types_with_no_knockback,X ; Set to 0xE2.
ROM4:9449 LDA #Sound0_BossRoar1
ROM4:944A STA play_sound_0 ; Play Sound0_BossRoar1
ROM4:944B LDA #176
ROM4:944C STA object_x,X ; Spawn Aquamentus at X = 176
ROM4:944D LDA #128
ROM4:944E STA object_y,X ; Spawn Aquamentus at Y = 128
ROM4:944F RTS
 
Subroutine spawn_digdogger_3
ROM4:945A spawn_digdogger_3:
ROM4:945A LDA #Sound0_BossRoar3
ROM4:945B STA play_sound_0 ; Play Sound0_BossRoar3
ROM4:945C LDA prng_0,X
ROM4:945D AND #7
ROM4:945E TAY
ROM4:945F LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:9460 STA object_direction,X
ROM4:9461 LDA #$3F
ROM4:9462 STA enemy_projectile_speed_x,X
ROM4:9463 LDA #$80
ROM4:9464 STA enemy_state_5,X
ROM4:9465 LDA #3
ROM4:9466 STA number_of_digdogger_spawn_to_create ; Set to 3.
ROM4:9467 RTS
 
Subroutine spawn_digdogger_1
ROM4:9479 spawn_digdogger_1:
ROM4:9479 JSR spawn_digdogger_3
ROM4:947A LDA #ObjectType_Digdogger_3
ROM4:947B STA object_type,X ; Set to ObjectType_Digdogger_3.
ROM4:947C LDA #1
ROM4:947D STA number_of_digdogger_spawn_to_create ; Set to 1.
ROM4:947E RTS
 
Subroutine spawn_dodongo
ROM4:9487 spawn_dodongo:
ROM4:9487 LDA #Sound0_BossRoar2
ROM4:9488 STA play_sound_0 ; Play Sound0_BossRoar2
ROM4:9489 LDY #ControllerBits_Dpad_Right ; Y = ControllerBits_Dpad_Right
ROM4:948A LDA prng_0,X ; Randomly spawn facing left or right.
ROM4:948B CMP #$80
ROM4:948C BCC ret
ROM4:948D INY ; Y = ControllerBits_Dpad_Left
 
ROM4:948E ret:
ROM4:948E STY object_direction,X
ROM4:948F RTS
 
Subroutine update_monster_moldorm
ROM4:9498 update_monster_moldorm:
ROM4:9498 LDA object_direction,X
ROM4:9499 BEQ locret_11501
ROM4:949A LDA clock_active
ROM4:949B BNE loc_114A7
 
ROM4:94A1 loc_114A1:
ROM4:94A1 JSR loc_11502
ROM4:94A2 JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
 
ROM4:94A7 loc_114A7:
ROM4:94A7 LDA #2
ROM4:94A8 STA var_3 ; Moldorm's palette index
ROM4:94A9 LDA #$44
ROM4:94AA JSR setup_sprites_ganon_moldorm_lanmola
ROM4:94AB LDA object_direction,X
ROM4:94AC PHA
ROM4:94AD LDA enemy_action_timers,X
ROM4:94AE PHA
ROM4:94AF JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:94B0 PLA
ROM4:94B1 STA enemy_action_timers,X
ROM4:94B2 PLA
ROM4:94B3 STA object_direction,X
ROM4:94B4 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:94B5 BEQ locret_11501
ROM4:94B6 LDA #$20
ROM4:94B7 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM4:94B8 JSR loc_1179A
ROM4:94B9 LDY #$FF
ROM4:94BA CPX #6
ROM4:94BB BCC loc_114D4
ROM4:94BC LDY #4
 
ROM4:94D4 loc_114D4:
ROM4:94D4 INY
ROM4:94D5 LDA object_type_1,Y
ROM4:94D6 CMP #$41
ROM4:94D7 BNE loc_114D4
ROM4:94D8 LDA #$11
ROM4:94D9 STA npc_action_timer_1,Y ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:94DA LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:94DB STA invincibility_frames_1,Y
ROM4:94DC LDA object_x,X
ROM4:94DD STA object_x_1,Y
ROM4:94DE LDA object_y,X
ROM4:94DF STA object_y_1,Y
ROM4:94E0 CPY #4
ROM4:94E1 BEQ locret_11501
ROM4:94E2 CPY #9
ROM4:94E3 BEQ locret_11501
ROM4:94E4 LDA #ObjectType_EnemyDeath
ROM4:94E5 STA object_type_1,Y ; Set to ObjectType_EnemyDeath
ROM4:94E6 JSR set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
 
ROM4:9501 locret_11501:
ROM4:9501 RTS
 
ROM4:9502 loc_11502:
ROM4:9502 LDA enemy_state_6,X
ROM4:9503 JSR call_jump_table
 
ROM4:9504   .WORD update_monster_moldorm_0
ROM4:9506   .WORD update_monster_moldorm_0
ROM4:9508   .WORD update_monster_moldorm_0
ROM4:950A   .WORD update_monster_moldorm_3
 
Subroutine update_monster_moldorm_0
ROM4:9510 update_monster_moldorm_0:
ROM4:9510 CPX #5
ROM4:9511 BEQ loc_11518
ROM4:9512 CPX #$A
ROM4:9513 BNE locret_1156B
 
ROM4:9518 loc_11518: ; Update the current enemy's direction relative to the seek
ROM4:9518 JSR update_monster_diagonal_movement_relative_to_seek ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:9519 LDA enemy_action_timers,X
ROM4:951A BNE loc_1153A
 
ROM4:951F loc_1151F:
ROM4:951F JSR update_monster_moldorm_0a
ROM4:9520 LDA #$10
ROM4:9521 STA enemy_action_timers,X
ROM4:9522 LDA floor_item_y,X
ROM4:9523 BNE loc_1153A
ROM4:9524 RTS
 
Subroutine update_monster_moldorm_3
ROM4:952B update_monster_moldorm_3:
ROM4:952B CPX #5
ROM4:952C BEQ loc_11533
ROM4:952D CPX #$A
ROM4:952E BNE locret_1156B
 
ROM4:9533 loc_11533: ; Randomly change direction by 45, 0 or -45 degrees.
ROM4:9533 JSR update_monster_45_degree_movement
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:9534 LDA enemy_action_timers,X
ROM4:9535 BEQ loc_1151F
 
ROM4:953A loc_1153A:
ROM4:953A LDA enemy_action_timers,X
ROM4:953B CMP #$10
ROM4:953C BNE locret_1156B
ROM4:953D LDA object_walk_speed,X
ROM4:953E BEQ loc_1154C
ROM4:953F STA object_direction,X
ROM4:9540 LDA #0
ROM4:9541 STA object_walk_speed,X
 
ROM4:954C loc_1154C:
ROM4:954C LDA #4
ROM4:954D STA var_0
ROM4:954E LDY #0
ROM4:954F CPX #5
ROM4:9550 BEQ loc_11558
ROM4:9551 LDY #5
 
ROM4:9558 loc_11558:
ROM4:9558 LDA unk_382,Y
ROM4:9559 STA enemy_state_11_1,Y
ROM4:955A STA object_direction_1,Y
ROM4:955B INY
ROM4:955C DEC var_0
ROM4:955D BNE loc_11558
ROM4:955E LDA object_direction,X
ROM4:955F STA enemy_state_11,X
 
ROM4:956B locret_1156B:
ROM4:956B RTS
 
Subroutine update_monster_moldorm_0a
ROM4:956C update_monster_moldorm_0a:
ROM4:956C LDY #2
ROM4:956D LDA prng_0,X
ROM4:956E CMP #$40
ROM4:956F BCS loc_11575
ROM4:9570 INY
 
ROM4:9575 loc_11575:
ROM4:9575 TYA
ROM4:9576 STA enemy_state_6,X
ROM4:9577 LDA #8
ROM4:9578 STA enemy_state_4,X
ROM4:9579 RTS
 
ROM4:957F byte_1157F: .BYTE 0
ROM4:9580   .BYTE $10
ROM4:9581   .BYTE 0
ROM4:9582   .BYTE $F0
ROM4:9583 byte_11583: .BYTE 0
ROM4:9584   .BYTE $10
ROM4:9585   .BYTE $F0
ROM4:9586   .BYTE $10
 
Function chunk for update_monster_digdogger
ROM4:9587 update_monster_digdogger_sub:
ROM4:9587 DEY
ROM4:9588 BNE loc_11599
ROM4:9589 LDA enemy_state_1,X
ROM4:958A BNE loc_115FC
ROM4:958B LDA #$40
ROM4:958C STA enemy_action_timers,X ; Set to 0x40.
ROM4:958D INC used_recorder_in_dungeon
ROM4:958E JMP loc_11621
 
ROM4:9599 loc_11599:
ROM4:9599 LDA enemy_action_timers,X
ROM4:959A BEQ loc_115AE
ROM4:959B AND #7
ROM4:959C BNE loc_115AB
ROM4:959D LDA enemy_state_1,X
ROM4:959E EOR #1
ROM4:959F STA enemy_state_1,X
ROM4:95A0 BEQ loc_11621
 
ROM4:95AB loc_115AB:
ROM4:95AB JMP done_creating_digdogger_spawn
 
ROM4:95AE loc_115AE:
ROM4:95AE DEC used_recorder_in_dungeon
ROM4:95AF LDA number_of_digdogger_spawn_to_create
ROM4:95B0 STA var_0
ROM4:95B1 STA total_enemies_spawned_in_room
ROM4:95B2 TXA
ROM4:95B3 PHA
 
ROM4:95B4 create_digdogger_spawn:
ROM4:95B4 INX
ROM4:95B5 JSR spawn_digdogger_3
ROM4:95B6 LDA #ObjectType_Digdogger_Spawn
 
ROM4:95C1 loc_115C1: ; Set to ObjectType_Digdogger_Spawn
ROM4:95C1 STA object_type,X
ROM4:95C2 INC enemy_state_6,X
ROM4:95C3 LDA #1
ROM4:95C4 STA enemy_state_1,X ; Set to 1
ROM4:95C5 LDA #0
ROM4:95C6 STA enemy_state_2,X ; Set to 0
ROM4:95C7 LDA object_x_1 ; This assumes digdogger is the only enemy on screen.
ROM4:95C8 STA object_x,X ; Set the new enemy's X location to where we used to be.
ROM4:95C9 LDA object_y_1
ROM4:95CA STA object_y,X ; Set the new enemy's Y location to where we used to be.
ROM4:95CB DEC var_0
ROM4:95CC BNE create_digdogger_spawn ; Loop if we need to create more spawn.
ROM4:95CD PLA
ROM4:95CE TAX
ROM4:95CF JSR play_boss_sound_1
ROM4:95D0 LDA #0
ROM4:95D1 STA object_type,X ; Delete the original digdogger.
ROM4:95D2 JMP done_creating_digdogger_spawn
 
ROM4:95EA loc_115EA:
ROM4:95EA JSR update_monster_diagonal_movement_relative_to_seek_from_digdogger
ROM4:95EB JMP loc_11610
 
Subroutine update_monster_digdogger
ROM4:95F0 update_monster_digdogger:
 
ROM4:95F0 LDA clock_active
ROM4:95F1 ORA enemy_stun,X
ROM4:95F2 BNE loc_11613 ; Branch if the clock is active or the enemy is stunned.
ROM4:95F3 LDY used_recorder_in_dungeon
ROM4:95F4 BNE update_monster_digdogger_sub
 
ROM4:95FC loc_115FC:
ROM4:95FC JSR call_digdogger_state
ROM4:95FD LDA enemy_action_timers,X
ROM4:95FE BNE loc_11610
ROM4:95FF LDA #$10
ROM4:9600 STA enemy_action_timers,X
ROM4:9601 LDA prng_0,X
ROM4:9602 CMP #$80
ROM4:9603 BCS loc_115EA
ROM4:9604 JSR randomly_rotate_movement_by_45_degrees
 
ROM4:9610 loc_11610:
ROM4:9610 JSR update_monster_digdogger_4
 
ROM4:9613 loc_11613:
ROM4:9613 LDA enemy_state_1,X
ROM4:9614 BEQ loc_11621
ROM4:9615 JSR reverse_walking_direction_if_out_of_bounds ; If this object is walking out of the boundary of this
  ; screen, turn around.
ROM4:9616 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9617 JMP update_monster_digdogger_2
 
ROM4:9621 loc_11621: ; Save object_x[X} and object_y[X].
ROM4:9621 LDA object_x,X
ROM4:9622 PHA
ROM4:9623 LDA object_y,X
ROM4:9624 PHA
ROM4:9625 LDA #0
ROM4:9626 STA enemy_blind_projectile_timer,X
 
ROM4:9627 loop:
ROM4:9627 LDY enemy_blind_projectile_timer,X
ROM4:9628 LDA object_x,X
ROM4:9629 CLC
ROM4:962A ADC byte_1157F,Y
ROM4:962B STA object_x,X
ROM4:962C LDA object_y,X
ROM4:962D CLC
ROM4:962E ADC byte_11583,Y
ROM4:962F STA object_y,X
ROM4:9630 JSR reverse_walking_direction_if_out_of_bounds ; If this object is walking out of the boundary of this
  ; screen, turn around.
ROM4:9631 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9632 INC enemy_blind_projectile_timer,X
ROM4:9633 LDA enemy_blind_projectile_timer,X
ROM4:9634 CMP #4
ROM4:9635 BCC loop
ROM4:9636 PLA ; Restore object_x[X} and object_y[X].
ROM4:9637 STA object_y,X
ROM4:9638 PLA
ROM4:9639 STA object_x,X
ROM4:963A JSR update_monster_digdogger_2
 
ROM4:963B done_creating_digdogger_spawn:
ROM4:963B LDA object_x,X
ROM4:963C PHA ; Save our X position.
ROM4:963D LDA object_y,X
ROM4:963E PHA ; Save our Y position.
ROM4:963F CLC
ROM4:9640 ADC #8
ROM4:9641 STA object_y,X ; Y position += 8
ROM4:9642 LDA object_x,X
ROM4:9643 CLC
ROM4:9644 ADC #8
ROM4:9645 STA object_x,X ; X position += 8
ROM4:9646 LDA enemy_state_1,X
ROM4:9647 PHA
ROM4:9648 LDA object_type,X ; Save our object type.
ROM4:9649 PHA
ROM4:964A LDA #ObjectType_Digdogger_Spawn
ROM4:964B STA object_type,X ; Replace our object type with Digdogger_Spawn.
ROM4:964C LDA #1
ROM4:964D STA enemy_state_1,X
ROM4:964E JSR update_monster_digdogger_2
ROM4:964F PLA
ROM4:9650 STA object_type,X ; Restore our object type
ROM4:9651 PLA
ROM4:9652 STA enemy_state_1,X
ROM4:9653 PLA
ROM4:9654 STA object_y,X ; Restore our Y position.
ROM4:9655 PLA
ROM4:9656 STA object_x,X ; Restore our X position.
ROM4:9657 RTS
 
Subroutine call_digdogger_state
ROM4:968E call_digdogger_state:
ROM4:968E LDA enemy_state_2,X
ROM4:968F JSR call_jump_table
 
ROM4:9690   .WORD update_monster_digdogger_0
ROM4:9692   .WORD update_monster_digdogger_1
 
Subroutine update_monster_digdogger_0
ROM4:9698 update_monster_digdogger_0:
ROM4:9698 INC enemy_projectile_speed_x,X
ROM4:9699 BNE loc_116A0
ROM4:969A INC enemy_state_4,X
 
ROM4:96A0 loc_116A0:
ROM4:96A0 LDA enemy_projectile_speed_x,X
ROM4:96A1 CMP enemy_state_5,X
ROM4:96A2 BNE locret_116EA
ROM4:96A3 LDA enemy_state_4,X
ROM4:96A4 CMP enemy_state_6,X
ROM4:96A5 BNE locret_116EA
ROM4:96A6 INC enemy_state_2,X
ROM4:96A7 LDA #$40
ROM4:96A8 JMP loc_116DA
 
ROM4:96B8 update_monster_digdogger_1:
ROM4:96B8 DEC enemy_projectile_speed_x,X
ROM4:96B9 LDA enemy_projectile_speed_x,X
ROM4:96BA CMP #$FF
ROM4:96BB BNE loc_116C5
ROM4:96BC DEC enemy_state_4,X
 
ROM4:96C5 loc_116C5:
ROM4:96C5 LDA enemy_projectile_speed_x,X
ROM4:96C6 CMP enemy_state_5,X
ROM4:96C7 BNE locret_116EA
ROM4:96C8 LDA enemy_state_4,X
ROM4:96C9 CMP enemy_state_6,X
ROM4:96CA BNE locret_116EA
ROM4:96CB DEC enemy_state_2,X
ROM4:96CC LDA #$80
 
ROM4:96DA loc_116DA:
ROM4:96DA STA enemy_state_5,X
ROM4:96DB LDA #0
ROM4:96DC STA enemy_state_6,X
ROM4:96DD LDA enemy_state_1,X
ROM4:96DE BEQ locret_116EA
ROM4:96DF INC enemy_state_6,X
 
ROM4:96EA locret_116EA:
ROM4:96EA RTS
 
Subroutine update_monster_digdogger_4
ROM4:96EB update_monster_digdogger_4:
ROM4:96EB LDA enemy_projectile_speed_x,X
ROM4:96EC AND #$E0
ROM4:96ED CLC
ROM4:96EE ADC enemy_state_0,X
ROM4:96EF STA enemy_state_0,X
ROM4:96F0 LDA enemy_state_4,X
ROM4:96F1 ADC #0
ROM4:96F2 STA var_3
ROM4:96F3 LDA #$A1
ROM4:96F4 STA var_2
ROM4:96F5 LDA object_direction,X
ROM4:96F6 BIT var_2
ROM4:96F7 BEQ loc_1170F
ROM4:96F8 LDA object_x,X
ROM4:96F9 CLC
ROM4:96FA ADC var_3
ROM4:96FB STA object_x,X
 
ROM4:970F loc_1170F:
ROM4:970F LDA object_direction,X
ROM4:9710 ASL var_2
ROM4:9711 BIT var_2
ROM4:9712 BEQ loc_1171D
ROM4:9713 LDA object_x,X
ROM4:9714 SBC var_3
ROM4:9715 STA object_x,X
 
ROM4:971D loc_1171D:
ROM4:971D LDA object_direction,X
ROM4:971E ASL var_2
ROM4:971F BIT var_2
ROM4:9720 BEQ loc_1172B
ROM4:9721 LDA object_y,X
ROM4:9722 ADC var_3
ROM4:9723 STA object_y,X
 
ROM4:972B loc_1172B:
ROM4:972B LDA object_direction,X
ROM4:972C ASL var_2
ROM4:972D BIT var_2
ROM4:972E BEQ loc_11739
ROM4:972F LDA object_y,X
ROM4:9730 SBC var_3
ROM4:9731 STA object_y,X
 
ROM4:9739 loc_11739: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:9739 JMP set_var_0_to_object_position
 
ROM4:973C digdogger_spawn_x_offsets: .BYTE 0
ROM4:973D   .BYTE $10
ROM4:973E   .BYTE 0
ROM4:973F   .BYTE $10
ROM4:9740 digdogger_spawn_y_offsets: .BYTE 0
ROM4:9741   .BYTE 0
ROM4:9742   .BYTE $10
ROM4:9743   .BYTE $10
ROM4:9744 digdogger_spawn_tile_attributes: .BYTE OAMAttributes_Palette_3
ROM4:9745   .BYTE OAMAttributes_Palette_3
ROM4:9746   .BYTE OAMAttributes_Palette_3|OAMAttributes_FlipVertically
ROM4:9747   .BYTE OAMAttributes_Palette_3|OAMAttributes_FlipVertically
 
Subroutine update_monster_digdogger_2
ROM4:9748 update_monster_digdogger_2:
ROM4:9748 LDA #6
ROM4:9749 JSR update_object_animation_frame
ROM4:974A LDA enemy_state_1,X
ROM4:974B BNE loc_1177D
ROM4:974C LDY #0 ; Loop Y = 0 to 3.
 
ROM4:974D loop:
ROM4:974D LDA object_x,X
ROM4:974E CLC
ROM4:974F ADC digdogger_spawn_x_offsets,Y
ROM4:9750 STA var_0
ROM4:9751 LDA object_y,X
ROM4:9752 CLC
ROM4:9753 ADC digdogger_spawn_y_offsets,Y
ROM4:9754 STA var_1
ROM4:9755 LDA digdogger_spawn_tile_attributes,Y
ROM4:9756 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:9757 TYA ; Save Y.
ROM4:9758 PHA
ROM4:9759 AND #1
ROM4:975A STA var_15 ; var_15 = Y & 1
ROM4:975B LDA #0
ROM4:975C JSR update_object_sprite_horizontal
ROM4:975D PLA ; Restore Y.
ROM4:975E TAY
ROM4:975F INY
ROM4:9760 CPY #4
ROM4:9761 BNE loop ; 4x
ROM4:9762 RTS
 
ROM4:977D loc_1177D:
ROM4:977D JSR set_tile_attributes_to_palette_3
ROM4:977E LDA object_animation_frame,X
ROM4:977F JMP update_object_sprite_vertical
 
Subroutine update_monster_aquamentus
ROM4:9786 update_monster_aquamentus:
ROM4:9786 LDA clock_active
ROM4:9787 BNE ret ; Skip if the clock is active. (Is it ever possible to have
  ; a clock in an aquamentus room? This would cause fireballs
  ; to stop moving correctly.)
ROM4:9788 JSR update_monster_aquamentus_movement
ROM4:9789 JSR update_aquamentus_fireballs
 
ROM4:978A ret:
ROM4:978A JSR update_monster_aquamentus_0
ROM4:978B JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:978C JSR play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
 
ROM4:979A loc_1179A:
ROM4:979A JSR play_boss_sound_1_if_not_state_0
ROM4:979B JMP clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
 
ROM4:97A0 aquamentus_x_movement_speed: .BYTE 1 ; Right
ROM4:97A1   .BYTE $FF ; Left
 
Subroutine update_monster_aquamentus_movement
ROM4:97A2 update_monster_aquamentus_movement:
ROM4:97A2 LDA object_tile_offset_whole,X
ROM4:97A3 BNE not_on_tile ; Check if we're standing on a tile
ROM4:97A4 LDA prng_0,X ; When Aquamentus steps on a tile, randomly choose if it should
  ; move left or right.
ROM4:97A5 PHA ; Push prng value
ROM4:97A6 AND #$F
ROM4:97A7 ORA #7
ROM4:97A8 STA object_tile_offset_whole,X
ROM4:97A9 PLA ; Pop prng value
ROM4:97AA AND #1 ; Randomly move left or right (3 or 2)
ROM4:97AB TAY
ROM4:97AC INY
ROM4:97AD STY object_direction,X ; Store new aquamentus direction
ROM4:97AE RTS
 
ROM4:97AF not_on_tile:
ROM4:97AF LDA frame_counter
ROM4:97B0 AND #7
ROM4:97B1 BNE ret ; Skip if the frame number isn't divisible by 8
ROM4:97B2 LDA object_x,X
ROM4:97B3 CMP #$88
ROM4:97B4 BCS not_too_far_left ; X >= 0x88
ROM4:97B5 LDA #$88 ; If we've moved further left than X = 0x88, snap to 0x88
  ; and start moving right.
ROM4:97B6 STA object_x,X
ROM4:97B7 LDA #ControllerBits_Dpad_Right
ROM4:97B8 STA object_direction,X
ROM4:97B9 BNE reset_tile_offset
 
ROM4:97BA not_too_far_left:
ROM4:97BA CMP #$C8
ROM4:97BB BCC not_too_far_right ; X < 0xC8
ROM4:97BC LDA #$C7 ; If we've moved further right than X = 0xC7, snap to 0xC7
  ; and start moving left.
ROM4:97BD STA object_x,X
ROM4:97BE LDA #2
ROM4:97BF STA object_direction,X
 
ROM4:97C0 reset_tile_offset: ; Adjust the tile offset to line up with the snapped X position.
ROM4:97C0 LDA #7
ROM4:97C1 STA object_tile_offset_whole,X
 
ROM4:97C2 not_too_far_right:
ROM4:97C2 LDY object_direction,X
ROM4:97C3 DEY ; We're always moving left or right. Decrement by 1
  ; so Y = 0 if right, 1 if left.
ROM4:97C4 LDA object_x,X ; Update our X position depending on which direction
  ; we're moving.
ROM4:97C5 CLC
ROM4:97C6 ADC aquamentus_x_movement_speed,Y
ROM4:97C7 STA object_x,X
ROM4:97C8 DEC object_tile_offset_whole,X
 
ROM4:97C9 ret:
ROM4:97C9 RTS
 
Subroutine update_aquamentus_fireballs
ROM4:97EF update_aquamentus_fireballs:
ROM4:97EF LDA enemy_action_timers,X
ROM4:97F0 BNE action_timer_not_expired
ROM4:97F1 LDA prng_0,X
ROM4:97F2 ORA #$70
ROM4:97F3 STA enemy_action_timers,X ; Set action timer to 0x70-0xFF. This timer is biased due
  ; to the simple way the minimum delay is set.
ROM4:97F4 JSR aquamentus_shoot_fireball ; Shoot three fireballs
ROM4:97F5 LDA #0
ROM4:97F6 STA enemy_blind_projectile_timer,Y ; Set to 0 (straight forward)
ROM4:97F7 JSR aquamentus_shoot_fireball
ROM4:97F8 LDA #1
ROM4:97F9 STA enemy_blind_projectile_timer,Y ; Set to 1 (down-left)
ROM4:97FA JSR aquamentus_shoot_fireball
ROM4:97FB LDA #$FF
ROM4:97FC STA enemy_blind_projectile_timer,Y ; Set to -1 (up-left)
ROM4:97FD RTS
 
ROM4:97FE action_timer_not_expired: ; Update the Y positions of all fireballs
ROM4:97FE LDX #$B
 
ROM4:97FF loop:
ROM4:97FF LDA object_type,X
ROM4:9800 CMP #ObjectType_Homing_Fireball_1 ; Check if this object is one of our fireballs
ROM4:9801 BNE skip
ROM4:9802 LDA frame_counter
ROM4:9803 LSR A
ROM4:9804 BCS skip ; Skip on odd frames
ROM4:9805 LDA object_y,X
ROM4:9806 CLC
ROM4:9807 ADC enemy_blind_projectile_timer,X ; Move this projectile on Y by -1, 0 or +1
ROM4:9808 STA object_y,X
 
ROM4:9809 skip:
ROM4:9809 DEX
ROM4:980A BPL loop
ROM4:980B LDX processing_object_index
ROM4:980C RTS
 
Subroutine aquamentus_shoot_fireball
ROM4:982F aquamentus_shoot_fireball:
ROM4:982F LDA #ObjectType_Homing_Fireball_1
ROM4:9830 JMP create_fireball_near_object ; Create a ObjectType_Homing_Fireball_1.
 
ROM4:9834 aquamentus_data_0: .BYTE $CC
ROM4:9835   .BYTE $C4
ROM4:9836   .BYTE $C8
ROM4:9837   .BYTE $C2
ROM4:9838   .BYTE $C6
ROM4:9839   .BYTE $CA
ROM4:983A   .BYTE $CC
ROM4:983B   .BYTE $C4
ROM4:983C   .BYTE $C8
ROM4:983D   .BYTE $CE
ROM4:983E   .BYTE $D0
ROM4:983F   .BYTE $D2
ROM4:9840 aquamentus_data_1: .BYTE 0
ROM4:9841   .BYTE 0
ROM4:9842   .BYTE 0
ROM4:9843   .BYTE $10
ROM4:9844   .BYTE $10
ROM4:9845   .BYTE $10
ROM4:9846 aquamentus_data_2: .BYTE 0
ROM4:9847   .BYTE 8
ROM4:9848   .BYTE $10
ROM4:9849   .BYTE 0
ROM4:984A   .BYTE 8
ROM4:984B   .BYTE $10
 
Subroutine update_monster_aquamentus_0
ROM4:984C update_monster_aquamentus_0:
ROM4:984C LDY #5 ; This alternates between 5 and 12 every 16 frames.
ROM4:984D LDA frame_counter
ROM4:984E AND #$10
ROM4:984F BNE alternating
ROM4:9850 LDY #$B
 
ROM4:9851 alternating:
ROM4:9851 STY var_10
ROM4:9852 LDA #5 ; Loop 6 times
ROM4:9853 STA var_11
 
ROM4:9854 loop:
ROM4:9854 LDY var_11
ROM4:9855 LDA object_x,X
ROM4:9856 CLC
ROM4:9857 ADC aquamentus_data_2,Y
ROM4:9858 STA var_0
ROM4:9859 LDA object_y,X
ROM4:985A CLC
ROM4:985B ADC aquamentus_data_1,Y
ROM4:985C STA var_1
ROM4:985D LDA invincibility_frames,X ; Apply palette shifting for invincibility frames.
ROM4:985E AND #3
ROM4:985F EOR #3
ROM4:9860 STA var_3 ; Save the palette number to tile attributes.
ROM4:9861 LDY var_10
ROM4:9862 LDA aquamentus_data_0,Y
ROM4:9863 CMP aquamentus_data_0
ROM4:9864 BNE run_update_sprite
ROM4:9865 LDY enemy_action_timers,X
ROM4:9866 CPY #$20
ROM4:9867 BCS run_update_sprite
ROM4:9868 LDA #$C0 ; Tile index
 
ROM4:9869 run_update_sprite:
ROM4:9869 JSR update_aquamentus_sprite
ROM4:986A DEC var_10
ROM4:986B DEC var_11
ROM4:986C BPL loop
ROM4:986D RTS
 
Subroutine update_aquamentus_sprite
ROM4:9893 update_aquamentus_sprite:
ROM4:9893 PHA ; Store A
ROM4:9894 LDY next_sprite_index ; This load gets overwritten immediately by the TAY below.
ROM4:9895 LDA sprite_index_to_left_half,Y
ROM4:9896 TAY
ROM4:9897 PLA ; Restore A
ROM4:9898 STA sprite_oam_data.tile,Y ; Tile index
ROM4:9899 LDA var_0
ROM4:989A STA sprite_oam_data.x_pos,Y ; Sprite X position
ROM4:989B LDA var_1 ; Sprite Y position
ROM4:989C JMP update_sprite_y_attributes_then_advance ; sprite_oam_data[Y] = A (Y position)
  ; sprite_oam_data[Y+2] = var_3 (tile attributes)
 
Subroutine update_monster_dodongo
ROM4:98A9 update_monster_dodongo:
ROM4:98A9 JSR update_monster_dodongo_sub_1
ROM4:98AA JSR dodongo_check_hits_and_death ; Check if Dodongo hit Link, or if Link hit Dodongo for both
  ; tiles of Dodongo.
ROM4:98AB JSR dodongo_check_nearby_bombs
ROM4:98AC JMP dodongo_update_sprites
 
ROM4:98AD   .BYTE $10
ROM4:98AE   .BYTE $F0
ROM4:98AF   .BYTE $10
ROM4:98B0   .BYTE $FF
ROM4:98B1   .BYTE $F0
ROM4:98BA frames_per_dodongo_state_4: .BYTE $20
ROM4:98BB   .BYTE $40
ROM4:98BC   .BYTE $40
 
Subroutine update_monster_dodongo_sub_1
ROM4:98BD update_monster_dodongo_sub_1:
ROM4:98BD LDA walk_state_and_weapon_state,X
ROM4:98BE JSR call_jump_table
 
ROM4:98BF   .WORD dodongo_walk_state_0_walking ; Dodongo is walking around.
 
  ; Dodongo's turning is handled by the generic walking enemy handling (see change_direction). This
  ; just turns Dodongo to the right if he tries to walk into the wall, probably because the generic
  ; handling doesn't understand Dodongo's size.
ROM4:98C1   .WORD dodongo_walk_state_1_ate_bomb ; This state handler is called while Dodongo is stunned due
  ; to eating a bomb.
ROM4:98C3   .WORD dodongo_walk_state_2_stunned_by_bomb_explosion ; walk_state_and_weapon_state 2 is set after a bomb blew up
  ; near Dodongo. Stun for a while.
 
Subroutine dodongo_walk_state_0_walking
; Dodongo is walking around. ; ; Dodongo's turning is handled by the generic walking enemy handling (see change_direction). This ; just turns Dodongo to the right if he tries to walk into the wall, probably because the generic ; handling doesn't understand Dodongo's size.
ROM4:98C8 dodongo_walk_state_0_walking:
ROM4:98C8 LDY #0
ROM4:98C9 LDA object_direction,X
ROM4:98CA AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM4:98CB BEQ facing_left ; Branch if facing left.
ROM4:98CC LDA object_x,X ; Not facing left
ROM4:98CD CLC
ROM4:98CE ADC #$10
ROM4:98CF STA object_x,X
ROM4:98D0 LDY #$F0 ; Value to subtract from object_x to undo the above offset
 
ROM4:98D1 facing_left:
ROM4:98D1 TYA
ROM4:98D2 PHA ; Save Y (0 or 0xF0)
ROM4:98D3 LDA #$20
ROM4:98D4 STA enemy_projectile_speed_x,X ; Set Dodongo's walking speed to 0x20.
ROM4:98D5 JSR update_movement_or_fire_projectile_if_zero_timer
ROM4:98D6 PLA
ROM4:98D7 CLC
ROM4:98D8 ADC object_x,X ; Add 0 or 0xF0. This undoes the 0x10 offset applied above.
ROM4:98D9 STA object_x,X
ROM4:98DA CMP #$20 ; If Dodongo's X position is < 0x10 (X < 0x20 if facing left), turn around.
ROM4:98DB BCS ret
ROM4:98DC LDA #ControllerBits_Dpad_Right
ROM4:98DD STA object_direction,X
 
ROM4:98DE ret:
ROM4:98DE RTS
 
Subroutine dodongo_walk_state_2_stunned_by_bomb_explosion
; walk_state_and_weapon_state 2 is set after a bomb blew up ; near Dodongo. Stun for a while.
ROM4:98F2 dodongo_walk_state_2_stunned_by_bomb_explosion:
ROM4:98F2 LDY enemy_stun,X
ROM4:98F3 DEY
ROM4:98F4 BEQ dodongo_set_state_4_to_0_and_clear_weapon_state ; Reset state once stun wears off.
ROM4:98F5 BPL ret
ROM4:98F6 LDA #32
ROM4:98F7 STA enemy_stun,X ; Stun Dodongo for 32 frames.
 
ROM4:98F8 ret:
ROM4:98F8 RTS
 
Subroutine dodongo_walk_state_1_ate_bomb
; This state handler is called while Dodongo is stunned due ; to eating a bomb.
ROM4:9900 dodongo_walk_state_1_ate_bomb:
ROM4:9900 LDA enemy_state_4,X
ROM4:9901 JSR call_jump_table
 
ROM4:9902   .WORD dodongo_walk_state_1_state_0
ROM4:9904   .WORD dodongo_walk_state_1_state_0
ROM4:9906   .WORD dodongo_walk_state_1_state_0
ROM4:9908   .WORD dodongo_set_killed_and_play_sound
ROM4:990A   .WORD dodongo_set_state_4_to_0_and_clear_weapon_state
 
Subroutine dodongo_walk_state_1_state_0
ROM4:9910 dodongo_walk_state_1_state_0:
ROM4:9910 LDY enemy_state_2,X ; Number of frames to stay in this state
ROM4:9911 DEY
ROM4:9912 BEQ state_2_is_1 ; Branch if the enemy_state_2 timer has expired.
ROM4:9913 BPL decrement_state_2_and_return ; Branch if enemy_state_2 was >= 1.
ROM4:9914 LDY enemy_state_4,X ; enemy_state_2 was 0 and we just decremented it to 0xFF.
ROM4:9915 LDA frames_per_dodongo_state_4,Y ; Get the number of frames to stay in this state and
  ; store it in enemy_state_2.
ROM4:9916 STA enemy_state_2,X
ROM4:9917 CPY #0
ROM4:9918 BNE decrement_state_2_and_return ; Branch if enemy_state_4 != 0, which means this is the
  ; second or third time through this state after swallowing
  ; a bomb.
ROM4:9919 LDY #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
ROM4:991A LDA #0
ROM4:991B STA walk_state_and_weapon_state,Y ; Delete the bomb.
ROM4:991C LDA enemy_state_5,X ; Increment enemy_state_5. This is the number of times Dodongo
  ; has swallowed a bomb.
ROM4:991D CLC
ROM4:991E ADC #1
ROM4:991F STA enemy_state_5,X
ROM4:9920 JMP decrement_state_2_and_return ; Decrement enemy_state_2, which is the timer for this state.
 
ROM4:9921 state_2_is_1: ; Increase enemy_state_4, which advances this substate.
ROM4:9921 INC enemy_state_4,X
ROM4:9922 LDA enemy_state_4,X
ROM4:9923 CMP #2
ROM4:9924 BCC decrement_state_2_and_return ; If enemy_state_2 < 2, return. This state will repeat
  ; until we hit 2, with different timers selected from
  ; frames_per_dodongo_state_4.
ROM4:9925 LDY enemy_state_5,X ; If Dodongo has eaten two or more bombs, continue decrementing
  ; the state and allow it to continue into state 3, which is
  ; dodongo_set_killed_and_play_sound. Otherwise, switch
  ; enemy_state_4 to 4 to exit this stun state, so we don't
  ; kill it.
ROM4:9926 CPY #2
ROM4:9927 BCS decrement_state_2_and_return ; Decrement enemy_state_2, which is the timer for this state.
ROM4:9928 LDA #4
ROM4:9929 STA enemy_state_4,X ; Set to 4, which will reset to the moving state next frame.
 
ROM4:992A decrement_state_2_and_return: ; Decrement enemy_state_2, which is the timer for this state.
ROM4:992A DEC enemy_state_2,X
ROM4:992B RTS
 
Subroutine dodongo_set_killed_and_play_sound
ROM4:9952 dodongo_set_killed_and_play_sound:
ROM4:9952 JSR set_enemy_killed
ROM4:9953 JSR play_boss_sound_1
 
ROM4:9958 dodongo_set_state_4_to_0_and_clear_weapon_state: ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM4:9958 JSR clear_weapon_state
ROM4:9959 STA enemy_state_4,X ; Set to 0.
ROM4:995A RTS
 
Subroutine dodongo_check_hits_and_death
; Check if Dodongo hit Link, or if Link hit Dodongo for both ; tiles of Dodongo.
ROM4:995F dodongo_check_hits_and_death:
ROM4:995F JSR dodongo_check_hits_for_one_side ; Check if Dodongo hit Link, or if Link hit Dodongo.
ROM4:9960 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:9961 BNE dodongo_dead ; Branch if dead
ROM4:9962 LDA object_direction,X
ROM4:9963 CMP #ControllerBits_Dpad_Down
ROM4:9964 BCS locret_11989 ; If Dodongo is facing up or down, skip checking the right half.
ROM4:9965 LDA object_x,X ; Get Dodongo's X position
ROM4:9966 PHA ; Save Dodongo's X position.
ROM4:9967 CLC
ROM4:9968 ADC #$10
ROM4:9969 STA object_x,X ; Add a tile to Dodongo's X position to check hits on the right side.
ROM4:996A JSR dodongo_check_hits_for_one_side ; Check if Dodongo hit Link, or if Link hit Dodongo.
ROM4:996B PLA ; Restore Dodongo's real X position.
ROM4:996C STA object_x,X
ROM4:996D LDA invincibility_frames,X ; Skip if not in invincibility frames
ROM4:996E BEQ locret_11989 ; Branch if not dead
 
ROM4:996F dodongo_dead:
ROM4:996F JSR dodongo_set_killed_and_play_sound
ROM4:9970 LDA #10
ROM4:9971 STA consecutive_ten_kill_counter ; Force the consecutive counter to 10 after killing a Dodongo.
ROM4:9972 STA reached_ten_kills_with_last_bomb ; Force to 10 after killing a Dodongo.
 
ROM4:9989 locret_11989:
ROM4:9989 RTS
 
Subroutine dodongo_check_hits_for_one_side
; Check if Dodongo hit Link, or if Link hit Dodongo.
ROM4:998A dodongo_check_hits_for_one_side:
ROM4:998A LDA #DamageType_Sword|DamageType_Boomerang|DamageType_Arrow|DamageType_Bomb|DamageType_Rod|DamageType_Fire|DamageType_Unknown_40|DamageType_Unknown_80
ROM4:998B STA damage_types_with_no_knockback,X ; Set to 0xFF.
ROM4:998C JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:998D LDA walk_state_and_weapon_state,X ; Check if Dodongo is in state 2, which allows damage from the sword.
ROM4:998E CMP #2
ROM4:998F BNE locret_11989 ; Return if we're not in state 2.
ROM4:9990 LDA #$FE
ROM4:9991 STA damage_types_with_no_knockback,X ; Set to 0xFE (allow DamageType_Sword).
ROM4:9992 JSR set_position_for_hitbox_check ; Set var_2/var_3 to this object's X/Y position for hit checking.
ROM4:9993 LDY #AttackType_Sword
ROM4:9994 JMP check_attack_sword
 
ROM4:99A5 dodongo_second_check_bomb_distances_vertical: .BYTE $F0 ; Max second bomb distance up when Dodongo is facing right
ROM4:99A6   .BYTE 0 ; Max second bomb distance up when Dodongo is facing left
ROM4:99A7   .BYTE $F8 ; Max second bomb distance up when Dodongo is facing down
ROM4:99A8   .BYTE $FF ; (unused)
ROM4:99A9   .BYTE $F8 ; Max second bomb distance up when Dodongo is facing up
ROM4:99AA dodongo_second_check_bomb_distances_horizontal: .BYTE 0 ; Max second bomb distance down when Dodongo is facing right
ROM4:99AB   .BYTE $10 ; Max second bomb distance down when Dodongo is facing left
ROM4:99AC   .BYTE 8 ; Max second bomb distance down when Dodongo is facing down
ROM4:99AD   .BYTE $FF ; (unused)
ROM4:99AE   .BYTE 8 ; Max second bomb distance down when Dodongo is facing down
ROM4:99AF   .BYTE $FC ; Max second bomb distance right when Dodongo is facing right
ROM4:99B0   .BYTE $FC ; Max second bomb distance right when Dodongo is facing left
ROM4:99B1   .BYTE $F0 ; Max second bomb distance right when Dodongo is facing down
ROM4:99B2   .BYTE $FF ; (unused)
ROM4:99B3   .BYTE 0 ; Max second bomb distance right when Dodongo is facing up
ROM4:99B4   .BYTE 4 ; Max second bomb distance left when Dodongo is facing right
ROM4:99B5   .BYTE 4 ; Max second bomb distance left when Dodongo is facing left
ROM4:99B6   .BYTE 0 ; Max second bomb distance left when Dodongo is facing down
ROM4:99B7   .BYTE $FF ; (unused)
ROM4:99B8   .BYTE $10 ; Max second bomb distance left when Dodongo is facing up
 
Subroutine dodongo_check_nearby_bombs
ROM4:99B9 dodongo_check_nearby_bombs:
ROM4:99B9 LDA walk_state_and_weapon_state,X
ROM4:99BA BNE ret
ROM4:99BB LDA object_x,X ; A = Dodongo X position
ROM4:99BC CLC
ROM4:99BD ADC #8 ; A = Dodongo X position + 8
ROM4:99BE LDY object_direction,X
ROM4:99BF CPY #ControllerBits_Dpad_Down
ROM4:99C0 BCS vertical
ROM4:99C1 ADC #8 ; A = Dodongo X position + 16 if horizontal
 
ROM4:99C2 vertical:
ROM4:99C2 STA var_0
ROM4:99C3 LDA object_y,X
ROM4:99C4 ADC #8
ROM4:99C5 STA var_1 ; var_1 = Dodongo Y position + 8
ROM4:99C6 LDY #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
ROM4:99C7 LDA object_x,Y ; A = bomb X position
ROM4:99C8 ADC #8
ROM4:99C9 STA var_2 ; var_2 = bomb X position + 8
ROM4:99CA LDA object_y,Y
ROM4:99CB ADC #8
ROM4:99CC STA var_3 ; var_3 = bomb Y position + 8
ROM4:99CD LDA walk_state_and_weapon_state,Y
ROM4:99CE BEQ ret
ROM4:99CF CMP #BombOrFireState_BombDelay|BombOrFireState_Type_Bomb
ROM4:99D0 BEQ check_bombs_during_bomb_delay
ROM4:99D1 CMP #$20
ROM4:99D2 BCS ret
ROM4:99D3 LDY #0
ROM4:99D4 JSR dodongo_check_bomb_distance ; In Y: distance to check (0 for explosion radius, 1 for bomb delay radius)
  ; In var_0 = Dodongo X position
  ; In var_1 = Dodongo Y position
  ; In var_2 = Bomb X position
  ; In var_3 = Bomb Y position
  ; Out A: 0 if the bomb was close enough to Dodongo to hit
  ; Out var_4: X distance from Dodongo to bomb (if hit)
  ; Out var_5: Y distance from Dodongo to bomb (if hit)
ROM4:99D5 BNE ret
ROM4:99D6 LDA #2
ROM4:99D7 STA walk_state_and_weapon_state,X ; Set to 2 if a bomb goes off near Dodongo without him eating it.
 
ROM4:99D8 ret:
ROM4:99D8 RTS
 
ROM4:99D9 check_bombs_during_bomb_delay:
ROM4:99D9 LDY #1
ROM4:99DA JSR dodongo_check_bomb_distance ; In Y: distance to check (0 for explosion radius, 1 for bomb delay radius)
  ; In var_0 = Dodongo X position
  ; In var_1 = Dodongo Y position
  ; In var_2 = Bomb X position
  ; In var_3 = Bomb Y position
  ; Out A: 0 if the bomb was close enough to Dodongo to hit
  ; Out var_4: X distance from Dodongo to bomb (if hit)
  ; Out var_5: Y distance from Dodongo to bomb (if hit)
ROM4:99DB BNE ret2
ROM4:99DC LDA #1 ; The first bomb distance check passed. This seems to do a second bomb
  ; distance check.
ROM4:99DD STA var_0 ; Set to 1 to loop 1 and 0
ROM4:99DE LDA object_direction,X ; Set A to Dodongo's direction mask
ROM4:99DF LSR A ; Set A to 0 if Dodongo is right, 1 if left, 2 if down, 4 if up
ROM4:99E0 TAY ; Y = A (0 or 1)
ROM4:99E1 LDA var_4 ; Load X distance from Dodongo to bomb
 
ROM4:99E2 loop:
ROM4:99E2 CMP dodongo_second_check_bomb_distances_vertical,Y
ROM4:99E3 BMI ret2
ROM4:99E4 CMP dodongo_second_check_bomb_distances_horizontal,Y
ROM4:99E5 BPL ret2
ROM4:99E6 TYA
ROM4:99E7 CLC
ROM4:99E8 ADC #$A
ROM4:99E9 TAY
ROM4:99EA LDA var_5 ; Load Y distance from Dodongo to bomb for the next loop
ROM4:99EB DEC var_0
ROM4:99EC BPL loop
ROM4:99ED INC walk_state_and_weapon_state,X ; Set to 1 after eating a bomb.
ROM4:99EE LDY #$10
ROM4:99EF LDA #0
ROM4:99F0 STA walk_state_and_weapon_state,Y ; Delete the bomb.
ROM4:99F1 STA enemy_state_4,X ; Set to 0
 
ROM4:99F2 ret2:
ROM4:99F2 RTS
 
ROM4:9A2E dodongo_bomb_max_distance_left: .BYTE $C
ROM4:9A2F   .BYTE $11
ROM4:9A30 dodongo_bomb_max_distance_right: .BYTE $F4
ROM4:9A31   .BYTE $F0
 
Subroutine dodongo_check_bomb_distance
; In Y: distance to check (0 for explosion radius, 1 for bomb delay radius) ; In var_0 = Dodongo X position ; In var_1 = Dodongo Y position ; In var_2 = Bomb X position ; In var_3 = Bomb Y position ; Out A: 0 if the bomb was close enough to Dodongo to hit ; Out var_4: X distance from Dodongo to bomb (if hit) ; Out var_5: Y distance from Dodongo to bomb (if hit)
ROM4:9A32 dodongo_check_bomb_distance:
ROM4:9A32 LDA dodongo_bomb_max_distance_left,Y
ROM4:9A33 STA var_6
ROM4:9A34 LDA dodongo_bomb_max_distance_right,Y
ROM4:9A35 STA var_7
ROM4:9A36 LDA #3
ROM4:9A37 STA var_8 ; Set to 3.
ROM4:9A38 LDY #1 ; Loop Y = 1 and 0 (Y and X).
 
ROM4:9A39 loop:
ROM4:9A39 LDA var_0,Y
ROM4:9A3A SEC
ROM4:9A3B SBC var_2,Y
ROM4:9A3C CMP var_6
ROM4:9A3D BPL too_far ; Branch if Dodongo X - Bomb X > var_6
ROM4:9A3E CMP var_7
ROM4:9A3F BMI too_far ; Branch if Dodongo Y - Bomb Y < var_7
ROM4:9A40 STA var_4,Y
ROM4:9A41 LSR var_8 ; Shift a bit out of var_8.
 
ROM4:9A42 too_far:
ROM4:9A42 DEY
ROM4:9A43 BPL loop
ROM4:9A44 LDA var_8 ; We're close enough on both axes if var_8 is 0.
ROM4:9A45 RTS
 
ROM4:9A5C byte_11A5C: .BYTE 0
ROM4:9A5D   .BYTE 1
ROM4:9A5E   .BYTE 6
ROM4:9A5F   .BYTE $FF
ROM4:9A60   .BYTE 8
ROM4:9A61   .BYTE 2
ROM4:9A62   .BYTE 3
ROM4:9A63   .BYTE 6
ROM4:9A64   .BYTE $FF
ROM4:9A65   .BYTE 8
ROM4:9A66 byte_11A66: .BYTE 0
ROM4:9A67   .BYTE $40
ROM4:9A68   .BYTE 0
ROM4:9A69   .BYTE $FF
ROM4:9A6A   .BYTE 0
ROM4:9A6B   .BYTE 0
ROM4:9A6C   .BYTE $40
ROM4:9A6D   .BYTE $40
ROM4:9A6E   .BYTE $FF
ROM4:9A6F   .BYTE $40
ROM4:9A70   .BYTE 4
ROM4:9A71   .BYTE 5
ROM4:9A72   .BYTE 7
ROM4:9A73   .BYTE $FF
ROM4:9A74   .BYTE 9
ROM4:9A75   .BYTE 4
ROM4:9A76   .BYTE 5
ROM4:9A77   .BYTE 7
ROM4:9A78   .BYTE $FF
ROM4:9A79   .BYTE 9
ROM4:9A7A   .BYTE 0
ROM4:9A7B   .BYTE $40
ROM4:9A7C   .BYTE 0
ROM4:9A7D   .BYTE $FF
ROM4:9A7E   .BYTE 0
ROM4:9A7F   .BYTE 0
ROM4:9A80   .BYTE $40
ROM4:9A81   .BYTE 0
ROM4:9A82   .BYTE $FF
ROM4:9A83   .BYTE 0
 
Subroutine dodongo_update_sprites
ROM4:9A84 dodongo_update_sprites:
ROM4:9A84 JSR set_tile_attributes_to_palette_3
ROM4:9A85 LDA object_direction,X
ROM4:9A86 LSR A
ROM4:9A87 STA var_0
ROM4:9A88 LDY walk_state_and_weapon_state,X
ROM4:9A89 BEQ loc_11AB6
ROM4:9A8A LDA #$20
ROM4:9A8B DEY
ROM4:9A8C BNE loc_11AB8
ROM4:9A8D LDY enemy_state_4,X
ROM4:9A8E BEQ loc_11AB6
ROM4:9A8F CPY #2
ROM4:9A90 BEQ loc_11AAB
ROM4:9A91 CPY #3
ROM4:9A92 BEQ loc_11AAB
ROM4:9A93 LDA var_0
ROM4:9A94 CLC
ROM4:9A95 ADC #$14
ROM4:9A96 TAY
ROM4:9A97 JMP loc_11AC3
 
ROM4:9AAB loc_11AAB:
ROM4:9AAB LDA frame_counter
ROM4:9AAC AND #2
ROM4:9AAD BEQ locret_11B00 ; Return if the frame count & 0x02 == 0.
ROM4:9AAE LDY var_0
ROM4:9AAF JMP loc_11AC3
 
ROM4:9AB6 loc_11AB6:
ROM4:9AB6 LDA #8
 
ROM4:9AB8 loc_11AB8:
ROM4:9AB8 LDY var_0
ROM4:9AB9 AND frame_counter
ROM4:9ABA BEQ loc_11AC3
ROM4:9ABB TYA
ROM4:9ABC CLC
ROM4:9ABD ADC #5
ROM4:9ABE TAY
 
ROM4:9AC3 loc_11AC3: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:9AC3 JSR set_var_0_to_object_position
ROM4:9AC4 TYA
ROM4:9AC5 PHA
ROM4:9AC6 LDA byte_11A66,Y
ROM4:9AC7 STA var_15
ROM4:9AC8 LDA byte_11A5C,Y
ROM4:9AC9 CMP #7
ROM4:9ACA BEQ update_sprite_vertical
ROM4:9ACB CMP #9
ROM4:9ACC BNE update_sprite_horizontal
 
ROM4:9ACD update_sprite_vertical:
ROM4:9ACD JSR update_object_sprite_vertical
ROM4:9ACE JMP continue_after_updating_sprite
 
ROM4:9ACF update_sprite_horizontal:
ROM4:9ACF JSR update_object_sprite_horizontal
 
ROM4:9AD0 continue_after_updating_sprite:
ROM4:9AD0 PLA
ROM4:9AD1 TAY
ROM4:9AD2 LDA object_direction,X
ROM4:9AD3 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:9AD4 BEQ locret_11B00 ; Return if vertical.
ROM4:9AD5 LDA object_x,X
ROM4:9AD6 CLC
ROM4:9AD7 ADC #$10
ROM4:9AD8 STA var_0 ; var_0 = Dodongo X + 0x10
ROM4:9AD9 JSR set_tile_attributes_to_palette_3
ROM4:9ADA LDA byte_11A5C,Y
ROM4:9ADB EOR #1
ROM4:9ADC JMP update_object_sprite_horizontal
 
Subroutine set_tile_attributes_to_palette_3
ROM4:9AFB set_tile_attributes_to_palette_3:
ROM4:9AFB LDA #OAMAttributes_Palette_3
ROM4:9AFC JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
 
ROM4:9B00 locret_11B00:
ROM4:9B00 RTS
 
ROM4:9B01 Skipped empty chunk
Subroutine spawn_darknut
ROM4:9B20 spawn_darknut:
ROM4:9B20 LDA #$F6
ROM4:9B21 STA damage_types_with_no_knockback,X ; Set to 0xF6.
ROM4:9B22 LDA #$20 ; Red darknut speed
ROM4:9B23 LDY object_type,X ; check if ObjectType_RedDarknut
ROM4:9B24 CPY #ObjectType_RedDarknut
ROM4:9B25 BEQ red_darknut
ROM4:9B26 LDA #$28 ; Blue darknut speed
 
ROM4:9B27 red_darknut:
ROM4:9B27 STA object_walk_speed,X
ROM4:9B28 JMP spawn_monster_basic
  ; This is the common setup for most monsters. It just picks
  ; an initial walking direction, based on the enemy's spawn
  ; position and the player seek position (enemy_behavior_seek_x,
  ; enemy_behavior_seek_y).
 
Subroutine update_monster_gibdo
ROM4:9B36 update_monster_gibdo:
ROM4:9B36 LDA #$80 ; Gibdo speed
ROM4:9B37 JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:9B38 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9B39 LDA #8
ROM4:9B3A JSR update_object_animation_frame
ROM4:9B3B JSR store_animation_frame
ROM4:9B3C LDA #0
ROM4:9B3D JMP update_object_sprite_horizontal
 
Subroutine update_monster_darknut
ROM4:9B4B update_monster_darknut:
ROM4:9B4B LDA #$80 ; Darknut walking speed
ROM4:9B4C JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:9B4D JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9B4E LDA #0
ROM4:9B4F STA enemy_stun,X ; Clear stun. Darknuts don't have hit stun.
ROM4:9B50 LDA #8
ROM4:9B51 JSR update_object_animation_frame
ROM4:9B52 LDA object_direction,X
ROM4:9B53 CMP #ControllerBits_Dpad_Left
ROM4:9B54 BNE left
ROM4:9B55 INC var_15 ; Flip the sprite horizontally when facing right.
 
ROM4:9B56 left:
ROM4:9B56 LSR A
ROM4:9B57 LSR A
ROM4:9B58 LDY object_animation_frame,X
ROM4:9B59 BEQ loc_11B76
ROM4:9B5A CLC
ROM4:9B5B ADC #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:9B5C LDY object_direction,X
ROM4:9B5D CPY #ControllerBits_Dpad_Up
ROM4:9B5E BNE loc_11B76
ROM4:9B5F INC var_15
 
ROM4:9B76 loc_11B76:
ROM4:9B76 JSR update_object_sprite_horizontal
ROM4:9B77 RTS
 
ROM4:9B7A byte_11B7A: .BYTE 1
ROM4:9B7B   .BYTE $FF
ROM4:9B7C   .BYTE 0
ROM4:9B7D   .BYTE 0
ROM4:9B7E   .BYTE 1
ROM4:9B7F   .BYTE $FF
ROM4:9B80   .BYTE 0
ROM4:9B81   .BYTE 0
ROM4:9B82   .BYTE 1
ROM4:9B83   .BYTE $FF
ROM4:9B84 byte_11B84: .BYTE 0
ROM4:9B85   .BYTE 0
ROM4:9B86   .BYTE 0
ROM4:9B87   .BYTE 1
ROM4:9B88   .BYTE 1
ROM4:9B89   .BYTE 1
ROM4:9B8A   .BYTE 0
ROM4:9B8B   .BYTE $FF
ROM4:9B8C   .BYTE $FF
ROM4:9B8D   .BYTE $FF
ROM4:9B8E byte_11B8E: .BYTE $FD
ROM4:9B8F   .BYTE $FD
ROM4:9B90   .BYTE $FF
ROM4:9B91   .BYTE $FF
ROM4:9B92   .BYTE $FF
ROM4:9B93   .BYTE $FF
ROM4:9B94   .BYTE $FF
ROM4:9B95   .BYTE $FC
ROM4:9B96 byte_11B96: .BYTE 0
ROM4:9B97   .BYTE 0
ROM4:9B98   .BYTE $20
ROM4:9B99   .BYTE $20
ROM4:9B9A   .BYTE $20
ROM4:9B9B   .BYTE $20
ROM4:9B9C   .BYTE $20
ROM4:9B9D   .BYTE $E0
ROM4:9B9E byte_11B9E: .BYTE 1
ROM4:9B9F   .BYTE 2
ROM4:9BA0   .BYTE 4
ROM4:9BA1   .BYTE 8
 
Subroutine update_monster_pols_voice
ROM4:9BA2 update_monster_pols_voice:
ROM4:9BA2 CPX #1
ROM4:9BA3 BNE dummy ; No-op?
 
ROM4:9BA4 dummy:
ROM4:9BA4 LDA clock_active
ROM4:9BA5 ORA enemy_stun,X
ROM4:9BA6 BNE loc_11BFA ; Skip update if stunned or the clock is active
ROM4:9BA7 LDA frame_counter
ROM4:9BA8 LSR A
ROM4:9BA9 BCS loc_11C26
ROM4:9BAA JSR update_monster_pols_voice_0
ROM4:9BAB LDA walk_state_and_weapon_state,X
ROM4:9BAC BEQ loc_11BBF
ROM4:9BAD JSR update_monster_pols_voice_1
ROM4:9BAE JMP loc_11BCF
 
ROM4:9BBF loc_11BBF:
ROM4:9BBF LDA object_tile_offset_whole,X
ROM4:9BC0 BEQ loc_11BFD
ROM4:9BC1 DEC object_tile_offset_whole,X
ROM4:9BC2 LDA object_y,X
ROM4:9BC3 CLC
ROM4:9BC4 ADC byte_11B84,Y
ROM4:9BC5 STA object_y,X
 
ROM4:9BCF loc_11BCF:
ROM4:9BCF JSR update_monster_pols_voice_2
ROM4:9BD0 BCC loc_11BFA
ROM4:9BD1 LDA enemy_projectile_speed_x,X
ROM4:9BD2 AND #$FC
ROM4:9BD3 CMP #$B0
ROM4:9BD4 BEQ loc_11BFD
ROM4:9BD5 CMP #$F4
ROM4:9BD6 BCS loc_11BFD
ROM4:9BD7 LDA object_direction,X
ROM4:9BD8 AND #3
ROM4:9BD9 BNE loc_11BF0
ROM4:9BDA LDA object_direction,X
ROM4:9BDB EOR #$C
ROM4:9BDC STA object_direction,X
ROM4:9BDD JMP loc_11C26
 
ROM4:9BF0 loc_11BF0:
ROM4:9BF0 EOR #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:9BF1 STA object_direction,X
ROM4:9BF2 JSR update_monster_pols_voice_0
ROM4:9BF3 JSR update_monster_pols_voice_0
 
ROM4:9BFA loc_11BFA:
ROM4:9BFA JMP loc_11C26
 
ROM4:9BFD loc_11BFD:
ROM4:9BFD LDA walk_state_and_weapon_state,X
ROM4:9BFE BNE loc_11C26
ROM4:9BFF INC walk_state_and_weapon_state,X
ROM4:9C00 LDY object_direction,X
ROM4:9C01 DEY
ROM4:9C02 LDA object_y,X
ROM4:9C03 CMP #$78
ROM4:9C04 BCS loc_11C0E
ROM4:9C05 LDY #3
 
ROM4:9C0E loc_11C0E:
ROM4:9C0E CMP #$A8
ROM4:9C0F BCC loc_11C14
ROM4:9C10 LDY #7
 
ROM4:9C14 loc_11C14:
ROM4:9C14 LDA byte_11B8E,Y
ROM4:9C15 STA enemy_state_0,X
ROM4:9C16 LDA object_y,X
ROM4:9C17 CLC
ROM4:9C18 ADC byte_11B96,Y
ROM4:9C19 STA enemy_state_4,X
ROM4:9C1A INY
ROM4:9C1B STY object_direction,X
 
ROM4:9C26 loc_11C26:
ROM4:9C26 LDA #8
ROM4:9C27 JSR update_object_animation_frame
ROM4:9C28 LDA object_animation_frame,X
ROM4:9C29 JSR update_object_sprite_vertical
ROM4:9C2A LDA #$FE
ROM4:9C2B STA damage_types_with_no_knockback,X ; Set to 0xFE.
ROM4:9C2C JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9C2D RTS
 
Subroutine update_monster_pols_voice_1
ROM4:9C3A update_monster_pols_voice_1:
ROM4:9C3A LDA enemy_state_6,X
ROM4:9C3B CLC
ROM4:9C3C ADC #$38
ROM4:9C3D STA enemy_state_6,X
ROM4:9C3E LDA enemy_state_0,X
ROM4:9C3F ADC #0
ROM4:9C40 STA enemy_state_0,X
ROM4:9C41 CLC
ROM4:9C42 ADC object_y,X
ROM4:9C43 STA object_y,X
ROM4:9C44 LDA enemy_state_0,X
ROM4:9C45 BMI locret_11C8E
ROM4:9C46 LDA object_y,X
ROM4:9C47 CMP enemy_state_4,X
ROM4:9C48 BCC locret_11C8E
ROM4:9C49 LDA #0
ROM4:9C4A STA walk_state_and_weapon_state,X
ROM4:9C4B STA enemy_state_6,X
ROM4:9C4C STA enemy_state_0,X
ROM4:9C4D LDA prng_0,X
ROM4:9C4E AND #3
ROM4:9C4F TAY
ROM4:9C50 LDA byte_11B9E,Y
ROM4:9C51 STA object_direction,X
ROM4:9C52 LDA prng_0,X
ROM4:9C53 AND #$40
ROM4:9C54 ADC #$30
ROM4:9C55 STA object_tile_offset_whole,X
ROM4:9C56 LDA object_x,X
ROM4:9C57 CLC
ROM4:9C58 ADC #8
ROM4:9C59 AND #$F0
ROM4:9C5A STA object_x,X
ROM4:9C5B LDA object_y,X
ROM4:9C5C CLC
ROM4:9C5D ADC #8
ROM4:9C5E AND #$F0
ROM4:9C5F SEC
ROM4:9C60 SBC #3
ROM4:9C61 STA object_y,X
 
ROM4:9C8E locret_11C8E:
ROM4:9C8E RTS
 
Subroutine update_monster_pols_voice_2
ROM4:9C8F update_monster_pols_voice_2:
ROM4:9C8F JSR update_monster_pols_voice_3
ROM4:9C90 BCS locret_11CAD
ROM4:9C91 LDA object_x,X
ROM4:9C92 PHA
ROM4:9C93 CLC
ROM4:9C94 ADC #$E
ROM4:9C95 STA object_x,X
ROM4:9C96 LDA object_y,X
ROM4:9C97 PHA
ROM4:9C98 CLC
ROM4:9C99 ADC #6
ROM4:9C9A STA object_y,X
ROM4:9C9B JSR update_monster_pols_voice_3
ROM4:9C9C PLA
ROM4:9C9D STA object_y,X
ROM4:9C9E PLA
ROM4:9C9F STA object_x,X
 
ROM4:9CAD locret_11CAD:
ROM4:9CAD RTS
 
Subroutine update_monster_pols_voice_3
ROM4:9CAE update_monster_pols_voice_3:
ROM4:9CAE LDY #0
ROM4:9CAF JSR set_tile_walking_onto_3
ROM4:9CB0 LDA tile_walking_onto,X
ROM4:9CB1 CMP screen_first_solid_tile_id
ROM4:9CB2 STA enemy_projectile_speed_x,X
ROM4:9CB3 RTS
 
Subroutine update_monster_pols_voice_0
ROM4:9CBD update_monster_pols_voice_0:
ROM4:9CBD LDY object_direction,X
ROM4:9CBE DEY
ROM4:9CBF LDA object_x,X
ROM4:9CC0 CLC
ROM4:9CC1 ADC byte_11B7A,Y
ROM4:9CC2 STA object_x,X
ROM4:9CC3 RTS
 
Subroutine update_monster_like_like
ROM4:9CC9 update_monster_like_like:
ROM4:9CC9 LDA enemy_state_4,X
ROM4:9CCA BNE like_like_holding_link
ROM4:9CCB LDA #$80 ; Like like movement speed
ROM4:9CCC JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:9CCD DEC object_animation_frame_timer,X
ROM4:9CCE BNE animation_frame_timer_not_expired
ROM4:9CCF LDA #8
ROM4:9CD0 STA object_animation_frame_timer,X ; Eight frames per animation frame
ROM4:9CD1 LDY object_animation_frame,X ; Increase the like like's animation frame
ROM4:9CD2 INY
ROM4:9CD3 TYA
ROM4:9CD4 AND #3 ; Four animation frames
ROM4:9CD5 STA object_animation_frame,X ; Save the like like's new animation frame
 
ROM4:9CD6 animation_frame_timer_not_expired: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:9CD6 JSR set_var_0_to_object_position
ROM4:9CD7 LDA object_animation_frame,X
ROM4:9CD8 JSR update_object_sprite_vertical
ROM4:9CD9 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9CDA LDA enemy_state_4,X
ROM4:9CDB BEQ ret
ROM4:9CDC LDA object_x ; When a like like hits Link, snap the like like to Link's position.
ROM4:9CDD STA object_x,X
ROM4:9CDE LDA object_y
ROM4:9CDF STA object_y,X
ROM4:9CE0 LDA #0
ROM4:9CE1 STA enemy_action_timers ; Set to 0
ROM4:9CE2 STA enemy_spawn_state ; Set to 0
ROM4:9CE3 STA object_knockback ; Clear Link's knockback.
ROM4:9CE4 STA knockback_frames ; Set to 0
ROM4:9CE5 STA object_animation_frame,X ; Set to 0
ROM4:9CE6 LDA #4
ROM4:9CE7 STA object_animation_frame_timer,X
ROM4:9CE8 INC held_by_like_like ; Remember that Link is held by a like like.
 
ROM4:9CE9 ret:
ROM4:9CE9 RTS
 
ROM4:9CEA like_like_holding_link:
ROM4:9CEA LDA #2
ROM4:9CEB CMP object_animation_frame,X
ROM4:9CEC BCC no_animation_frame_change ; Animation frame < 2
ROM4:9CED DEC object_animation_frame_timer,X
ROM4:9CEE BNE no_animation_frame_change ; Branch if the animation timer hasn't expired
ROM4:9CEF ASL A ; A = 4
ROM4:9CF0 STA object_animation_frame_timer,X ; 4 frames per animation frame while holding Link
ROM4:9CF1 INC object_animation_frame,X ; Increase the like like's animation frame while holding Link
 
ROM4:9CF2 no_animation_frame_change: ; This state is the number of frames Link has been held
ROM4:9CF2 INC enemy_state_4,X
ROM4:9CF3 LDA enemy_state_4,X
ROM4:9CF4 CMP #96
ROM4:9CF5 BCC not_stealing_shield_yet
ROM4:9CF6 LDA #0
ROM4:9CF7 STA have_magic_shield ; Like like steals shield after 96 frames
ROM4:9CF8 LDA #192 ; Lock the frame counter. This is probably so it doesn't wrap at 0xFF.
ROM4:9CF9 STA enemy_state_4,X
 
ROM4:9CFA not_stealing_shield_yet: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:9CFA JSR set_var_0_to_object_position
ROM4:9CFB LDA object_animation_frame,X
ROM4:9CFC JSR update_sprite_like_like
ROM4:9CFD JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9CFE LDA enemy_spawn_state,X ; Check if the like like has been killed.
ROM4:9CFF BEQ ret
ROM4:9D00 LDA #0
ROM4:9D01 STA held_by_like_like ; Set to 0 after killing the like like holding Link.
ROM4:9D02 JMP remove_like_like_or_wall_master_holding_link_sprite
 
Subroutine update_monster_vire
ROM4:9D57 update_monster_vire:
 
ROM4:9D57 JSR call_vire_state_engine
ROM4:9D58 LDA walk_state_and_weapon_state,X
ROM4:9D59 CMP #2
ROM4:9D5A BCS spawn_keese
ROM4:9D5B JSR update_monster_vire_main
ROM4:9D5C JMP update_monster_vire_sprite
 
ROM4:9D5D spawn_keese:
ROM4:9D5D INC total_enemies_spawned_in_room
ROM4:9D5E JSR delete_enemy ; X = object slot
ROM4:9D5F LDY #1 ; Spawn two keese when a Vire is killed.
 
ROM4:9D60 spawn_keese_loop:
ROM4:9D60 TYA
ROM4:9D61 PHA ; Push the loop index.
ROM4:9D62 JSR find_last_available_object_idx ; Result is returned in tmp_result.
ROM4:9D63 BEQ no_object_slots_available
ROM4:9D64 LDA #ObjectType_RedKeese
ROM4:9D65 STA var_0 ; Store the object type to spawn from dead Vires.
ROM4:9D66 JSR create_object_at_another_object_with_slot ; Create ObjectType_RedKeese.
 
ROM4:9D67 no_object_slots_available: ; Pop the loop index.
ROM4:9D67 PLA
ROM4:9D68 TAY
ROM4:9D69 DEY
ROM4:9D6A BPL spawn_keese_loop
ROM4:9D6B RTS
 
ROM4:9D6C call_vire_state_engine: ; This will never be called when in state 2, since the
ROM4:9D6C LDA walk_state_and_weapon_state,X ; Vire is despawned by spawn_keese after setting that state.
ROM4:9D6D JSR call_jump_table
 
ROM4:9D6E   .WORD update_monster_vire_normal
ROM4:9D70   .WORD update_monster_vire_zol_1
 
ROM4:9D8B vire_y_movement_speed: .BYTE 0
ROM4:9D8C   .BYTE $FD ; -3
ROM4:9D8D   .BYTE $FE ; -2
ROM4:9D8E   .BYTE $FF ; -1
ROM4:9D8F   .BYTE $FF ; -1
ROM4:9D90   .BYTE 0
ROM4:9D91   .BYTE $FF ; -1
ROM4:9D92   .BYTE 0
ROM4:9D93   .BYTE 0
ROM4:9D94   .BYTE 1
ROM4:9D95   .BYTE 0
ROM4:9D96   .BYTE 1
ROM4:9D97   .BYTE 1
ROM4:9D98   .BYTE 2
ROM4:9D99   .BYTE 3
ROM4:9D9A   .BYTE 0
 
Subroutine update_monster_vire_normal
ROM4:9D9B update_monster_vire_normal:
ROM4:9D9B LDA #$80
ROM4:9D9C JSR store_speed_and_update_movement ; On entry, A is the current enemy's walking speed.
ROM4:9D9D LDA clock_active
ROM4:9D9E ORA enemy_stun,X
ROM4:9D9F BNE ret ; Stop if stunned or the clock is active.
ROM4:9DA0 LDA object_direction,X
ROM4:9DA1 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM4:9DA2 BEQ ret ; Stop if not moving left or right.
ROM4:9DA3 LDA object_tile_offset_whole,X
ROM4:9DA4 JSR absolute_value ; A = abs(A)
ROM4:9DA5 TAY
ROM4:9DA6 LDA object_y,X
ROM4:9DA7 CLC
ROM4:9DA8 ADC vire_y_movement_speed,Y ; Move the Vire on Y depending on its offset from the tile on X.
ROM4:9DA9 STA object_y,X
 
ROM4:9DAA ret:
ROM4:9DAA RTS
 
Subroutine update_monster_vire_main
ROM4:9DBD update_monster_vire_main:
ROM4:9DBD LDA walk_state_and_weapon_state,X
ROM4:9DBE BNE ret ; Stop if not in state 0
ROM4:9DBF JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:9DC0 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:9DC1 BNE ret ; Stop if dead
ROM4:9DC2 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:9DC3 BEQ ret
ROM4:9DC4 INC walk_state_and_weapon_state,X ; Switch to state 1
 
ROM4:9DC5 ret:
ROM4:9DC5 RTS
 
Function chunk for update_monster_vire
ROM4:9DC6 update_monster_vire_sprite:
ROM4:9DC6 LDA #$A
ROM4:9DC7 JSR update_object_animation_frame
ROM4:9DC8 LDA object_direction,X ; Update the Vire's animation frame.
ROM4:9DC9 AND #ControllerBits_Dpad_Up
ROM4:9DCA LSR A
ROM4:9DCB LSR A
ROM4:9DCC CLC
ROM4:9DCD ADC object_animation_frame,X
ROM4:9DCE JMP update_object_sprite_vertical
 
Subroutine update_monster_wizzrobe_blue
ROM4:9DE3 update_monster_wizzrobe_blue:
ROM4:9DE3 LDA clock_active
ROM4:9DE4 BNE ret ; Stop if the clock is active. Wizzrobes don't have hit stun.
ROM4:9DE5 JSR update_monster_wizzrobe_blue_0
ROM4:9DE6 JSR update_monster_wizzrobe_blue_1
 
ROM4:9DEE update_monster_wizzrobe_shared_red_blue: ; This is called by both blue and red wizzrobes.
ROM4:9DEE LDA object_tile_offset_whole,X
ROM4:9DEF LSR A
ROM4:9DF0 BCS locret_11E17
 
ROM4:9DF1 ret:
ROM4:9DF1 JMP loc_12040
 
Subroutine update_monster_wizzrobe_blue_0
ROM4:9DF7 update_monster_wizzrobe_blue_0:
ROM4:9DF7 LDA enemy_action_timers,X
ROM4:9DF8 BNE action_timer_not_expired
ROM4:9DF9 LDA object_tile_offset_whole,X ; The action timer has expired.
ROM4:9DFA BEQ on_tile
ROM4:9DFB DEC object_tile_offset_whole,X
ROM4:9DFC JMP loc_11E20
 
ROM4:9DFD on_tile:
ROM4:9DFD JSR loc_11EFC
ROM4:9DFE JMP loc_11E62
 
ROM4:9DFF action_timer_not_expired:
ROM4:9DFF CMP #16
ROM4:9E00 BCS action_timer_gte_16 ; Check if the action timer is >= 16 frames.
ROM4:9E01 CMP #1
ROM4:9E02 BNE locret_11E17 ; Check if the action timer is at 1 frame.
ROM4:9E03 JSR blue_wizzrobe_action_timer_at_1_frame
 
ROM4:9E17 locret_11E17:
ROM4:9E17 RTS
 
ROM4:9E18 action_timer_gte_16:
ROM4:9E18 LDA frame_counter
ROM4:9E19 LSR A
ROM4:9E1A BCS action_timer_gte_16_odd ; The action timer is >= 16 frames. Branch if the main frame counter is odd.
 
ROM4:9E1D update_from_ganon:
ROM4:9E1D JSR sub_11E58
 
ROM4:9E20 loc_11E20:
ROM4:9E20 JSR sub_11E9D
ROM4:9E21 JSR sub_11F2C
ROM4:9E22 BCC locret_11E57
ROM4:9E23 LDA enemy_projectile_speed_x,X
ROM4:9E24 AND #$FC
ROM4:9E25 CMP #$B0
ROM4:9E26 BEQ loc_11E35
ROM4:9E27 CMP #$F4
ROM4:9E28 BCC loc_11E3D
 
ROM4:9E35 loc_11E35:
ROM4:9E35 LDA object_tile_offset_whole,X
ROM4:9E36 BNE locret_11E17
ROM4:9E37 JMP loc_11EEB
 
ROM4:9E3D loc_11E3D:
ROM4:9E3D LDY object_direction,X
ROM4:9E3E TYA
ROM4:9E3F AND #$C
ROM4:9E40 BEQ loc_11E4A
ROM4:9E41 TYA
ROM4:9E42 EOR #$C
ROM4:9E43 STA object_direction,X
ROM4:9E44 TAY
 
ROM4:9E4A loc_11E4A:
ROM4:9E4A TYA
ROM4:9E4B AND #3
ROM4:9E4C BEQ loc_11E54
ROM4:9E4D TYA
ROM4:9E4E EOR #3
ROM4:9E4F STA object_direction,X
 
ROM4:9E54 loc_11E54:
ROM4:9E54 JMP sub_11E9D
 
ROM4:9E57 locret_11E57:
ROM4:9E57 RTS
 
Subroutine sub_11E58
ROM4:9E58 sub_11E58:
ROM4:9E58 INC enemy_state_0,X
 
ROM4:9E5B action_timer_gte_16_odd:
ROM4:9E5B LDA enemy_state_0,X
ROM4:9E5C AND #$3F
ROM4:9E5D BNE locret_11EAF
 
ROM4:9E62 loc_11E62:
ROM4:9E62 LDA enemy_state_0,X
ROM4:9E63 AND #$40
ROM4:9E64 BNE loc_11E75
ROM4:9E65 LDA #2
ROM4:9E66 LDY object_x,X
ROM4:9E67 CPY $70
ROM4:9E68 BCS loc_11E72
ROM4:9E69 LSR A
 
ROM4:9E72 loc_11E72:
ROM4:9E72 JMP loc_11E7E
 
ROM4:9E75 loc_11E75:
ROM4:9E75 LDA #8
ROM4:9E76 LDY object_y,X
ROM4:9E77 CPY object_y
ROM4:9E78 BCS loc_11E7E
ROM4:9E79 LSR A
 
ROM4:9E7E loc_11E7E:
ROM4:9E7E CMP object_direction,X
ROM4:9E7F BEQ locret_11EAF
ROM4:9E80 STA object_direction,X
ROM4:9E81 JMP loc_11F02
 
ROM4:9E87 byte_11E87: .BYTE 0
ROM4:9E88   .BYTE 1
ROM4:9E89   .BYTE $FF
ROM4:9E8A   .BYTE 0
ROM4:9E8B   .BYTE 0
ROM4:9E8C   .BYTE 1
ROM4:9E8D   .BYTE $FF
ROM4:9E8E   .BYTE 0
ROM4:9E8F   .BYTE 0
ROM4:9E90   .BYTE 1
ROM4:9E91   .BYTE $FF
ROM4:9E92 byte_11E92: .BYTE 0
ROM4:9E93   .BYTE 0
ROM4:9E94   .BYTE 0
ROM4:9E95   .BYTE 0
ROM4:9E96   .BYTE 1
ROM4:9E97   .BYTE 1
ROM4:9E98   .BYTE 1
ROM4:9E99   .BYTE 0
ROM4:9E9A   .BYTE $FF
ROM4:9E9B   .BYTE $FF
ROM4:9E9C   .BYTE $FF
 
Subroutine sub_11E9D
ROM4:9E9D sub_11E9D:
ROM4:9E9D LDY object_direction,X
ROM4:9E9E LDA object_x,X
ROM4:9E9F CLC
ROM4:9EA0 ADC byte_11E87,Y
ROM4:9EA1 STA object_x,X
ROM4:9EA2 LDA object_y,X
ROM4:9EA3 CLC
ROM4:9EA4 ADC byte_11E92,Y
ROM4:9EA5 STA object_y,X
 
ROM4:9EAF locret_11EAF:
ROM4:9EAF RTS
 
ROM4:9EB0 blue_wizzrobe_hidden_x_movement: .BYTE $E0
ROM4:9EB1   .BYTE $20
ROM4:9EB2   .BYTE $E0
ROM4:9EB3   .BYTE $20
ROM4:9EB4 blue_wizzrobe_hidden_y_movement: .BYTE $E0
ROM4:9EB5   .BYTE $E0
ROM4:9EB6   .BYTE $20
ROM4:9EB7   .BYTE $20
ROM4:9EB8 byte_11EB8: .BYTE ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
ROM4:9EB9   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Up
ROM4:9EBA   .BYTE ControllerBits_Dpad_Left|ControllerBits_Dpad_Down
ROM4:9EBB   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
 
Subroutine blue_wizzrobe_action_timer_at_1_frame
ROM4:9EBC blue_wizzrobe_action_timer_at_1_frame:
ROM4:9EBC LDA prng_0,X
ROM4:9EBD AND #3
ROM4:9EBE TAY
ROM4:9EBF LDA object_x,X
ROM4:9EC0 PHA ; Push wizzrobe's X position
ROM4:9EC1 CLC
ROM4:9EC2 ADC blue_wizzrobe_hidden_x_movement,Y
ROM4:9EC3 STA object_x,X
ROM4:9EC4 LDA object_y,X
ROM4:9EC5 PHA ; Push wizzrobe's Y position
ROM4:9EC6 CLC
ROM4:9EC7 ADC blue_wizzrobe_hidden_y_movement,Y
ROM4:9EC8 STA object_y,X
ROM4:9EC9 TYA
ROM4:9ECA PHA ; Push prng & 0x3
ROM4:9ECB LDA byte_11EB8,Y
ROM4:9ECC TAY
ROM4:9ECD JSR blue_wizzrobe_action_timer_at_1_frame_xxx
ROM4:9ECE PLA ; Pop prng & 0x3
ROM4:9ECF TAY
ROM4:9ED0 PLA ; Pop wizzrobe's Y position
ROM4:9ED1 STA object_y,X
ROM4:9ED2 PLA ; Pop wizzrobe's X position
ROM4:9ED3 STA object_x,X
ROM4:9ED4 BCS loc_11EFC
ROM4:9ED5 LDA byte_11EB8,Y
ROM4:9ED6 STA object_direction,X
 
ROM4:9EEB loc_11EEB:
ROM4:9EEB LDA #$20
ROM4:9EEC STA object_tile_offset_whole,X
ROM4:9EED LDA enemy_state_0,X
ROM4:9EEE EOR #$40
ROM4:9EEF STA enemy_state_0,X
ROM4:9EF0 LDA #0
ROM4:9EF1 BEQ loc_11F00
 
ROM4:9EFC loc_11EFC:
ROM4:9EFC LDA prng_0,X
ROM4:9EFD ORA #$70
 
ROM4:9F00 loc_11F00:
ROM4:9F00 STA enemy_action_timers,X
 
ROM4:9F02 loc_11F02:
ROM4:9F02 LDA object_x,X
ROM4:9F03 CLC
ROM4:9F04 ADC #8
ROM4:9F05 AND #$F0
ROM4:9F06 STA object_x,X
ROM4:9F07 LDA object_y,X
ROM4:9F08 CLC
ROM4:9F09 ADC #8
 
ROM4:9F10 loc_11F10:
ROM4:9F10 AND #$F0
ROM4:9F11 SEC
ROM4:9F12 SBC #3
ROM4:9F13 STA object_y,X
ROM4:9F14 RTS
 
ROM4:9F18 byte_11F18: .BYTE $F
ROM4:9F19   .BYTE 0
ROM4:9F1A   .BYTE 0
ROM4:9F1B   .BYTE 4
ROM4:9F1C   .BYTE 8
ROM4:9F1D   .BYTE 0
ROM4:9F1E   .BYTE 0
ROM4:9F1F   .BYTE 4
ROM4:9F20   .BYTE 8
ROM4:9F21   .BYTE 0
ROM4:9F22 byte_11F22: .BYTE 4
ROM4:9F23   .BYTE 4
ROM4:9F24   .BYTE 0
ROM4:9F25   .BYTE 8
ROM4:9F26   .BYTE 8
ROM4:9F27   .BYTE 8
ROM4:9F28   .BYTE 0
ROM4:9F29   .BYTE $F8
ROM4:9F2A   .BYTE 0
ROM4:9F2B   .BYTE 0
 
Subroutine sub_11F2C
ROM4:9F2C sub_11F2C:
ROM4:9F2C LDY object_direction,X
 
ROM4:9F2E blue_wizzrobe_action_timer_at_1_frame_xxx:
ROM4:9F2E DEY
ROM4:9F2F LDA object_x,X
ROM4:9F30 PHA
ROM4:9F31 CLC
ROM4:9F32 ADC byte_11F18,Y
ROM4:9F33 STA object_x,X
ROM4:9F34 LDA object_y,X
ROM4:9F35 PHA
ROM4:9F36 CLC
ROM4:9F37 ADC byte_11F22,Y
ROM4:9F38 STA object_y,X
ROM4:9F39 JSR sub_11F4B
ROM4:9F3A PLA
ROM4:9F3B STA object_y,X
ROM4:9F3C PLA
ROM4:9F3D STA object_x,X
ROM4:9F3E RTS
 
Subroutine sub_11F4B
ROM4:9F4B sub_11F4B:
ROM4:9F4B JSR set_tile_walking_onto_1 ; Set tile_walking_onto for the current object.
ROM4:9F4C LDA tile_walking_onto,X
ROM4:9F4D CMP screen_first_solid_tile_id
ROM4:9F4E STA enemy_projectile_speed_x,X
ROM4:9F4F RTS
 
Subroutine update_monster_wizzrobe_blue_1
ROM4:9F58 update_monster_wizzrobe_blue_1:
ROM4:9F58 LDA object_tile_offset_whole,X
ROM4:9F59 BNE ret ; Branch if not on a tile
ROM4:9F5A LDA frame_counter
ROM4:9F5B AND #$1F
ROM4:9F5C BNE ret ; Branch if frame number not divisible by 32
ROM4:9F5D LDA object_y,X ; Compare the wizzrobe's X position with Link's X position,
  ; ignoring sub-tile offsets.
ROM4:9F5E AND #$F0
ROM4:9F5F STA var_0
ROM4:9F60 LDA object_y
ROM4:9F61 AND #$F0
ROM4:9F62 CMP var_0
ROM4:9F63 BNE check_vertical ; If the X positions aren't the same, check Y positions.
ROM4:9F64 LDA #ControllerBits_Dpad_Left
ROM4:9F65 LDY object_x,X ; If Link is to the left of the wizzrobe, fire left. Otherwise,
  ; fire right.
ROM4:9F66 CPY object_x
ROM4:9F67 BCS left
ROM4:9F68 LSR A ; A = ControllerBits_Dpad_Right
 
ROM4:9F69 left:
ROM4:9F69 CMP object_direction,X
ROM4:9F6A BEQ fire_beam
 
ROM4:9F6B ret:
ROM4:9F6B RTS
 
ROM4:9F6C check_vertical: ; Compare the wizzrobe's Y position with Link's Y position,
ROM4:9F6C LDA object_x,X ; ignoring sub-tile offsets.
ROM4:9F6D AND #$F0
ROM4:9F6E STA var_0
ROM4:9F6F LDA object_x
ROM4:9F70 CMP var_0
ROM4:9F71 BNE ret ; If the Y positions aren't the same, stop.
ROM4:9F72 LDA #ControllerBits_Dpad_Up
ROM4:9F73 LDY object_y,X
ROM4:9F74 CPY object_y
ROM4:9F75 BCS up
ROM4:9F76 LSR A ; A = ControllerBits_Dpad_Down
 
ROM4:9F77 up: ; We're lined up with Link and figured out which direction
ROM4:9F77 CMP object_direction,X ; we'd need to fire. If the wizzrobe isn't actually facing
  ; in that direction, don't fire.
ROM4:9F78 BNE ret
 
ROM4:9F79 fire_beam:
ROM4:9F79 LDA #ObjectType_Projectile_Blue_Wizzrobe_Beam
 
ROM4:9F9A fire_wizzrobe_beam: ; Red wizzrobes also branch here to fire beams.
ROM4:9F9A STA var_0 ; A is the beam object type. Store it in var_0 for
  ; create_object_at_another_object.
ROM4:9F9B LDA clock_active
ROM4:9F9C BNE ret
ROM4:9F9D LDA #Sound3_WizzrobeBeam
ROM4:9F9E STA play_sound_3 ; Play Sound3_WizzrobeBeam
ROM4:9F9F JMP create_object_at_another_object ; Create ObjectType_Projectile_Blue_Wizzrobe_Beam or ObjectType_Projectile_Red_Wizzrobe_Beam.
 
Subroutine update_monster_wizzrobe_red
ROM4:9FA9 update_monster_wizzrobe_red:
ROM4:9FA9 LDA clock_active
ROM4:9FAA BEQ clock_not_active
ROM4:9FAB JMP loc_12040
 
ROM4:9FAC clock_not_active:
ROM4:9FAC INC enemy_state_0,X
ROM4:9FAD DEC walk_state_and_weapon_state,X
ROM4:9FAE LDA walk_state_and_weapon_state,X
ROM4:9FAF LSR A ; A >>= 6
ROM4:9FB0 LSR A
ROM4:9FB1 LSR A
ROM4:9FB2 LSR A
ROM4:9FB3 LSR A
ROM4:9FB4 LSR A
ROM4:9FB5 JSR call_jump_table
 
ROM4:9FB6   .WORD locret_12034
ROM4:9FB8   .WORD update_monster_wizzrobe_red_0
ROM4:9FBA   .WORD update_monster_wizzrobe_red_1
ROM4:9FBC   .WORD update_monster_wizzrobe_red_2
 
ROM4:9FC9 byte_11FC9: .BYTE 0
ROM4:9FCA   .BYTE 0
ROM4:9FCB   .BYTE $E0
ROM4:9FCC   .BYTE $20
ROM4:9FCD   .BYTE 0
ROM4:9FCE   .BYTE 0
ROM4:9FCF   .BYTE $C0
ROM4:9FD0   .BYTE $40
ROM4:9FD1   .BYTE 0
ROM4:9FD2   .BYTE 0
ROM4:9FD3   .BYTE $D0
ROM4:9FD4   .BYTE $30
ROM4:9FD5   .BYTE 0
ROM4:9FD6   .BYTE 0
ROM4:9FD7   .BYTE $B0
ROM4:9FD8   .BYTE $50
ROM4:9FD9 byte_11FD9: .BYTE $E0
ROM4:9FDA   .BYTE $20
ROM4:9FDB   .BYTE 0
ROM4:9FDC   .BYTE 0
ROM4:9FDD   .BYTE $C0
ROM4:9FDE   .BYTE $40
ROM4:9FDF   .BYTE 0
ROM4:9FE0   .BYTE 0
ROM4:9FE1   .BYTE $D0
ROM4:9FE2   .BYTE $30
ROM4:9FE3   .BYTE 0
ROM4:9FE4   .BYTE 0
ROM4:9FE5   .BYTE $B0
ROM4:9FE6   .BYTE $50
ROM4:9FE7   .BYTE 0
ROM4:9FE8   .BYTE 0
ROM4:9FE9 byte_11FE9: .BYTE 4
ROM4:9FEA   .BYTE 8
ROM4:9FEB   .BYTE 1
ROM4:9FEC   .BYTE 2
 
Subroutine update_monster_wizzrobe_red_0
ROM4:9FED update_monster_wizzrobe_red_0:
ROM4:9FED LDA walk_state_and_weapon_state,X
ROM4:9FEE CMP #$7F
ROM4:9FEF BNE loc_11FF7
ROM4:9FF0 LDA #$4F
ROM4:9FF1 STA walk_state_and_weapon_state,X
 
ROM4:9FF7 loc_11FF7:
ROM4:9FF7 INC object_tile_offset_whole,X
ROM4:9FF8 JMP update_monster_wizzrobe_shared_red_blue
 
ROM4:9FFD update_monster_wizzrobe_red_2:
ROM4:9FFD LDY walk_state_and_weapon_state,X
ROM4:9FFE INY
 
ROM4:A000 loc_12000:
ROM4:A000 BNE update_monster_wizzrobe_red_0
ROM4:A001 LDA prng_0,X
ROM4:A002 PHA
ROM4:A003 AND #3
ROM4:A004 TAY
ROM4:A005 LDA byte_11FE9,Y
ROM4:A006 STA object_direction,X
ROM4:A007 PLA
ROM4:A008 AND #$F
ROM4:A009 TAY
ROM4:A00A LDA object_x
ROM4:A00B ADC byte_11FC9,Y
ROM4:A00C AND #$F0
ROM4:A00D STA object_x,X
ROM4:A00E LDA object_y
ROM4:A00F CLC
ROM4:A010 ADC #3
 
ROM4:A01F loc_1201F:
ROM4:A01F ADC byte_11FD9,Y
ROM4:A020 JSR loc_11F10
ROM4:A021 CMP #$5D
ROM4:A022 BCC loc_12032
ROM4:A023 CMP #$C4
ROM4:A024 BCS loc_12032
ROM4:A025 JSR sub_11F2C
ROM4:A026 BCC locret_12034
 
ROM4:A032 loc_12032:
ROM4:A032 INC walk_state_and_weapon_state,X
 
ROM4:A034 locret_12034:
ROM4:A034 RTS
 
Subroutine update_monster_wizzrobe_red_1
ROM4:A035 update_monster_wizzrobe_red_1:
ROM4:A035 LDA walk_state_and_weapon_state,X
ROM4:A036 CMP #$B0
ROM4:A037 BNE loc_12040
ROM4:A038 LDA #ObjectType_Projectile_Red_Wizzrobe_Beam
ROM4:A039 JSR fire_wizzrobe_beam
 
ROM4:A040 loc_12040:
ROM4:A040 LDA #$F6
ROM4:A041 STA damage_types_with_no_knockback,X ; Set to 0xF6.
ROM4:A042 JSR set_position_for_hitbox_check ; Set var_2/var_3 to this object's X/Y position for hit checking.
ROM4:A043 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:A044 BNE invincible ; Skip if this object is in i-frames.
ROM4:A045 LDY #AttackType_SwordBeamOrRodBeam ; The beam of either the beam sword or the rod.
ROM4:A046 JSR check_attack_beam_sword_rod
ROM4:A047 LDY #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
ROM4:A048 JSR check_attack_bomb_or_fire
ROM4:A049 LDY #AttackType_BombOrFire2
ROM4:A04A JSR check_attack_bomb_or_fire
ROM4:A04B LDY #AttackType_Sword
ROM4:A04C JSR check_attack_sword
 
ROM4:A04D invincible: ; Check if Link was hit by an enemy. X is the enemy we're
ROM4:A04D JSR check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM4:A04E LDA enemy_state_0,X
ROM4:A04F LSR A
ROM4:A050 LSR A
ROM4:A051 AND #1
ROM4:A052 PHA
ROM4:A053 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:A054 LDA object_direction,X
ROM4:A055 AND #ControllerBits_Dpad_Up
ROM4:A056 BNE up
ROM4:A057 LDA object_direction,X
ROM4:A058 LSR A
ROM4:A059 AND #1
ROM4:A05A STA var_15
ROM4:A05B PLA
ROM4:A05C JMP update_object_sprite_horizontal
 
ROM4:A05D up:
ROM4:A05D PLA
ROM4:A05E CLC
ROM4:A05F ADC #2
ROM4:A060 JMP update_object_sprite_vertical
 
ROM4:A061   .BYTE $6F
ROM4:A062   .BYTE $74
ROM4:A063   .BYTE $79
ROM4:A064   .BYTE $7E
ROM4:A065   .BYTE $83
ROM4:A066   .BYTE $88
 
Subroutine spawn_gleeok
ROM4:A08D spawn_gleeok:
ROM4:A08D LDA #Sound0_BossRoar1
ROM4:A08E STA play_sound_0 ; Play Sound0_BossRoar1
ROM4:A08F LDX #5
 
ROM4:A090 loop:
ROM4:A090 LDA #$7C
ROM4:A091 STA enemy_state_5_1,X ; Set to 0x7C
ROM4:A092 STA stop_enemy_for_frames_1,X ; Set to 0x7C
ROM4:A093 STA enemy_state_1_1,X ; Set to 0x7C
ROM4:A094 STA object_tile_offset_whole_1,X ; Set to 0x7C
ROM4:A095 STA object_x_1,X ; Set to 0x7C
ROM4:A096 LDA loc_A086+1,X
ROM4:A097 STA enemy_state_6_1,X
ROM4:A098 STA enemy_state_2_1,X
ROM4:A099 STA enemy_blind_projectile_timer_1,X
ROM4:A09A STA object_walk_speed_1,X
ROM4:A09B STA object_y_1,X
ROM4:A09C LDA #$A0
ROM4:A09D STA enemy_health_1,X ; Set to 0xA0
ROM4:A09E LDA #0
ROM4:A09F STA enemy_spawn_state_1,X ; Set to 0
ROM4:A0A0 STA byte_494,X ; Set to 0
ROM4:A0A1 LDA #$FE
ROM4:A0A2 STA damage_types_with_no_knockback_1,X ; Set to 0xFE
ROM4:A0A3 DEX
ROM4:A0A4 BPL loop
ROM4:A0A5 STX store_item
ROM4:A0A6 STX enemy_state_4_4
ROM4:A0A7 STX unk_383
ROM4:A0A8 STX object_tile_offset_fraction_4
ROM4:A0A9 LDA #3
ROM4:A0AA STA byte_421
ROM4:A0AB STA enemy_state_4_2
ROM4:A0AC STA unk_382
ROM4:A0AD STA object_tile_offset_fraction_2
ROM4:A0AE ASL A
ROM4:A0AF STA enemy_projectile_speed_x_1
ROM4:A0B0 STA enemy_state_4_1
ROM4:A0B1 STA enemy_state_11_1
ROM4:A0B2 STA object_tile_offset_fraction_1 ; Lots of code refers to this through object_tile_offset_fraction, since object IDs start at 1.
ROM4:A0B3 ASL A
ROM4:A0B4 STA enemy_state_4_6
ROM4:A0B5 ASL A
ROM4:A0B6 STA unk_386
ROM4:A0B7 ADC enemy_state_4_6
ROM4:A0B8 STA object_tile_offset_fraction_6
ROM4:A0B9 RTS
 
ROM4:A100 byte_12100: .BYTE 0
ROM4:A101   .BYTE $80
ROM4:A102   .BYTE 2
ROM4:A103   .BYTE $42
ROM4:A104   .BYTE 4
ROM4:A105 manhandla_claw_y_positions: .BYTE 0
ROM4:A106   .BYTE 0
ROM4:A107 manhandla_claw_x_positions: .BYTE $F0
ROM4:A108   .BYTE $10
ROM4:A109   .BYTE 0
ROM4:A10A   .BYTE 0
ROM4:A10B   .BYTE 0
 
Subroutine spawn_manhandla
ROM4:A10C spawn_manhandla:
ROM4:A10C LDA #Sound0_BossRoar3
ROM4:A10D STA play_sound_0 ; Play Sound0_BossRoar3
ROM4:A10E LDA prng_0,X
ROM4:A10F AND #7
ROM4:A110 TAY
ROM4:A111 LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:A112 STA object_direction,X
ROM4:A113 LDY #4 ; Create 4 Manhandla claws
 
ROM4:A114 loop:
ROM4:A114 LDA object_direction_1
ROM4:A115 STA object_direction_1,Y
ROM4:A116 LDA #ObjectType_Manhandla
ROM4:A117 STA object_type_1,Y ; Set to ObjectType_Manhandla
ROM4:A118 LDA #$E2
ROM4:A119 STA damage_types_with_no_knockback_1,Y ; Set to 0xE2
ROM4:A11A LDA byte_12100,Y
ROM4:A11B STA enemy_blind_projectile_timer_1,Y
ROM4:A11C LDA #0
ROM4:A11D STA enemy_spawn_state_1,Y ; Set to 0 (no spawn cloud for Manhandla claws)
ROM4:A11E STA byte_493,Y ; Set to 0
ROM4:A11F LDA enemy_state_9_1
ROM4:A120 STA enemy_state_9_1,Y
ROM4:A121 LDA enemy_health_1
ROM4:A122 STA enemy_health_1,Y
ROM4:A123 LDA object_x_5
ROM4:A124 CLC
ROM4:A125 ADC manhandla_claw_y_positions,Y
ROM4:A126 STA object_x_1,Y
ROM4:A127 LDA object_y_5
ROM4:A128 CLC
ROM4:A129 ADC manhandla_claw_x_positions,Y
ROM4:A12A STA object_y_1,Y
ROM4:A12B LDA #$80
ROM4:A12C STA enemy_projectile_speed_x_1,Y
ROM4:A12D DEY
ROM4:A12E BPL loop
ROM4:A12F RTS
 
Subroutine spawn_gohma
ROM4:A161 spawn_gohma:
ROM4:A161 LDA #Sound0_BossRoar2
ROM4:A162 STA play_sound_0 ; Play Sound0_BossRoar2
ROM4:A163 LDA #$FB
ROM4:A164 STA damage_types_with_no_knockback,X ; Set to 0xFB.
ROM4:A165 INC enemy_state_11,X
ROM4:A166 LDA #$80
ROM4:A167 STA object_x,X
ROM4:A168 LDA #$70
ROM4:A169 STA object_y,X
ROM4:A16A JMP spawn_monster_no_timer_no_spawn_cloud
 
Subroutine spawn_gleeok_flying_head
ROM4:A179 spawn_gleeok_flying_head:
ROM4:A179 JSR spawn_blue_keese
ROM4:A17A LDA #$E0
ROM4:A17B STA increase_enemy_speed_max ; Set to 0xE0.
ROM4:A17C LDA #$BF ; Flying head enemy speed
ROM4:A17D STA enemy_projectile_speed_x,X
ROM4:A17E RTS
 
Subroutine update_monster_manhandla
ROM4:A187 update_monster_manhandla:
 
ROM4:A187 CPX #5
ROM4:A188 BNE loc_121CC
ROM4:A189 LDA unk_383
ROM4:A18A BEQ loc_121AB
ROM4:A18B LDY #4
 
ROM4:A192 loc_12192:
ROM4:A192 LDA enemy_projectile_speed_x_1,Y
ROM4:A193 CLC
ROM4:A194 ADC #$80
ROM4:A195 STA enemy_projectile_speed_x_1,Y
ROM4:A196 LDA enemy_state_4_1,Y
ROM4:A197 ADC #0
ROM4:A198 STA enemy_state_4_1,Y
ROM4:A199 DEY
ROM4:A19A BPL loc_12192
ROM4:A19B LDA #0
ROM4:A19C STA unk_383
 
ROM4:A1AB loc_121AB:
ROM4:A1AB LDA unk_385
ROM4:A1AC BEQ loc_121B3
ROM4:A1AD JSR sub_12285
 
ROM4:A1B3 loc_121B3:
ROM4:A1B3 LDA enemy_action_timers,X
ROM4:A1B4 BNE loc_121CC
ROM4:A1B5 LDA #$10
ROM4:A1B6 STA enemy_action_timers,X
ROM4:A1B7 LDA prng_0,X
ROM4:A1B8 CMP #$80
ROM4:A1B9 BCS loc_1221F
ROM4:A1BA JSR randomly_rotate_movement_by_45_degrees
 
ROM4:A1C4 loc_121C4:
ROM4:A1C4 LDA object_direction_1+4
ROM4:A1C5 STA unk_385
ROM4:A1C6 JSR sub_12285
 
ROM4:A1CC loc_121CC:
ROM4:A1CC CPX #5
ROM4:A1CD BNE loc_121D5
ROM4:A1CE LDA object_direction,X
ROM4:A1CF STA unk_384
 
ROM4:A1D5 loc_121D5:
ROM4:A1D5 JSR update_monster_manhandla_1
ROM4:A1D6 JSR update_monster_manhandla_2
ROM4:A1D7 LDA object_direction,X
ROM4:A1D8 CMP unk_384
ROM4:A1D9 BEQ loc_121E5
ROM4:A1DA STA unk_385
 
ROM4:A1E5 loc_121E5:
ROM4:A1E5 LDA stop_enemy_for_frames,X
ROM4:A1E6 AND #$10
ROM4:A1E7 LSR A
ROM4:A1E8 LSR A
ROM4:A1E9 LSR A
ROM4:A1EA LSR A
ROM4:A1EB STA var_0
ROM4:A1EC LDA enemy_blind_projectile_timer,X
ROM4:A1ED AND #$FE
ROM4:A1EE ORA var_0
ROM4:A1EF STA enemy_blind_projectile_timer,X
ROM4:A1F0 CPX #5
ROM4:A1F1 BEQ loc_1221C
ROM4:A1F2 LDA enemy_blind_projectile_timer,X
ROM4:A1F3 CMP enemy_state_5,X
ROM4:A1F4 BEQ loc_1221C
ROM4:A1F5 STA enemy_state_5,X
ROM4:A1F6 LSR A
ROM4:A1F7 BCS loc_1221C
ROM4:A1F8 LDA prng_1,X
ROM4:A1F9 CMP #$E0
ROM4:A1FA BCC loc_1221C
ROM4:A1FB LDA object_type_7
ROM4:A1FC BNE loc_1221C
ROM4:A1FD LDA #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:A1FE JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_2.
 
ROM4:A21C loc_1221C:
ROM4:A21C JMP loc_122EF
 
ROM4:A21F loc_1221F:
ROM4:A21F JSR update_monster_diagonal_movement_relative_to_seek_from_digdogger
ROM4:A220 JMP loc_121C4
 
Subroutine update_monster_manhandla_2
ROM4:A225 update_monster_manhandla_2:
ROM4:A225 LDA object_direction,X
ROM4:A226 PHA
ROM4:A227 LDA enemy_action_timers,X
ROM4:A228 PHA
ROM4:A229 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:A22A PLA
ROM4:A22B STA enemy_action_timers,X
ROM4:A22C PLA
ROM4:A22D STA object_direction,X
ROM4:A22E CPX #5
ROM4:A22F BNE loc_1223D
ROM4:A230 LDA #0
ROM4:A231 STA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
 
ROM4:A23D loc_1223D: ; If the current enemy was just hit (has 16 invincibility
ROM4:A23D JSR play_boss_pain_sound_after_hit ; frames), play Sound0_BossPainSound.
ROM4:A23E LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:A23F BEQ locret_1227C
ROM4:A240 JSR clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
ROM4:A241 CPX #5
ROM4:A242 BNE loc_12252
ROM4:A243 STA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:A244 JMP locret_1227C
 
ROM4:A252 loc_12252:
ROM4:A252 LDY #3
ROM4:A253 LDA #0
ROM4:A254 STA var_0
 
ROM4:A258 loc_12258: ; check if ObjectType_Manhandla
ROM4:A258 LDA object_type_1,Y
ROM4:A259 CMP #ObjectType_Manhandla
ROM4:A25A BNE loc_12261
ROM4:A25B INC var_0
 
ROM4:A261 loc_12261:
ROM4:A261 DEY
ROM4:A262 BPL loc_12258 ; check if ObjectType_Manhandla
ROM4:A263 DEC var_0
ROM4:A264 BMI loc_1226A
ROM4:A265 BNE loc_1227D
 
ROM4:A26A loc_1226A:
ROM4:A26A JSR play_boss_sound_1
ROM4:A26B LDA #$5D
ROM4:A26C STA object_type_5
ROM4:A26D LDA #$10
ROM4:A26E STA enemy_spawn_state_1_5
ROM4:A26F STA npc_action_timer_5
 
ROM4:A279 loc_12279:
ROM4:A279 INC unk_383
 
ROM4:A27C locret_1227C:
ROM4:A27C RTS
 
ROM4:A27D loc_1227D:
ROM4:A27D LDA #$5D
ROM4:A27E STA $34F,X
ROM4:A27F JMP loc_12279
 
Subroutine sub_12285
ROM4:A285 sub_12285:
ROM4:A285 LDY #4
 
ROM4:A287 loc_12287:
ROM4:A287 STA $99,Y
ROM4:A288 DEY
ROM4:A289 BPL loc_12287
ROM4:A28A RTS
 
Subroutine update_monster_manhandla_1
ROM4:A28E update_monster_manhandla_1:
ROM4:A28E LDA enemy_projectile_speed_x,X
ROM4:A28F AND #$E0
ROM4:A290 CLC
ROM4:A291 ADC enemy_state_0,X
ROM4:A292 STA enemy_state_0,X
ROM4:A293 LDA enemy_state_4,X
ROM4:A294 ADC #0
ROM4:A295 STA var_3
ROM4:A296 LDA #$A1
ROM4:A297 STA var_2
ROM4:A298 LDA object_direction,X
ROM4:A299 BIT var_2
ROM4:A29A BEQ loc_122B2
ROM4:A29B LDA object_x,X
ROM4:A29C CLC
ROM4:A29D ADC var_3
ROM4:A29E STA object_x,X
 
ROM4:A2B2 loc_122B2:
ROM4:A2B2 LDA object_direction,X
ROM4:A2B3 ASL var_2
ROM4:A2B4 BIT var_2
ROM4:A2B5 BEQ loc_122C0
ROM4:A2B6 LDA object_x,X
ROM4:A2B7 SBC var_3
ROM4:A2B8 STA object_x,X
 
ROM4:A2C0 loc_122C0:
ROM4:A2C0 LDA object_direction,X
ROM4:A2C1 ASL var_2
ROM4:A2C2 BIT var_2
ROM4:A2C3 BEQ loc_122CE
ROM4:A2C4 LDA object_y,X
ROM4:A2C5 ADC var_3
ROM4:A2C6 STA object_y,X
 
ROM4:A2CE loc_122CE:
ROM4:A2CE LDA object_direction,X
ROM4:A2CF ASL var_2
ROM4:A2D0 BIT var_2
ROM4:A2D1 BEQ loc_122DC
ROM4:A2D2 LDA object_y,X
ROM4:A2D3 SBC var_3
ROM4:A2D4 STA object_y,X
 
ROM4:A2DC loc_122DC:
ROM4:A2DC LDA prng_1,X
ROM4:A2DD AND #3
ROM4:A2DE CLC
ROM4:A2DF ADC var_3
ROM4:A2E0 ADC stop_enemy_for_frames,X
ROM4:A2E1 STA stop_enemy_for_frames,X
ROM4:A2E2 JSR reverse_walking_direction_if_out_of_bounds ; If this object is walking out of the boundary of this
  ; screen, turn around.
ROM4:A2E3 JMP set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
 
Function chunk for update_monster_manhandla
ROM4:A2EF loc_122EF: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:A2EF JSR set_var_0_to_object_position
ROM4:A2F0 LDA enemy_blind_projectile_timer,X
ROM4:A2F1 PHA
ROM4:A2F2 AND #OAMAttributes_FlipVertically
ROM4:A2F3 ORA #OAMAttributes_Palette_1
ROM4:A2F4 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:A2F5 PLA
ROM4:A2F6 PHA
ROM4:A2F7 AND #$40
ROM4:A2F8 BEQ loc_12305
ROM4:A2F9 INC var_15
 
ROM4:A305 loc_12305:
ROM4:A305 PLA
ROM4:A306 AND #$F
ROM4:A307 CMP #2
ROM4:A308 BEQ loc_12313
ROM4:A309 CMP #3
ROM4:A30A BEQ loc_12313
ROM4:A30B JMP update_object_sprite_vertical
 
ROM4:A313 loc_12313:
ROM4:A313 JMP update_object_sprite_horizontal
 
Subroutine update_monster_gohma
ROM4:A316 update_monster_gohma:
ROM4:A316 LDA stop_enemy_for_frames,X
ROM4:A317 BNE gohma_is_stopped
ROM4:A318 LDA #1
ROM4:A319 LDY prng_0,X
ROM4:A31A CPY #$B0
ROM4:A31B BCS set_gohma_direction ; What does this do? Gohmas don't turn.
ROM4:A31C ASL A ; A = 2
ROM4:A31D CPY #$60
ROM4:A31E BCS set_gohma_direction ; What does this do? Gohmas don't turn.
ROM4:A31F ASL A ; A = 4
 
ROM4:A320 set_gohma_direction: ; What does this do? Gohmas don't turn.
ROM4:A320 STA object_direction,X
ROM4:A321 INC stop_enemy_for_frames,X ; Stop for a frame after changing direction
ROM4:A322 JMP loc_12380
 
ROM4:A323 gohma_is_stopped:
ROM4:A323 LDA enemy_projectile_speed_x,X
ROM4:A324 CLC
ROM4:A325 ADC #$80
ROM4:A326 STA enemy_projectile_speed_x,X
ROM4:A327 BCC loc_12380
ROM4:A328 INC enemy_state_0,X
ROM4:A329 LDA #1
ROM4:A32A STA var_2
ROM4:A32B LDA object_direction,X
ROM4:A32C BIT var_2
ROM4:A32D BEQ loc_1234B
ROM4:A32E INC object_x,X
 
ROM4:A34B loc_1234B:
ROM4:A34B ASL var_2
ROM4:A34C BIT var_2
ROM4:A34D BEQ loc_12353
ROM4:A34E DEC object_x,X
 
ROM4:A353 loc_12353:
ROM4:A353 ASL var_2
ROM4:A354 BIT var_2
ROM4:A355 BEQ loc_1235B
ROM4:A356 INC object_y,X
 
ROM4:A35B loc_1235B:
ROM4:A35B ASL var_2
ROM4:A35C BIT var_2
ROM4:A35D BEQ loc_12363
ROM4:A35E DEC object_y,X
 
ROM4:A363 loc_12363:
ROM4:A363 LDA enemy_state_0,X
ROM4:A364 CMP #prng_8
ROM4:A365 BNE loc_12380
ROM4:A366 LDA #0
ROM4:A367 STA enemy_state_0,X
ROM4:A368 JSR reverse_walking_direction
ROM4:A369 LDA enemy_state_2,X
ROM4:A36A INC enemy_state_2,X
ROM4:A36B LSR A
ROM4:A36C BCC loc_12380
ROM4:A36D LDA #0
ROM4:A36E STA stop_enemy_for_frames,X
 
ROM4:A380 loc_12380:
ROM4:A380 LDA enemy_state_4,X
ROM4:A381 BNE loc_12391
ROM4:A382 LDA #$80
ROM4:A383 STA enemy_state_6,X
ROM4:A384 LDA #$C0
ROM4:A385 ORA prng_0,X
ROM4:A386 STA enemy_state_4,X
 
ROM4:A391 loc_12391:
ROM4:A391 LDA frame_counter
ROM4:A392 LSR A
ROM4:A393 BCC loc_12399
ROM4:A394 DEC enemy_state_4,X
 
ROM4:A399 loc_12399:
ROM4:A399 LDA enemy_state_6,X
ROM4:A39A BEQ loc_123C8
ROM4:A39B DEC enemy_state_6,X
ROM4:A39C LDY #2
ROM4:A39D CMP #$70
ROM4:A39E BCS loc_123AC
ROM4:A39F CMP #$10
ROM4:A3A0 BCC loc_123AC
ROM4:A3A1 INY
 
ROM4:A3AC loc_123AC:
ROM4:A3AC TYA
 
ROM4:A3AD loc_123AD:
ROM4:A3AD STA enemy_state_1,X
 
ROM4:A3B0 loc_123B0:
ROM4:A3B0 DEC enemy_state_11,X
ROM4:A3B1 BNE loc_123BF
ROM4:A3B2 LDA #$41
ROM4:A3B3 STA enemy_state_11,X
ROM4:A3B4 LDA #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:A3B5 JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_2.
 
ROM4:A3BF loc_123BF:
ROM4:A3BF LDA enemy_state_1,X
ROM4:A3C0 JSR update_monster_gohma_1
ROM4:A3C1 JMP update_monster_gohma_0
 
ROM4:A3C8 loc_123C8:
ROM4:A3C8 INC enemy_blind_projectile_timer,X
ROM4:A3C9 LDA enemy_blind_projectile_timer,X
ROM4:A3CA CMP #8
ROM4:A3CB BNE loc_123B0
ROM4:A3CC LDA #0
ROM4:A3CD STA enemy_blind_projectile_timer,X
ROM4:A3CE LDA enemy_state_1,X
ROM4:A3CF AND #1
ROM4:A3D0 EOR #1
ROM4:A3D1 JMP loc_123AD
 
ROM4:A3E1 byte_123E1: .BYTE $F0
ROM4:A3E2   .BYTE $10
 
Subroutine update_monster_gohma_1
ROM4:A3E3 update_monster_gohma_1:
ROM4:A3E3 PHA
ROM4:A3E4 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:A3E5 JSR update_monster_gohma_3
ROM4:A3E6 PLA
ROM4:A3E7 JSR update_object_sprite_vertical
ROM4:A3E8 LDA #$10
ROM4:A3E9 JSR update_object_animation_frame
ROM4:A3EA LDY #1
ROM4:A3EB JSR update_monster_gohma_2
ROM4:A3EC LDY #0
 
Subroutine update_monster_gohma_2
ROM4:A3FA update_monster_gohma_2:
ROM4:A3FA LDA object_x,X
ROM4:A3FB CLC
ROM4:A3FC ADC byte_123E1,Y
ROM4:A3FD STA var_0
ROM4:A3FE LDA object_y,X
ROM4:A3FF STA var_1
ROM4:A400 JSR update_monster_gohma_3
ROM4:A401 JSR store_animation_frame
ROM4:A402 TYA
ROM4:A403 CLC
ROM4:A404 ADC object_animation_frame,X
ROM4:A405 AND #1
ROM4:A406 CLC
ROM4:A407 ADC #4
ROM4:A408 JMP update_object_sprite_horizontal
 
Subroutine update_monster_gohma_3
ROM4:A419 update_monster_gohma_3:
ROM4:A419 LDA object_type,X
ROM4:A41A SEC
ROM4:A41B SBC #ObjectType_DodongoBoss ; Palette 1 for blue Gohma, 2 for red Gohma.
ROM4:A41C JMP store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
 
Subroutine update_monster_gohma_0
ROM4:A422 update_monster_gohma_0:
ROM4:A422 LDA object_x,X
ROM4:A423 PHA
ROM4:A424 SEC
ROM4:A425 SBC #$10
ROM4:A426 STA object_x,X
ROM4:A427 LDA #5
ROM4:A428 STA var_15
 
ROM4:A42E loc_1242E: ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:A42E JSR check_enemy_hits
ROM4:A42F LDA object_x,X
ROM4:A430 CLC
ROM4:A431 ADC #8
ROM4:A432 STA object_x,X
ROM4:A433 DEC var_15
ROM4:A434 BNE loc_1242E
ROM4:A435 PLA
ROM4:A436 STA object_x,X
ROM4:A437 RTS
 
Subroutine apply_damage_to_gohma
ROM4:A440 apply_damage_to_gohma:
ROM4:A440 CPY #AttackType_ArrowOrMeleeRod ; An arrow in the air, or the melee part of the rod attack.
ROM4:A441 BNE loc_1244E
ROM4:A442 LDA #$28
ROM4:A443 STA walk_state_and_weapon_state,Y
ROM4:A444 LDA #4
ROM4:A445 STA object_animation_frame_timer,Y
 
ROM4:A44E loc_1244E:
ROM4:A44E LDA var_15
ROM4:A44F CMP #3
ROM4:A450 BEQ loc_12458
ROM4:A451 CMP #4
ROM4:A452 BNE play_gohma_shield_ting
 
ROM4:A458 loc_12458: ; Probably checking if Gohma's eye is closed
ROM4:A458 LDA enemy_state_1,X
ROM4:A459 CMP #3
ROM4:A45A BNE play_gohma_shield_ting
ROM4:A45B LDA object_direction,Y ; Only takes damage when shot upwards
ROM4:A45C CMP #ControllerBits_Dpad_Up
ROM4:A45D BNE play_gohma_shield_ting
ROM4:A45E LDA #Sound0_BossPainSound
ROM4:A45F STA play_sound_0 ; Play Sound0_BossSound1 for Gohma damage
ROM4:A460 JSR apply_damage_to_enemy ; Continue applying damage to Gohma
ROM4:A461 JSR play_boss_sound_1_if_not_state_0
 
ROM4:A462 play_gohma_shield_ting:
ROM4:A462 LDA #Sound3_ShieldTing
ROM4:A463 STA play_sound_3 ; Play Sound3_ShieldTing
ROM4:A464 RTS
 
Subroutine update_monster_gleeok_flying_head
ROM4:A477 update_monster_gleeok_flying_head:
ROM4:A477 JSR run_state
ROM4:A478 JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
ROM4:A479 LDA enemy_state_5,X
ROM4:A47A AND #1
ROM4:A47B BNE skip_create_fireball
ROM4:A47C LDA prng_1,X
ROM4:A47D CMP #$20
ROM4:A47E BCS skip_create_fireball ; Shoot a fireball if prng < 0x20
ROM4:A47F LDA object_type_B
ROM4:A480 BNE skip_create_fireball
ROM4:A481 LDA #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:A482 JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_2.
 
ROM4:A483 skip_create_fireball:
ROM4:A483 LDA #1
ROM4:A484 JSR update_object_animation_frame
ROM4:A485 LDA object_animation_frame,X
ROM4:A486 JSR update_object_sprite_vertical
ROM4:A487 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:A488 JSR set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM4:A489 JSR clear_knockback2 ; A = 0
ROM4:A48A STA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:A48B RTS
 
ROM4:A48C run_state:
ROM4:A48C LDA enemy_state_6,X
ROM4:A48D JSR call_jump_table
 
ROM4:A48E   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:A490   .WORD update_monster_gleeok_flying_head_choose_random_state ; Randomly choose whether to go to state 2 or 3.
ROM4:A492   .WORD update_monster_diagonal_movement_relative_to_seek ; Update the current enemy's direction relative to the seek
  ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:A494   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
 
ROM4:A4BA update_monster_gleeok_flying_head_choose_random_state: ; Randomly choose whether to go to state 2 or 3.
ROM4:A4BA LDY #2
ROM4:A4BB LDA prng_1,X
ROM4:A4BC CMP #$D0 ; If random value >= 0xD0, 2
ROM4:A4BD BCC set_state_thunk
ROM4:A4BE INY ; Otherwise, state 3.
 
ROM4:A4C3 set_state_thunk:
ROM4:A4C3 JMP set_enemy_state_4_and_6
 
ROM4:A4C6 gleeok_ptr_x_low: .BYTE $38 ; 0x438, enemy_state_5_1
ROM4:A4C7   .BYTE $52 ; 0x452, stop_enemy_for_frames_1
ROM4:A4C8   .BYTE $6C ; 0x46C, enemy_state_1_1
ROM4:A4C9   .BYTE $95 ; 0x395, object_tile_offset_whole_1
ROM4:A4CA gleeok_ptr_x_high: .BYTE 4
ROM4:A4CB   .BYTE 4
ROM4:A4CC   .BYTE 4
ROM4:A4CD   .BYTE 3
ROM4:A4CE gleeok_ptr_y_low: .BYTE $45 ; 0x445, enemy_state_6_1
ROM4:A4CF   .BYTE $5F ; 0x45F, enemy_state_2_1
ROM4:A4D0   .BYTE $79 ; 0x479, enemy_blind_projectile_timer_1
ROM4:A4D1   .BYTE $BD ; 0x3BD, object_walk_speed_1
ROM4:A4D2 gleeok_ptr_y_high: .BYTE 4
ROM4:A4D3   .BYTE 4
ROM4:A4D4   .BYTE 4
ROM4:A4D5   .BYTE 3
ROM4:A4D6 gleeok_ptr_something_low: .BYTE $20 ; 0x420, enemy_projectile_speed_x_1
ROM4:A4D7   .BYTE $2D ; 0x42D, enemy_state_4_1
ROM4:A4D8   .BYTE $81 ; 0x381, enemy_state_11_1
ROM4:A4D9   .BYTE $A9 ; 0x3A9, object_tile_offset_fraction_1
ROM4:A4DA gleeok_ptr_something_high: .BYTE 4
ROM4:A4DB   .BYTE 4
ROM4:A4DC   .BYTE 3
ROM4:A4DD   .BYTE 3
 
Subroutine update_monster_gleeok
ROM4:A4DE update_monster_gleeok:
ROM4:A4DE JSR update_gleeok_body ; Update Gleeok's body sprites and animation.
ROM4:A4DF LDA object_type_1
ROM4:A4E0 SEC
ROM4:A4E1 SBC #ObjectType_Gleeok_1_Head
ROM4:A4E2 STA processing_gleeok_head
 
ROM4:A4E3 loop:
ROM4:A4E3 LDY processing_gleeok_head
ROM4:A4E4 LDA powers_of_two,Y
ROM4:A4E5 BIT detached_gleeok_heads ; A mask of Gleeok heads that are detached and flying around the room
ROM4:A4E6 BEQ update_living_gleeok_head ; Skip heads that are dead and flying around.
  ; Those are independent update_monster_gleeok_flying_head
  ; objects that update themselves.
ROM4:A4E7 JMP continue
 
ROM4:A4E8 update_living_gleeok_head: ; Get pointers to data for the neck of a Gleeok head (including
ROM4:A4E8 JSR get_gleeok_neck_pointers ; the head itself). Each array has 5 elements, with the 4th
  ; being the head.
 
  ; In X: Gleeok head number (0-3)
  ; Out: var_0: 16-bit pointer to array of X positions for each neck segment
  ; Out: var_2: 16-bit pointer to array of Y positions for each neck segment
  ; Out: var_4: 16-bit pointer to array of (unknown) for each neck segment
  ; Out Y: 5
 
ROM4:A4E9 loop1: ; Loop for each neck segment
ROM4:A4E9 LDA (var_0),Y
ROM4:A4EA STA object_x_1,Y ; Set object_x[1-5] to the X position of this Gleeok head's
  ; 1st-5th neck segment/head position. This is used during the
  ; sprite update.
ROM4:A4EB LDA (var_2),Y
ROM4:A4EC STA object_y_1,Y
ROM4:A4ED LDA (var_4),Y
ROM4:A4EE STA byte_413,Y
ROM4:A4EF DEY
ROM4:A4F0 BPL loop1
ROM4:A4F1 LDA frame_counter
ROM4:A4F2 AND #3
ROM4:A4F3 STA var_0 ; Store frame number & 0x3
ROM4:A4F4 CPX var_0
ROM4:A4F5 BNE skip_fireball ; There are up to four heads. Alternate updating one neck per frame.
ROM4:A4F6 JSR update_gleeok_head_and_necks_1
ROM4:A4F7 JSR update_gleeok_head_and_necks_2
ROM4:A4F8 LDX #5
ROM4:A4F9 LDA prng_0,X
ROM4:A4FA CMP #$20
ROM4:A4FB BCS skip_fireball ; Shoot a fireball if prng[5] < 0x20
ROM4:A4FC LDA object_type_B ; Don't shoot a fireball if one is already in the air.
ROM4:A4FD BNE skip_fireball
ROM4:A4FE LDA #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:A4FF JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_2.
 
ROM4:A500 skip_fireball: ; XXX
ROM4:A500 JSR gleeok_update_sprites_and_spawn_flying_heads
ROM4:A501 JSR get_gleeok_neck_pointers ; Get pointers to data for the neck of a Gleeok head (including
  ; the head itself). Each array has 5 elements, with the 4th
  ; being the head.
 
  ; In X: Gleeok head number (0-3)
  ; Out: var_0: 16-bit pointer to array of X positions for each neck segment
  ; Out: var_2: 16-bit pointer to array of Y positions for each neck segment
  ; Out: var_4: 16-bit pointer to array of (unknown) for each neck segment
  ; Out Y: 5
 
ROM4:A502 loop2: ; Loop for each neck segment, and store the resulting
ROM4:A502 LDA object_x_1,Y ; neck data back out
ROM4:A503 STA (var_0),Y
ROM4:A504 LDA object_y_1,Y
ROM4:A505 STA (var_2),Y
ROM4:A506 LDA byte_413,Y
ROM4:A507 STA (var_4),Y
ROM4:A508 DEY
ROM4:A509 BPL loop2
 
ROM4:A50A continue:
ROM4:A50A DEC processing_gleeok_head
ROM4:A50B BPL loop
ROM4:A50C RTS
 
Subroutine get_gleeok_neck_pointers
; Get pointers to data for the neck of a Gleeok head (including ; the head itself). Each array has 5 elements, with the 4th ; being the head. ; ; In X: Gleeok head number (0-3) ; Out: var_0: 16-bit pointer to array of X positions for each neck segment ; Out: var_2: 16-bit pointer to array of Y positions for each neck segment ; Out: var_4: 16-bit pointer to array of (unknown) for each neck segment ; Out Y: 5
ROM4:A54D get_gleeok_neck_pointers:
ROM4:A54D LDX processing_gleeok_head
ROM4:A54E LDA gleeok_ptr_x_low,X ; 0x438, enemy_state_5_1
ROM4:A54F STA var_0
ROM4:A550 LDA gleeok_ptr_x_high,X
ROM4:A551 STA var_1
ROM4:A552 LDA gleeok_ptr_y_low,X ; 0x445, enemy_state_6_1
ROM4:A553 STA var_2
ROM4:A554 LDA gleeok_ptr_y_high,X
ROM4:A555 STA var_3
ROM4:A556 LDA gleeok_ptr_something_low,X ; 0x420, enemy_projectile_speed_x_1
ROM4:A557 STA var_4
ROM4:A558 LDA gleeok_ptr_something_high,X
ROM4:A559 STA var_5
ROM4:A55A LDY #5
ROM4:A55B RTS
 
Function chunk for update_gleeok_head_and_necks_1
ROM4:A55C divide_by_4:
ROM4:A55C LSR A
ROM4:A55D LSR A
ROM4:A55E JMP continue_from_divide_by_4
 
Subroutine update_gleeok_head_and_necks_1
ROM4:A576 update_gleeok_head_and_necks_1:
 
ROM4:A576 LDA object_x_5 ; Head X position
ROM4:A577 SEC
ROM4:A578 SBC object_x_1 ; Head X position - Neck X position = pixels this head is to the right of the body
ROM4:A579 BPL divide_by_4 ; A /= 4
ROM4:A57A JSR inverse ; If negative, A = -A, A /= 4, then A = -A again
ROM4:A57B LSR A
ROM4:A57C LSR A
ROM4:A57D JSR inverse
 
ROM4:A57E continue_from_divide_by_4: ; Store the signed distance between the head and neck / 4.
ROM4:A57E STA byte_4D8 ; Is this used?
ROM4:A57F JSR absolute_value ; A = abs(A)
ROM4:A580 LDX #0 ; X = 0
ROM4:A581 JSR update_monster_gleeok_2b
ROM4:A582 LDA object_y_5 ; Head Y position
ROM4:A583 SEC
ROM4:A584 SBC object_y_1 ; Head Y position - Neck Y position = pixels this head is below the body
ROM4:A585 JSR absolute_value ; A = abs(A)
ROM4:A586 LSR A ; A /= 4
ROM4:A587 LSR A
ROM4:A588 INX ; X = 1
ROM4:A589 JSR update_monster_gleeok_2b
ROM4:A58A LDX #0 ; Loop X = 0 to 3
 
ROM4:A58B loop1:
ROM4:A58B LDA object_x_1,X
ROM4:A58C SEC
ROM4:A58D SBC object_x_2,X ; A = X distance between this neck segment and the next
ROM4:A58E JSR absolute_value ; A = abs(A)
ROM4:A58F CMP byte_4DD
ROM4:A590 BCC loc_125BC
ROM4:A591 LDA object_x_2,X
ROM4:A592 TAY
ROM4:A593 INY
ROM4:A594 INY
ROM4:A595 CMP object_x_1,X
ROM4:A596 BCC loc_125BA
ROM4:A597 DEY
ROM4:A598 DEY
ROM4:A599 DEY
ROM4:A59A DEY
 
ROM4:A5BA loc_125BA:
ROM4:A5BA STY object_x_2,X
 
ROM4:A5BC loc_125BC:
ROM4:A5BC LDA object_y_1,X
ROM4:A5BD SEC
ROM4:A5BE SBC object_y_2,X
ROM4:A5BF JSR absolute_value ; A = abs(A)
ROM4:A5C0 CMP byte_4DE
ROM4:A5C1 BCC loc_125D8
ROM4:A5C2 LDA object_y_2,X
ROM4:A5C3 TAY
ROM4:A5C4 INY
ROM4:A5C5 INY
ROM4:A5C6 CMP object_y_1,X
ROM4:A5C7 BCC loc_125D6
ROM4:A5C8 DEY
ROM4:A5C9 DEY
ROM4:A5CA DEY
ROM4:A5CB DEY
 
ROM4:A5D6 loc_125D6:
ROM4:A5D6 STY object_y_2,X
 
ROM4:A5D8 loc_125D8:
ROM4:A5D8 INX
ROM4:A5D9 CPX #4
ROM4:A5DA BNE loop1
ROM4:A5DB LDX #0
 
ROM4:A5DC loop2:
ROM4:A5DC JSR update_monster_gleeok_2a
ROM4:A5DD INX
ROM4:A5DE CPX #3
ROM4:A5DF BCC loop2
ROM4:A5E0 LDX #2
 
ROM4:A5E1 loop3:
ROM4:A5E1 TXA
ROM4:A5E2 TAY
ROM4:A5E3 LDA object_x_1
 
ROM4:A5E4 loop4:
ROM4:A5E4 CLC
ROM4:A5E5 ADC byte_4D8
ROM4:A5E6 DEY
ROM4:A5E7 BPL loop4
ROM4:A5E8 LDY object_x_2,X
ROM4:A5E9 INY
ROM4:A5EA CMP object_x_2,X
ROM4:A5EB BCS loc_125FD
ROM4:A5EC DEY
ROM4:A5ED DEY
 
ROM4:A5FD loc_125FD:
ROM4:A5FD STY object_x_2,X
ROM4:A5FE DEX
ROM4:A5FF BPL loop3
ROM4:A600 LDX #1 ; Loop X = 1 and 0
 
ROM4:A601 loop5:
ROM4:A601 LDA object_y_3,X
ROM4:A602 CMP object_y_2,X
ROM4:A603 BCS loc_12613
ROM4:A604 CMP object_y_4,X
ROM4:A605 BCS loc_1261D
ROM4:A606 INC object_y_3,X
ROM4:A607 JMP loc_1261D
 
ROM4:A613 loc_12613:
ROM4:A613 CMP object_y_2,X
ROM4:A614 BCC loc_1261D
ROM4:A615 CMP object_y_4,X
ROM4:A616 BCC loc_1261D
ROM4:A617 DEC object_y_3,X
 
ROM4:A61D loc_1261D:
ROM4:A61D DEX
ROM4:A61E BPL loop5
ROM4:A61F RTS
 
Subroutine update_monster_gleeok_2b
ROM4:A621 update_monster_gleeok_2b:
ROM4:A621 CMP #4
ROM4:A622 BCC not_4
ROM4:A623 LDA #4 ; A = 4
 
ROM4:A624 not_4:
ROM4:A624 STA byte_4D9,X
ROM4:A625 CLC
ROM4:A626 ADC #4 ; A += 4
ROM4:A627 CMP #8
ROM4:A628 BCC not_8
ROM4:A629 LDA #8 ; A = 8
 
ROM4:A62A not_8:
ROM4:A62A STA byte_4DB,X
ROM4:A62B CLC
ROM4:A62C ADC #4 ; A += 4
ROM4:A62D CMP #$B
ROM4:A62E BCC not_0x0B
ROM4:A62F LDA #$B ; A = 0x0B
 
ROM4:A630 not_0x0B:
ROM4:A630 STA byte_4DD,X
ROM4:A631 RTS
 
Subroutine update_monster_gleeok_2a
ROM4:A643 update_monster_gleeok_2a:
ROM4:A643 LDY #0
ROM4:A644 LDA object_x_3,X
ROM4:A645 SEC
ROM4:A646 SBC object_x_3,X
ROM4:A647 JSR absolute_value ; A = abs(A)
ROM4:A648 CMP byte_4D9
ROM4:A649 BCC loc_12653
ROM4:A64A INY
 
ROM4:A653 loc_12653:
ROM4:A653 CMP byte_4DB
ROM4:A654 BCC loc_12659
ROM4:A655 INY
 
ROM4:A659 loc_12659:
ROM4:A659 LDA object_y_3,X
ROM4:A65A SEC
ROM4:A65B SBC object_y_2,X
ROM4:A65C JSR absolute_value ; A = abs(A)
ROM4:A65D CMP byte_4DA
ROM4:A65E BCC loc_12669
ROM4:A65F INY
ROM4:A660 INY
ROM4:A661 INY
 
ROM4:A669 loc_12669:
ROM4:A669 CMP byte_4DC
ROM4:A66A BCC loc_12671
ROM4:A66B INY
ROM4:A66C INY
ROM4:A66D INY
 
ROM4:A671 loc_12671:
ROM4:A671 TYA
ROM4:A672 JSR call_jump_table
 
ROM4:A673   .WORD update_monster_gleeok_2a_0
ROM4:A675   .WORD update_monster_gleeok_2a_nop
ROM4:A677   .WORD update_monster_gleeok_2a_2
ROM4:A679   .WORD update_monster_gleeok_2a_nop
ROM4:A67B   .WORD update_monster_gleeok_2a_nop
ROM4:A67D   .WORD update_monster_gleeok_2a_2
ROM4:A67F   .WORD update_monster_gleeok_2a_6
ROM4:A681   .WORD update_monster_gleeok_2a_6
ROM4:A683   .WORD update_monster_gleeok_2a_8
 
Subroutine update_monster_gleeok_2a_0
ROM4:A687 update_monster_gleeok_2a_0:
ROM4:A687 LDA prng_0
ROM4:A688 BPL loc_126AA
ROM4:A689 LDA object_y_2,X
ROM4:A68A TAY
ROM4:A68B INY
ROM4:A68C INY
ROM4:A68D CMP object_y_3,X
ROM4:A68E BEQ loc_12696
ROM4:A68F BCS loc_1269A
 
ROM4:A696 loc_12696:
ROM4:A696 DEY
ROM4:A697 DEY
ROM4:A698 DEY
ROM4:A699 DEY
 
ROM4:A69A loc_1269A:
ROM4:A69A STY object_y_2,X
 
ROM4:A69C update_monster_gleeok_2a_nop:
ROM4:A69C RTS
 
Subroutine update_monster_gleeok_2a_6
ROM4:A69D update_monster_gleeok_2a_6:
ROM4:A69D LDA object_y_2,X
ROM4:A69E TAY
ROM4:A69F INY
ROM4:A6A0 INY
ROM4:A6A1 CMP object_y_3,X
ROM4:A6A2 BEQ loc_1269A
ROM4:A6A3 BCC loc_1269A
ROM4:A6A4 BCS loc_12696
 
ROM4:A6AA loc_126AA:
ROM4:A6AA LDA object_x_2,X
ROM4:A6AB TAY
ROM4:A6AC INY
ROM4:A6AD INY
ROM4:A6AE CMP object_x_3,X
ROM4:A6AF BCS loc_126C2
ROM4:A6B0 BCC loc_126BE
 
ROM4:A6B5 update_monster_gleeok_2a_2:
ROM4:A6B5 LDA object_x_2,X
ROM4:A6B6 TAY
ROM4:A6B7 INY
ROM4:A6B8 INY
ROM4:A6B9 CMP object_x_3,X
ROM4:A6BA BCC loc_126C2
 
ROM4:A6BE loc_126BE:
ROM4:A6BE DEY
ROM4:A6BF DEY
ROM4:A6C0 DEY
ROM4:A6C1 DEY
 
ROM4:A6C2 loc_126C2:
ROM4:A6C2 STY object_x_2,X
ROM4:A6C3 RTS
 
Subroutine update_monster_gleeok_2a_8
ROM4:A6C5 update_monster_gleeok_2a_8:
ROM4:A6C5 LDA prng_0
ROM4:A6C6 BPL update_monster_gleeok_2a_2
ROM4:A6C7 BMI update_monster_gleeok_2a_6 ; Always branch
 
Function chunk for gleeok_update_sprites_and_spawn_flying_heads
ROM4:A6C8 setup_gleeok_neck1_and_head_sprite: ; Part 1 (top neck segment) and 5 (the head) just draw where
ROM4:A6C8 LDY #3 ; the corresponding
ROM4:A6C9 STY var_3 ; Gleeok neck/head palette index
ROM4:A6CA PHA ; Push A (tile index)
ROM4:A6CB LDA processing_gleeok_head
ROM4:A6CC ASL A ; A = processing_gleeok_head * 8. This will be the
  ; sprite ID set below.
ROM4:A6CD ASL A
ROM4:A6CE ASL A
ROM4:A6CF CPX #5
ROM4:A6D0 BEQ part_5 ; Part 5 is the head.
ROM4:A6D1 CLC
ROM4:A6D2 ADC #$20 ; A += 0x20 for part 1. This is the neck segment
  ; closest to the body.
 
ROM4:A6D3 part_5:
ROM4:A6D3 TAY
ROM4:A6D4 PLA ; Pop A (tile index)
 
  ; update_monster_gleeok.loop1 set object 1's X/Y position
  ; to the position of
  ; This updates
ROM4:A6D5 JSR update_sprite_attributes_then_advance ; sprite_oam_data[Y+0] = object_y[X] (Y position)
  ; sprite_oam_data[Y+1] = A (tile index)
  ; sprite_oam_data[Y+2] = var_3 (tile attributes)
  ; sprite_oam_data[Y+3] = object_x[X] (X position)
ROM4:A6D6 JMP return_from_1_or_5
 
Subroutine gleeok_update_sprites_and_spawn_flying_heads
; Update sprites for this Gleeok head and neck. ; ; Check if this head has been killed and needs to be ; spawned as a flying head, and if the Gleeok is out ; of heads. ; ; processing_gleeok_head is set to the Gleeok head we're updating.
ROM4:A6E5 gleeok_update_sprites_and_spawn_flying_heads:
 
ROM4:A6E5 LDX #5
 
ROM4:A6E6 loop: ; Tile index 0xDA for parts other than #5 (Gleeok neck sprite)
ROM4:A6E6 LDA #$DA
ROM4:A6E7 CPX #5
ROM4:A6E8 BNE update_sprite
ROM4:A6E9 LDA #$DC ; Tile index 0xDC for part #5 (Gleeok head sprite)
 
ROM4:A6EA update_sprite:
ROM4:A6EA CPX #5
ROM4:A6EB BEQ setup_gleeok_neck1_and_head_sprite ; These branches jump back to return_from_1_or_5.
ROM4:A6EC CPX #1
ROM4:A6ED BEQ setup_gleeok_neck1_and_head_sprite ; Part 1 (top neck segment) and 5 (the head) just draw where
  ; the corresponding
ROM4:A6EE JSR setup_gleeok_middle_neck_sprites ; Otherwise, segment 2, 3 or 4
 
ROM4:A6EF return_from_1_or_5:
ROM4:A6EF CPX #5
ROM4:A6F0 BEQ update_part_1_or_5
ROM4:A6F1 CPX #1
ROM4:A6F2 BEQ update_part_1_or_5
ROM4:A6F3 JMP continue ; Skip for 2, 3 and 4
 
  ; The rest of this is for parts 1 and 5. 1 is the stationary
  ; head segment connected to the body, and 5 is the head. These
  ; are the only parts that can hit Link.
 
ROM4:A6F4 update_part_1_or_5: ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:A6F4 JSR check_enemy_hits
ROM4:A6F5 LDA object_knockback,X
ROM4:A6F6 BEQ not_hit
ROM4:A6F7 LDA #6 ; After Gleeok is hit, set these to 6 to speed up the body
  ; stepping animation briefly.
ROM4:A6F8 STA gleeok_body_animation_timer_or_lanmola_something ; Set to 6.
ROM4:A6F9 STA number_of_spawned_red_leevers_or_gleeok_fast_step_counter ; Set to 6
 
ROM4:A6FA not_hit: ; Set knockback to 0. This is called by monsters that don't
ROM4:A6FA JSR clear_knockback ; have knockback after hit.
ROM4:A6FB CPX #1
ROM4:A6FC BEQ set_not_dead_and_continue ; For X = 1, just mark this object not dead and continue.
ROM4:A6FD JSR play_boss_pain_sound_after_hit ; The rest of this is for part 5 only.
ROM4:A6FE LDA enemy_spawn_state,X ; If enemy_spawn_state has been set to nonzero by set_enemy_killed,
  ; the Gleeok ran out of health.
 
  ; Set the Gleeok back to 0x60 health and spawn a flying head.
ROM4:A6FF BEQ continue ; Branch if this is already set up (spawn state is 0).
ROM4:A700 LDA #$60
ROM4:A701 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM4:A702 TXA ; A = 5
ROM4:A703 PHA ; Push 5
ROM4:A704 CPX #5 ; Is it ever possible for X to not be 5 here?
ROM4:A705 BNE x_not_5
ROM4:A706 LDA processing_gleeok_head
ROM4:A707 CLC
ROM4:A708 ADC #7
ROM4:A709 TAX ; New head's object ID = head number + 7
ROM4:A70A LDA #$FF
ROM4:A70B STA object_slot_in_use,X ; Set to 0xFF
ROM4:A70C LDA object_x_5 ; Put the new head at the position of the old living one
ROM4:A70D STA object_x,X
ROM4:A70E LDA object_y_5
ROM4:A70F STA object_y,X
ROM4:A710 LDA #ObjectType_Gleeok_Flying_Head
ROM4:A711 STA object_type,X ; Set to ObjectType_Gleeok_Flying_Head
 
ROM4:A712 x_not_5:
ROM4:A712 PLA
ROM4:A713 TAX
ROM4:A714 LDA processing_gleeok_head
ROM4:A715 ASL A ; Head number * 8
ROM4:A716 ASL A
ROM4:A717 ASL A
ROM4:A718 TAY
ROM4:A719 LDA #$F8 ; Hide these sprites by setting Y offscreen
ROM4:A71A STA sprite_oam_data,Y ; Head
ROM4:A71B STA sprite_oam_data_20,Y ; Neck (closest to body)
ROM4:A71C LDY processing_gleeok_head
ROM4:A71D LDA powers_of_two,Y
ROM4:A71E ORA detached_gleeok_heads ; A mask of Gleeok heads that are detached and flying around the room
ROM4:A71F STA detached_gleeok_heads ; Mark this head as detached
ROM4:A720 STA var_0
ROM4:A721 LDA #0
ROM4:A722 LDY #4
 
ROM4:A723 loop2: ; Add the number of dead Gleeok heads (A = number of bits set in var_0).
ROM4:A723 LSR var_0
ROM4:A724 ADC #0
ROM4:A725 DEY
ROM4:A726 BNE loop2
ROM4:A727 STA var_0
ROM4:A728 LDA object_type_1
ROM4:A729 SEC
ROM4:A72A SBC #ObjectType_Moldorm ; A = object ID - ObjectType_Gleeok_1_Head + 1 = number of heads
ROM4:A72B CMP var_0 ; Compare the number of detached Gleeok heads to the original
  ; number of heads.
ROM4:A72C BEQ gleeok_dead ; If equal, the last Gleeok head was detached.
ROM4:A72D JMP set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
 
ROM4:A72E set_not_dead_and_continue: ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM4:A72E JSR set_enemy_spawn_state_to_spawned
 
ROM4:A72F continue:
ROM4:A72F DEX
ROM4:A730 CPX #1
ROM4:A731 BCC locret_127FA
ROM4:A732 JMP loop
 
ROM4:A733 gleeok_dead: ; The last Gleeok head was killed.
ROM4:A733 JSR setup_dungeon_only_sprites
ROM4:A734 JSR play_boss_sound_1
ROM4:A735 LDA #$11
ROM4:A736 STA enemy_spawn_state_1
ROM4:A737 LDY #1
 
ROM4:A738 loop3: ; Clear all the objects on the screen.
ROM4:A738 LDA #0
ROM4:A739 STA object_type_1,Y ; Set to 0
ROM4:A73A INY
ROM4:A73B CPY #$A
ROM4:A73C BCC loop3
ROM4:A73D RTS
 
Subroutine update_gleeok_head_and_necks_2
ROM4:A7A4 update_gleeok_head_and_necks_2:
ROM4:A7A4 LDA byte_418
ROM4:A7A5 BNE loc_127FB ; When is this set to nonzero? The only places currently
  ; referencing this are in unrelated text scrolling.
  ; Setting this would delay Gleeok updates for a while.
ROM4:A7A6 LDA object_x_5
ROM4:A7A7 LDY text_scroll_index ; The index of an old man message to display
ROM4:A7A8 JSR add_or_subtract_from_A
ROM4:A7A9 STA object_x_5
ROM4:A7AA LDA object_y_5
ROM4:A7AB LDY byte_416
ROM4:A7AC JSR add_or_subtract_from_A
ROM4:A7AD STA object_y_5
ROM4:A7AE INC byte_417
ROM4:A7AF LDA byte_417
ROM4:A7B0 CMP #4
ROM4:A7B1 BCC locret_127FA ; Branch if byte_417 < 4.
ROM4:A7B2 LDA #0
ROM4:A7B3 STA byte_417 ; Set to 0.
ROM4:A7B4 INC byte_413
ROM4:A7B5 LDA byte_413
ROM4:A7B6 CMP #$C
ROM4:A7B7 BCC loc_127E3 ; Branch if byte_413 < 0x0C.
ROM4:A7B8 LDA #0
ROM4:A7B9 STA byte_413 ; Set to 0.
ROM4:A7BA LDA text_scroll_index ; The index of an old man message to display
ROM4:A7BB EOR #$FF
ROM4:A7BC STA text_scroll_index ; The index of an old man message to display
 
ROM4:A7E3 loc_127E3:
ROM4:A7E3 INC byte_414
ROM4:A7E4 LDA byte_414
ROM4:A7E5 CMP #6
ROM4:A7E6 BCC locret_127FA
ROM4:A7E7 LDA #0
ROM4:A7E8 STA byte_414
ROM4:A7E9 LDA byte_416
ROM4:A7EA EOR #$FF
ROM4:A7EB STA byte_416
 
ROM4:A7FA locret_127FA:
ROM4:A7FA RTS
 
ROM4:A7FB loc_127FB:
ROM4:A7FB DEC byte_418
ROM4:A7FC RTS
 
ROM4:A7FD add_or_subtract_from_A:
ROM4:A7FD BNE subtract
ROM4:A7FE CLC ; Add 1 and return.
ROM4:A7FF ADC #1
ROM4:A800 RTS
 
ROM4:A801 subtract:
ROM4:A801 SEC
ROM4:A802 SBC #1 ; Subtract 1 and return.
ROM4:A803 RTS
 
ROM4:A809 gleeok_body_tiles: .BYTE $C0
ROM4:A80A   .BYTE $C4
ROM4:A80B   .BYTE $C8
ROM4:A80C   .BYTE $C2
ROM4:A80D   .BYTE $C6
ROM4:A80E   .BYTE $CA
ROM4:A80F   .BYTE $CC
ROM4:A810   .BYTE $C4
ROM4:A811   .BYTE $CE
ROM4:A812   .BYTE $C2
ROM4:A813   .BYTE $C6
ROM4:A814   .BYTE $D0
ROM4:A815   .BYTE $D2
ROM4:A816   .BYTE $D6
ROM4:A817   .BYTE $D8
ROM4:A818   .BYTE $D4
ROM4:A819   .BYTE $C6
ROM4:A81A   .BYTE $D0
ROM4:A81B byte_1281B: .BYTE 6
ROM4:A81C   .BYTE 0
ROM4:A81D   .BYTE 6
ROM4:A81E   .BYTE $C
 
Function chunk for update_gleeok_body
ROM4:A81F decrease_body_animation_timer:
ROM4:A81F DEC gleeok_body_animation_timer_or_lanmola_something
ROM4:A820 JMP loc_12844
 
Subroutine update_gleeok_body
; Update Gleeok's body sprites and animation.
ROM4:A825 update_gleeok_body:
 
ROM4:A825 LDA gleeok_body_animation_timer_or_lanmola_something
ROM4:A826 BNE decrease_body_animation_timer
ROM4:A827 LDA #$10
ROM4:A828 LDY number_of_spawned_red_leevers_or_gleeok_fast_step_counter
ROM4:A829 BEQ reset_animation_timer_and_increment_frame
ROM4:A82A DEC number_of_spawned_red_leevers_or_gleeok_fast_step_counter
ROM4:A82B LDA #6 ; If Gleeok was just hit, animate the body faster for a little while.
 
ROM4:A82C reset_animation_timer_and_increment_frame:
ROM4:A82C STA gleeok_body_animation_timer_or_lanmola_something
ROM4:A82D LDA gleeok_body_frame_or_lanmola_something ; Increase the body frame number.
ROM4:A82E CLC
ROM4:A82F ADC #1
ROM4:A830 AND #3
ROM4:A831 STA gleeok_body_frame_or_lanmola_something
 
ROM4:A844 loc_12844:
ROM4:A844 LDA #0
ROM4:A845 STA var_6
ROM4:A846 LDY gleeok_body_frame_or_lanmola_something
ROM4:A847 LDX byte_1281B,Y
 
ROM4:A848 loop1:
ROM4:A848 LDA #0
ROM4:A849 STA var_7
 
ROM4:A84A loop2:
ROM4:A84A LDY next_sprite_index
ROM4:A84B LDA sprite_index_to_left_half,Y
ROM4:A84C TAY
ROM4:A84D LDA var_6
ROM4:A84E ASL A
ROM4:A84F ASL A
ROM4:A850 ASL A
ROM4:A851 ASL A
ROM4:A852 ADC #$57
ROM4:A853 STA sprite_oam_data,Y
ROM4:A854 LDA gleeok_body_tiles,X
ROM4:A855 STA sprite_oam_data.tile,Y
ROM4:A856 LDA invincibility_frames_5 ; Load invincibility frames for object 5 for palette
  ; shifting the body on hit.
ROM4:A857 BNE loop3
ROM4:A858 LDA #3
 
ROM4:A859 loop3:
ROM4:A859 AND #3
ROM4:A85A STA sprite_oam_data.attr,Y
ROM4:A85B LDA 7
ROM4:A85C ASL A
ROM4:A85D ASL A
ROM4:A85E ASL A
ROM4:A85F ADC #$74
ROM4:A860 STA sprite_oam_data.x_pos,Y
ROM4:A861 INX
ROM4:A862 JSR set_next_sprite_index ; Increase next_sprite_index.
ROM4:A863 INC var_7
ROM4:A864 LDA var_7
ROM4:A865 CMP #3
ROM4:A866 BCC loop2
ROM4:A867 INC var_6
ROM4:A868 LDA var_6
ROM4:A869 CMP #2
ROM4:A86A BCC loop1
ROM4:A86B RTS
 
ROM4:A86C Skipped empty chunk
ROM4:A8BF zelda_flames_x: .BYTE $FF
ROM4:A8C0   .BYTE $78
ROM4:A8C1   .BYTE $60
ROM4:A8C2   .BYTE $70
ROM4:A8C3   .BYTE $80
ROM4:A8C4 zelda_flames_y: .BYTE $90
ROM4:A8C5   .BYTE $88
ROM4:A8C6   .BYTE $B5
ROM4:A8C7   .BYTE $9D
ROM4:A8C8   .BYTE $9D
ROM4:A8C9   .BYTE $B5
 
Subroutine spawn_zelda
ROM4:A8CA spawn_zelda:
ROM4:A8CA LDX #5 ; Spawn 5 flames
 
ROM4:A8CB loop:
ROM4:A8CB LDA zelda_flames_x,X
ROM4:A8CC STA object_x,X
ROM4:A8CD LDA zelda_flames_y,X
ROM4:A8CE STA object_y,X
ROM4:A8CF LDA #ObjectType_Flame
ROM4:A8D0 STA object_type,X ; Set to ObjectType_Flame
ROM4:A8D1 DEX
ROM4:A8D2 BNE loop
ROM4:A8D3 LDA #ObjectType_Zelda
ROM4:A8D4 STA object_type_1 ; Set to ObjectType_Zelda
ROM4:A8D5 RTS
 
Subroutine spawn_lanmola
ROM4:A8E4 spawn_lanmola:
ROM4:A8E4 LDY #var_9
 
ROM4:A8E6 loc_128E6:
ROM4:A8E6 LDA #$40
ROM4:A8E7 STA object_x_1,Y
ROM4:A8E8 LDA #$8D
ROM4:A8E9 STA object_y_1,Y
ROM4:A8EA LDA #0
ROM4:A8EB STA object_direction_1,Y
ROM4:A8EC STA enemy_spawn_state_1,Y
ROM4:A8ED STA byte_493,Y
ROM4:A8EE LDA enemy_state_9_1
ROM4:A8EF STA enemy_state_9_1,Y
ROM4:A8F0 LDA enemy_health_1
ROM4:A8F1 STA enemy_health_1,Y
ROM4:A8F2 LDA object_type_1
ROM4:A8F3 STA object_type_1,Y ; Make another Lanmola piece
ROM4:A8F4 DEY
ROM4:A8F5 BPL loc_128E6
ROM4:A8F6 LDA #8
ROM4:A8F7 STA object_direction_1+4
ROM4:A8F8 STA unk_385
ROM4:A8F9 STA projectile_direction_mask+3
ROM4:A8FA STA unk_38A
ROM4:A8FB LDA object_type_1
ROM4:A8FC STA gleeok_body_frame_or_lanmola_something
ROM4:A8FD SEC
ROM4:A8FE SBC #$39
ROM4:A8FF STA gleeok_body_animation_timer_or_lanmola_something
ROM4:A900 LDA #8
ROM4:A901 STA total_enemies_spawned_in_room
ROM4:A902 RTS
 
Subroutine spawn_patra
ROM4:A92E spawn_patra:
ROM4:A92E LDA #$FE
ROM4:A92F STA damage_types_with_no_knockback,X ; Set to 0xFE.
ROM4:A930 LDA #$80
ROM4:A931 STA object_x,X
ROM4:A932 LDA #$70
ROM4:A933 STA object_y,X
ROM4:A934 LDA #8
ROM4:A935 STA object_direction,X
ROM4:A936 LDA #$1F
ROM4:A937 STA enemy_projectile_speed_x,X
ROM4:A938 LDA #Sound0_BossRoar3
ROM4:A939 STA increase_enemy_speed_max ; Set to 0x1F.
ROM4:A93A STA play_sound_0 ; Play Sound0_BossRoar3
ROM4:A93B LDA #$FF
ROM4:A93C STA npc_action_timer_1,X ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:A93D LDA #ObjectType_Patra_Eye_1 ; Eyes used by ObjectType_Patra_1.
ROM4:A93E LDY object_type_1
ROM4:A93F CPY #ObjectType_Patra_1
ROM4:A940 BEQ is_patra_2
ROM4:A941 LDA #ObjectType_Patra_Eye_2 ; Eyes used by ObjectType_Patra_2.
 
ROM4:A942 is_patra_2: ; Create Patra eyes in slots 2-9.
ROM4:A942 LDY #2
ROM4:A943 STA var_0
 
ROM4:A944 loop:
ROM4:A944 LDA var_0
ROM4:A945 STA object_type,Y ; Set to ObjectType_Patra_Eye_1 or ObjectType_Patra_Eye_2.
ROM4:A946 LDA #DamageType_Boomerang|DamageType_Arrow|DamageType_Bomb|DamageType_Rod|DamageType_Fire|DamageType_Unknown_40|DamageType_Unknown_80
ROM4:A947 STA damage_types_with_no_knockback,Y ; Set to 0xFE.
ROM4:A948 INY
ROM4:A949 CPY #10
ROM4:A94A BNE loop
ROM4:A94B RTS
 
Subroutine spawn_ganon
ROM4:A96F spawn_ganon:
ROM4:A96F LDA #DamageType_Boomerang|DamageType_Bomb|DamageType_Rod|DamageType_Fire|DamageType_Unknown_40|DamageType_Unknown_80
ROM4:A970 STA damage_types_with_no_knockback,X ; Set to 0xFA
ROM4:A971 LDA #WalkState_3_MovementLocked
ROM4:A972 STA walk_state_and_weapon_state ; Lock movement while spawning Ganon
ROM4:A973 STA enemy_action_timers ; Set Link's action timer to 0x40
ROM4:A974 LDA #Sound0_BossPainSound
ROM4:A975 STA play_sound_0 ; Play Sound0_BossSound1 during Ganon spawn
ROM4:A976 LDA #Sound0_BossRoar1
ROM4:A977 JSR add_mask_to_play_sound_0 ; play_sound_0 |= A
ROM4:A978 JMP spawn_monster_no_timer_no_spawn_cloud
 
Subroutine update_monster_zelda
ROM4:A987 update_monster_zelda:
ROM4:A987 JSR update_sprite_zelda_wall_trap
ROM4:A988 LDA walk_state_and_weapon_state,X ; Check if we already triggered Zelda
ROM4:A989 BNE zelda_already_triggered
ROM4:A98A LDA object_x ; Check if Link is near Zelda
ROM4:A98B CMP #$70
ROM4:A98C BCC update_monster_zelda_ret ; x < 0x70
ROM4:A98D CMP #$81 ; x <= 0x81
ROM4:A98E BCS update_monster_zelda_ret ; x >= 0x81
ROM4:A98F LDA object_y
ROM4:A990 CMP #$95
ROM4:A991 BNE update_monster_zelda_ret ; y >= 0x95
ROM4:A992 INC walk_state_and_weapon_state,X ; Mark that zelda was triggered
ROM4:A993 LDA #$40
ROM4:A994 STA walk_state_and_weapon_state ; Lock walking
ROM4:A995 LDA #$88
ROM4:A996 STA object_x ; Teleport link next to zelda
ROM4:A997 STA object_y
ROM4:A998 LDA #ControllerBits_Dpad_Left
ROM4:A999 STA object_direction ; Point link at zelda
ROM4:A99A LDA #Music_Victory
ROM4:A99B STA play_music ; Play Music_Victory
ROM4:A99C LDA #$80
ROM4:A99D STA enemy_action_timers,X ; Wait 0x80 frames after triggering zelda
 
ROM4:A99E update_monster_zelda_ret:
ROM4:A99E RTS
 
ROM4:A99F zelda_already_triggered:
ROM4:A99F JSR sub_1F229
ROM4:A9A0 LDA enemy_action_timers,X
ROM4:A9A1 BNE update_monster_zelda_ret ; keep waiting
ROM4:A9A2 STA active_game_mode_task ; Set to 0
ROM4:A9A3 STA task_state ; Set to 0
ROM4:A9A4 STA walk_state_and_weapon_state ; Set to 0
ROM4:A9A5 LDA #GameMode_FoundZelda
ROM4:A9A6 STA game_mode ; set GameMode_FoundZelda
ROM4:A9A7 LDA #$20
ROM4:A9A8 STA object_x_12 ; Set to 0x20
ROM4:A9A9 LDA #1
ROM4:A9AA STA link_melee_x ; Set to 1
ROM4:A9AB LDA #$24
ROM4:A9AC STA var_10 ; Set to 0x24
ROM4:A9AD JMP clear_room_tiles_to_var_10 ; Clear the current room's tile data (0x6530-0x67EF) to var_10.
 
Subroutine update_monster_flame
ROM4:A9D8 update_monster_flame:
ROM4:A9D8 LDA #6
ROM4:A9D9 JSR update_sprite_bubble_stalfos_flame_patra
ROM4:A9DA JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:A9DB LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:A9DC BEQ locret_129EA
 
ROM4:A9E5 store_enemy_death:
ROM4:A9E5 LDA #ObjectType_EnemyDeath
ROM4:A9E6 STA object_type,X ; Set to ObjectType_EnemyDeath
 
ROM4:A9EA locret_129EA:
ROM4:A9EA RTS
 
Subroutine update_monster_lanmola
ROM4:A9EB update_monster_lanmola:
ROM4:A9EB LDA object_direction,X ; Return if object_direction is 0.
ROM4:A9EC BEQ locret_129EA
ROM4:A9ED LDA clock_active
ROM4:A9EE BNE skip_update ; Skip if the clock is active
ROM4:A9EF JSR update_monster_lanmola_1
ROM4:A9F0 CPX #5 ; Only run the below update for object IDs 0x05 and 0x0A.
ROM4:A9F1 BEQ do_update
ROM4:A9F2 CPX #$A
ROM4:A9F3 BNE skip_update
 
ROM4:A9F4 do_update:
ROM4:A9F4 JSR update_monster_lanmola_0
 
ROM4:A9F5 skip_update:
ROM4:A9F5 LDA object_x,X
ROM4:A9F6 PHA
ROM4:A9F7 CLC
ROM4:A9F8 ADC #4
ROM4:A9F9 STA object_x,X
ROM4:A9FA LDA gleeok_body_animation_timer_or_lanmola_something
ROM4:A9FB EOR #3
ROM4:A9FC STA var_3 ; Lanmola's palette index
ROM4:A9FD LDA #$9E
ROM4:A9FE CPX #5
ROM4:A9FF BEQ loc_12A1D
ROM4:AA00 CPX #$A
ROM4:AA01 BEQ loc_12A1D
ROM4:AA02 LDA #$A0
 
ROM4:AA1D loc_12A1D:
ROM4:AA1D JSR setup_sprites_ganon_moldorm_lanmola
ROM4:AA1E PLA
ROM4:AA1F STA object_x,X
ROM4:AA20 LDA object_direction,X
ROM4:AA21 PHA
ROM4:AA22 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:AA23 PLA
ROM4:AA24 STA object_direction,X
ROM4:AA25 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:AA26 BEQ locret_129EA
ROM4:AA27 JSR clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
ROM4:AA28 LDA #$20
ROM4:AA29 STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM4:AA2A LDY #$FF
ROM4:AA2B CPX #6
ROM4:AA2C BCC loc_12A41
ROM4:AA2D LDY #4
 
ROM4:AA41 loc_12A41:
ROM4:AA41 INY
ROM4:AA42 LDA object_type_1,Y
ROM4:AA43 CMP gleeok_body_frame_or_lanmola_something
ROM4:AA44 BNE loc_12A41
ROM4:AA45 LDA #$11
ROM4:AA46 STA npc_action_timer_1,Y ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:AA47 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:AA48 STA invincibility_frames_1,Y
ROM4:AA49 LDA object_x,X
ROM4:AA4A STA object_x_1,Y
ROM4:AA4B LDA object_y,X
ROM4:AA4C STA object_y_1,Y
ROM4:AA4D CPY #4
ROM4:AA4E BEQ locret_129EA
ROM4:AA4F CPY #9
ROM4:AA50 BEQ locret_129EA
ROM4:AA51 LDA #ObjectType_EnemyDeath
ROM4:AA52 STA object_type_1,Y ; Set to ObjectType_EnemyDeath
ROM4:AA53 JMP set_enemy_spawn_state_to_spawned ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
 
ROM4:AA6F locret_12A6F:
ROM4:AA6F RTS
 
Subroutine update_monster_lanmola_0
ROM4:AA70 update_monster_lanmola_0:
ROM4:AA70 LDA object_x,X
ROM4:AA71 AND #7
ROM4:AA72 BNE locret_12A6F
ROM4:AA73 LDA object_y,X
ROM4:AA74 CLC
ROM4:AA75 ADC #3
ROM4:AA76 AND #7
ROM4:AA77 BNE locret_12A6F
ROM4:AA78 LDA #4
ROM4:AA79 STA var_0
ROM4:AA7A LDY #0
ROM4:AA7B CPX #5
ROM4:AA7C BEQ loc_12A8B
ROM4:AA7D LDY #5
 
ROM4:AA8B loc_12A8B:
ROM4:AA8B LDA object_direction_1+1,Y
ROM4:AA8C STA object_direction_1,Y
ROM4:AA8D INY
ROM4:AA8E DEC var_0
ROM4:AA8F BNE loc_12A8B
ROM4:AA90 LDA object_x,X
ROM4:AA91 AND #$F
ROM4:AA92 BNE ret
ROM4:AA93 LDA object_y,X
ROM4:AA94 CLC
ROM4:AA95 ADC #3
ROM4:AA96 AND #$F
ROM4:AA97 BNE ret
ROM4:AA98 LDA object_direction,X
ROM4:AA99 LSR A
ROM4:AA9A AND #5
ROM4:AA9B STA var_0
ROM4:AA9C LDA object_direction,X
ROM4:AA9D ASL A
ROM4:AA9E AND #$A
ROM4:AA9F ORA var_0
ROM4:AAA0 EOR #$F
ROM4:AAA1 STA byte_50F
ROM4:AAA2 LDA prng_0,X
ROM4:AAA3 CMP #$80
ROM4:AAA4 BCC loc_12AFA
ROM4:AAA5 LDA object_direction,X
ROM4:AAA6 LDY prng_1,X
ROM4:AAA7 CPY #$80
ROM4:AAA8 BCS loc_12AD8
 
ROM4:AAA9 loop:
ROM4:AAA9 LSR A
ROM4:AAAA BCC loc_12ACB
ROM4:AAAB LDA #8
 
ROM4:AACB loc_12ACB:
ROM4:AACB BIT byte_50F
ROM4:AACC BEQ loop
ROM4:AACD CPY #$40
ROM4:AACE BCS loc_12AD8
ROM4:AACF LDY #$40
ROM4:AAD0 BCC loop
 
ROM4:AAD8 loc_12AD8:
ROM4:AAD8 STA object_direction,X
ROM4:AAD9 STA var_15
ROM4:AADA JSR check_object_against_screen_bounding_box_both ; If the current object is out of the bounding box for the
  ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM4:AADB LDA var_15
ROM4:AADC BNE loc_12AF1
 
ROM4:AADD loop2:
ROM4:AADD LDA object_direction,X
 
ROM4:AADE loop3:
ROM4:AADE LSR A
ROM4:AADF BCC loc_12AEA
ROM4:AAE0 LDA #8
 
ROM4:AAEA loc_12AEA:
ROM4:AAEA BIT byte_50F
ROM4:AAEB BNE loc_12AD8
ROM4:AAEC BEQ loop3
 
ROM4:AAF1 loc_12AF1: ; Set tile_walking_onto for the current object.
ROM4:AAF1 JSR set_tile_walking_onto_2 ; The caller sets var_15 to the walking direction.
ROM4:AAF2 CMP screen_first_solid_tile_id
ROM4:AAF3 BCS loop2
 
ROM4:AAF4 ret:
ROM4:AAF4 RTS
 
ROM4:AAFA loc_12AFA:
ROM4:AAFA LDA #1
ROM4:AAFB STA var_2
ROM4:AAFC LDA object_x
ROM4:AAFD SEC
ROM4:AAFE SBC object_x,X
ROM4:AAFF BCS loc_12B07
ROM4:AB00 ASL var_2
 
ROM4:AB07 loc_12B07:
ROM4:AB07 LDA #4
ROM4:AB08 STA var_3
ROM4:AB09 LDA object_y
ROM4:AB0A SEC
ROM4:AB0B SBC object_y,X
ROM4:AB0C BCS loc_12B14
ROM4:AB0D ASL var_3
 
ROM4:AB14 loc_12B14:
ROM4:AB14 LDA var_2
ROM4:AB15 BIT byte_50F
ROM4:AB16 BEQ loc_12B1F
ROM4:AB17 BIT object_direction
ROM4:AB18 BNE ret2
 
ROM4:AB1F loc_12B1F:
ROM4:AB1F LDA var_3
 
ROM4:AB20 ret2:
ROM4:AB20 JMP loc_12AD8
 
Subroutine update_monster_lanmola_1
ROM4:AB24 update_monster_lanmola_1:
ROM4:AB24 LDA #$A1
ROM4:AB25 STA var_2
ROM4:AB26 LDA object_direction,X
ROM4:AB27 BIT var_2
ROM4:AB28 BEQ loc_12B36
ROM4:AB29 LDA object_x,X
ROM4:AB2A CLC
ROM4:AB2B ADC gleeok_body_animation_timer_or_lanmola_something
ROM4:AB2C STA object_x,X
 
ROM4:AB36 loc_12B36:
ROM4:AB36 LDA object_direction,X
ROM4:AB37 ASL var_2
ROM4:AB38 BIT var_2
ROM4:AB39 BEQ loc_12B45
ROM4:AB3A LDA object_x,X
ROM4:AB3B SBC gleeok_body_animation_timer_or_lanmola_something
ROM4:AB3C STA object_x,X
 
ROM4:AB45 loc_12B45:
ROM4:AB45 LDA object_direction,X
ROM4:AB46 ASL var_2
ROM4:AB47 BIT var_2
ROM4:AB48 BEQ loc_12B54
ROM4:AB49 LDA object_y,X
ROM4:AB4A ADC gleeok_body_animation_timer_or_lanmola_something
ROM4:AB4B STA object_y,X
 
ROM4:AB54 loc_12B54:
ROM4:AB54 LDA object_direction,X
ROM4:AB55 ASL var_2
ROM4:AB56 BIT var_2
ROM4:AB57 BEQ ret
ROM4:AB58 LDA object_y,X
ROM4:AB59 SBC gleeok_body_animation_timer_or_lanmola_something
ROM4:AB5A STA object_y,X
 
ROM4:AB5B ret:
ROM4:AB5B RTS
 
ROM4:AB64 byte_12B64: .BYTE $FF
ROM4:AB65   .BYTE $50
 
Subroutine update_monster_patra
ROM4:AB66 update_monster_patra:
ROM4:AB66 JSR loc_12BAE
ROM4:AB67 LDA #0
ROM4:AB68 STA enemy_state_1,X
ROM4:AB69 STA enemy_blind_projectile_timer,X
ROM4:AB6A JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
ROM4:AB6B LDA #2
ROM4:AB6C JSR update_sprite_bubble_stalfos_flame_patra
ROM4:AB6D LDY #8 ; Check each object slot that can hold a Patra eye
 
ROM4:AB6E loop: ; Check if ObjectType_Patra_Eye_1 or ObjectType_Patra_Eye_2.
ROM4:AB6E LDA object_type_1,Y
ROM4:AB6F CMP #ObjectType_Patra_Eye_1 ; If we find any, check damage from Patra to Link but skip checking damage from Link to Patra.
ROM4:AB70 BEQ skip_damage_against_patra
ROM4:AB71 CMP #ObjectType_Patra_Eye_2 ; Eyes used by ObjectType_Patra_2.
ROM4:AB72 BEQ skip_damage_against_patra
ROM4:AB73 DEY
ROM4:AB74 BNE loop
ROM4:AB75 JSR check_enemy_hits ; Only check for hits against Patra after all of its eyes are dead.
ROM4:AB76 JSR play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:AB77 JSR play_boss_sound_1_if_not_state_0
ROM4:AB78 JMP skip_checking_link_hit_by_enemy
 
ROM4:AB79 skip_damage_against_patra: ; Check if Link was hit by an enemy. X is the enemy we're
ROM4:AB79 JSR check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
 
ROM4:AB7A skip_checking_link_hit_by_enemy: ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM4:AB7A LDA npc_action_timer_1,X
ROM4:AB7B ORA object_tile_offset_whole_3
ROM4:AB7C BNE locret_12BAD
ROM4:AB7D LDA enemy_state_2,X
ROM4:AB7E EOR #1
ROM4:AB7F STA enemy_state_2,X
ROM4:AB80 TYA
ROM4:AB81 LDA byte_12B64,Y
ROM4:AB82 STA npc_action_timer_1,X ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
 
ROM4:ABAD locret_12BAD:
ROM4:ABAD RTS
 
ROM4:ABAE loc_12BAE:
ROM4:ABAE LDA enemy_state_6,X
ROM4:ABAF JSR call_jump_table
 
ROM4:ABB0   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:ABB2   .WORD update_monster_patra_choose_random_state ; Randomly choose whether to go to state 2 or 3.
ROM4:ABB4   .WORD update_monster_diagonal_movement_relative_to_seek ; Update the current enemy's direction relative to the seek
  ; position with diagonal movement. This isn't fully traced.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
ROM4:ABB6   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
 
Subroutine update_monster_patra_choose_random_state
; Randomly choose whether to go to state 2 or 3.
ROM4:ABBC update_monster_patra_choose_random_state:
ROM4:ABBC LDY #2
ROM4:ABBD LDA prng_0,X
ROM4:ABBE CMP #$40 ; If random value >= 0x40, 2
ROM4:ABBF BCS set_state
ROM4:ABC0 INY ; Move to state 3
 
ROM4:ABC1 set_state:
ROM4:ABC1 TYA
ROM4:ABC2 STA enemy_state_6,X
ROM4:ABC3 LDA #8
ROM4:ABC4 STA enemy_state_4,X
ROM4:ABC5 RTS
 
ROM4:ABCF byte_12BCF: .BYTE $14
ROM4:ABD0   .BYTE $10
ROM4:ABD1   .BYTE $C
ROM4:ABD2   .BYTE 8
ROM4:ABD3   .BYTE 4
ROM4:ABD4   .BYTE 0
ROM4:ABD5   .BYTE $1C
ROM4:ABD6 byte_12BD6: .BYTE 6
ROM4:ABD7 byte_12BD7: .BYTE 5
ROM4:ABD8 byte_12BD8: .BYTE 6
ROM4:ABD9   .BYTE 6
 
Subroutine update_monster_patra_eye
ROM4:ABDA update_monster_patra_eye:
ROM4:ABDA LDA walk_state_and_weapon_state,X
ROM4:ABDB BNE enemy_state_nonzero
ROM4:ABDC CPX #2
ROM4:ABDD BEQ is_enemy_2
ROM4:ABDE LDA enemy_state_10_2
ROM4:ABDF BEQ ret
ROM4:ABE0 TXA
ROM4:ABE1 SEC
ROM4:ABE2 SBC #3
ROM4:ABE3 TAY
ROM4:ABE4 LDA object_tile_offset_whole_2
ROM4:ABE5 CMP byte_12BCF,Y
ROM4:ABE6 BNE ret
 
ROM4:ABE7 is_enemy_2:
ROM4:ABE7 CPX #9
ROM4:ABE8 BNE not_enemy_9
ROM4:ABE9 INC global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
 
ROM4:ABEA not_enemy_9:
ROM4:ABEA INC walk_state_and_weapon_state,X
ROM4:ABEB LDA #$80
ROM4:ABEC STA object_direction,X
ROM4:ABED LDA #$18
ROM4:ABEE STA object_tile_offset_whole,X ; Set to 0x18
ROM4:ABEF LDA object_x_1
ROM4:ABF0 STA object_x,X
ROM4:ABF1 LDA #44
ROM4:ABF2 LDY object_type,X ; Check if ObjectType_Patra_Eye_1
ROM4:ABF3 CPY #ObjectType_Patra_Eye_1 ; Eyes used by ObjectType_Patra_1.
ROM4:ABF4 BEQ is_eye_type_1
ROM4:ABF5 LDA #24
 
ROM4:ABF6 is_eye_type_1: ; Move Patra eye up by 44 (type 1) or 24 (type 2) pixels.
ROM4:ABF6 STA var_0
ROM4:ABF7 LDA object_y_1
ROM4:ABF8 SEC
ROM4:ABF9 SBC var_0
ROM4:ABFA STA object_y,X
 
ROM4:ABFB ret:
ROM4:ABFB RTS
 
ROM4:ABFC enemy_state_nonzero: ; Move Patra eye right by enemy_state_1_1
ROM4:ABFC LDA object_x,X
ROM4:ABFD CLC
ROM4:ABFE ADC enemy_state_1_1
ROM4:ABFF STA object_x,X
ROM4:AC00 LDA object_y,X ; Move Patra eye down by byte_479
ROM4:AC01 CLC
ROM4:AC02 ADC enemy_blind_projectile_timer_1
ROM4:AC03 STA object_y,X
ROM4:AC04 LDA #0
ROM4:AC05 STA var_11 ; Set to 0
ROM4:AC06 LDA #$70
ROM4:AC07 LDY object_type,X ; Check if ObjectType_Patra_Eye_1.
ROM4:AC08 CPY #ObjectType_Patra_Eye_1 ; Eyes used by ObjectType_Patra_1.
ROM4:AC09 BEQ is_eye_type_1a
ROM4:AC0A LDA #$60
 
ROM4:AC0B is_eye_type_1a:
ROM4:AC0B JSR update_spinning_hearts_patra_1
ROM4:AC0C LDY enemy_state_2_1
ROM4:AC0D LDA object_type,X ; Check if ObjectType_Patra_Eye_1.
ROM4:AC0E CMP #ObjectType_Patra_Eye_1 ; Eyes used by ObjectType_Patra_1.
ROM4:AC0F BNE is_eye_type_2
ROM4:AC10 LDA byte_12BD6,Y
ROM4:AC11 PHA
ROM4:AC12 LDA byte_12BD8,Y
ROM4:AC13 TAY
ROM4:AC14 PLA
ROM4:AC15 JMP not_eye_type_2
 
ROM4:AC16 is_eye_type_2:
ROM4:AC16 LDA byte_12BD7,Y
ROM4:AC17 TAY
 
ROM4:AC18 not_eye_type_2:
ROM4:AC18 JSR update_spinning_hearts_patra_2
ROM4:AC19 STA object_y,X
ROM4:AC1A JSR update_patra_eye_sprite
ROM4:AC1B LDA global_room_state ; Global room state. This is used by the fairy lake, stores, etc.
ROM4:AC1C BEQ ret2 ; Branch if room state is 0
ROM4:AC1D JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
ROM4:AC1E LDA enemy_spawn_state,X ; Check if the eye is dead
ROM4:AC1F BEQ ret2
ROM4:AC20 JSR store_enemy_death ; If dead, replace with ObjectType_EnemyDeath
 
ROM4:AC21 ret2:
ROM4:AC21 RTS
 
Subroutine update_patra_eye_sprite
ROM4:AC71 update_patra_eye_sprite:
ROM4:AC71 JSR store_palette_2_in_tile_attributes ; Store 0x2 in var_4 and var_5, and set A to 2.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:AC72 JSR update_object_animation_frame
ROM4:AC73 LDA object_animation_frame,X
ROM4:AC74 JMP update_object_sprite_horizontal
 
Subroutine update_monster_ganon
ROM4:AC7D update_monster_ganon:
ROM4:AC7D LDA enemy_state_6_1
ROM4:AC7E JSR call_jump_table
 
ROM4:AC7F   .WORD update_monster_ganon_0_start_cutscene ; Set Link to holding the triforce over his head, run the room palette shift as
  ; if a candle was used, start the "found Ganon" music, and then moves on to state
  ; 1 once the palette shift has finished.
ROM4:AC81   .WORD update_monster_ganon_1_wait_for_music_to_finish ; Link continues holding up the Triforce, Ganon appears, then
  ; Link puts down the Triforce once enemy_action_timers expires
  ; and move on to state 2.
ROM4:AC83   .WORD update_monster_ganon_2_main_combat ; This is the combat update for Ganon.
 
Subroutine update_monster_ganon_0_start_cutscene
; Set Link to holding the triforce over his head, run the room palette shift as ; if a candle was used, start the "found Ganon" music, and then moves on to state ; 1 once the palette shift has finished.
ROM4:AC89 update_monster_ganon_0_start_cutscene:
ROM4:AC89 LDA #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
ROM4:AC8A STA picking_up_item ; Set to InventoryItem_HoldingUpTriforce.
ROM4:AC8B LDA enemy_action_timers
ROM4:AC8C BNE waiting_for_action_timer ; Branch if we're still waiting for the action timer
  ; to expire. This lets the Ganon fanfare play for a
  ; while.
ROM4:AC8D TXA
ROM4:AC8E PHA ; Save our object ID.
ROM4:AC8F JSR update_lighting_room
ROM4:AC90 PLA
ROM4:AC91 TAX ; Restore our object ID.
ROM4:AC92 LDA #0
ROM4:AC93 STA paused_lighting_dungeon_room ; This is 1 while the candle palette shift is happening to
  ; light a dungeon room. The game doesn't update until this
  ; is set back to 0.
ROM4:AC94 LDA next_palette_cycle ; If next_palette_cycle is 0xC0, the palette cycle was just
  ; begun by update_lighting_room, which means the cutscene just
  ; started. Start the music.
ROM4:AC95 CMP #$C0
ROM4:AC96 BNE already_started_music
ROM4:AC97 LDA #Music_FoundGanon
ROM4:AC98 STA play_music ; Play Music_FoundGanon
 
ROM4:AC99 already_started_music:
ROM4:AC99 LDA next_palette_cycle
ROM4:AC9A AND #$F
ROM4:AC9B CMP #4
ROM4:AC9C BNE ganon_1_waiting_for_action_timer
ROM4:AC9D LDA #$C0
ROM4:AC9E STA enemy_action_timers
ROM4:AC9F INC enemy_state_6_1 ; Move on to state 1.
ROM4:ACA0 BNE ganon_1_waiting_for_action_timer
 
ROM4:ACA1 waiting_for_action_timer:
ROM4:ACA1 CMP #1
ROM4:ACA2 BNE ret
ROM4:ACA3 LDA #Sound0_BossPainSound
ROM4:ACA4 STA play_sound_0 ; Play Sound0_BossSound1 on the last frame before the
  ; action timer expires.
 
ROM4:ACA5 ret:
ROM4:ACA5 RTS
 
Subroutine update_monster_ganon_1_wait_for_music_to_finish
; Link continues holding up the Triforce, Ganon appears, then ; Link puts down the Triforce once enemy_action_timers expires ; and move on to state 2.
ROM4:ACC6 update_monster_ganon_1_wait_for_music_to_finish:
ROM4:ACC6 LDA #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
ROM4:ACC7 STA picking_up_item ; Set to InventoryItem_HoldingUpTriforce.
ROM4:ACC8 LDA enemy_action_timers
ROM4:ACC9 BNE ganon_1_waiting_for_action_timer
ROM4:ACCA STA walk_state_and_weapon_state ; Unlock movement, since it was locked by holding up the Triforce.
ROM4:ACCB STA picking_up_item ; Set to 0 to stop holding up the Triforce.
ROM4:ACCC LDA #Music_DeathMountain
ROM4:ACCD STA play_music ; Restore Music_DeathMountain after Ganon fanfare.
ROM4:ACCE INC enemy_state_6_1 ; Move on to state 2.
 
ROM4:ACDC ganon_1_waiting_for_action_timer:
ROM4:ACDC LDA #0
ROM4:ACDD STA enemy_state_1,X ; Set to 0
ROM4:ACDE JMP update_ganon_sprite
 
Subroutine update_monster_ganon_2_main_combat
; This is the combat update for Ganon.
ROM4:ACE4 update_monster_ganon_2_main_combat:
 
ROM4:ACE4 LDA enemy_state_4,X
ROM4:ACE5 BNE loc_12D4D
ROM4:ACE6 JSR update_monster_ganon_2g
ROM4:ACE7 JSR play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:ACE8 LDA walk_state_and_weapon_state,X
ROM4:ACE9 BNE loc_12D2F
ROM4:ACEA LDA enemy_action_timers,X
ROM4:ACEB BEQ loc_12D0A
ROM4:ACEC CMP #1
ROM4:ACED BNE loc_12D49
 
ROM4:ACFB loc_12CFB:
ROM4:ACFB LDA #$A0
ROM4:ACFC STA object_y,X
ROM4:ACFD LDA frame_counter
ROM4:ACFE AND #1
ROM4:ACFF TAY
ROM4:AD00 LDA byte_12D2D,Y
ROM4:AD01 STA object_x,X
ROM4:AD02 RTS
 
ROM4:AD0A loc_12D0A:
ROM4:AD0A INC enemy_state_1,X
ROM4:AD0B LDA enemy_state_1,X
ROM4:AD0C CMP #6
ROM4:AD0D BNE loc_12D19
ROM4:AD0E LDA #0
ROM4:AD0F STA enemy_state_1,X
 
ROM4:AD19 loc_12D19:
ROM4:AD19 LDA #1
ROM4:AD1A STA object_tile_offset_whole,X
ROM4:AD1B JSR update_from_ganon
ROM4:AD1C LDA frame_counter
ROM4:AD1D AND #$3F
ROM4:AD1E BNE locret_12D2C
ROM4:AD1F LDA #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
ROM4:AD20 JSR create_fireball_near_object ; Create a ObjectType_Homing_Fireball_2.
 
ROM4:AD2C locret_12D2C:
ROM4:AD2C RTS
 
ROM4:AD2D byte_12D2D: .BYTE $30
ROM4:AD2E   .BYTE $B0
 
ROM4:AD2F loc_12D2F:
ROM4:AD2F LDA frame_counter
ROM4:AD30 LSR A
ROM4:AD31 BCC loc_12D3E ; Branch if even frame
ROM4:AD32 DEC walk_state_and_weapon_state,X
ROM4:AD33 BNE loc_12D3E
ROM4:AD34 JSR loc_12CFB
ROM4:AD35 JMP loc_12F71
 
ROM4:AD3E loc_12D3E:
ROM4:AD3E LDA walk_state_and_weapon_state,X
ROM4:AD3F CMP #$30
ROM4:AD40 BCS loc_12D49
ROM4:AD41 LDA frame_counter
ROM4:AD42 LSR A
ROM4:AD43 BCC ret2 ; Branch if even frame
 
ROM4:AD49 loc_12D49:
ROM4:AD49 JSR update_ganon_sprite
 
ROM4:AD4A ret2:
ROM4:AD4A RTS
 
ROM4:AD4D loc_12D4D:
ROM4:AD4D INC enemy_state_4,X
ROM4:AD4E LDA enemy_state_4,X
ROM4:AD4F BNE state_4_not_zero
ROM4:AD50 LDA #$FF
ROM4:AD51 STA enemy_state_4,X ; Set to 0xFF
 
ROM4:AD52 state_4_not_zero:
ROM4:AD52 CMP #$50
ROM4:AD53 BCC loc_12D49
ROM4:AD54 BNE loc_12D7A
ROM4:AD55 JSR loc_12F75
ROM4:AD56 LDA object_x,X
ROM4:AD57 ADC #7
ROM4:AD58 STA object_x,X
ROM4:AD59 LDA object_y,X
ROM4:AD5A ADC #8
ROM4:AD5B STA object_y,X
ROM4:AD5C JSR update_monster_ganon_2a
ROM4:AD5D JSR play_boss_sound_1
ROM4:AD5E LDA #Music_FoundGanon
ROM4:AD5F STA play_music ; Play Music_FoundGanon
 
ROM4:AD7A loc_12D7A:
ROM4:AD7A JSR update_monster_ganon_2h
ROM4:AD7B LDA enemy_state_4,X
ROM4:AD7C CMP #$A0
ROM4:AD7D BCC loc_12DEB
ROM4:AD7E BNE ret
ROM4:AD7F JSR update_monster_ganon_2i
ROM4:AD80 LDA object_x,X
ROM4:AD81 STA floor_item_x
ROM4:AD82 LDA object_y,X
ROM4:AD83 STA floor_item_y
ROM4:AD84 INC object_type
 
ROM4:AD85 ret:
ROM4:AD85 RTS
 
ROM4:AD95 byte_12D95: .BYTE 1
ROM4:AD96   .BYTE 2
ROM4:AD97   .BYTE 4
ROM4:AD98   .BYTE 5
ROM4:AD99   .BYTE 6
ROM4:AD9A   .BYTE 8
ROM4:AD9B   .BYTE 9
ROM4:AD9C   .BYTE $A
ROM4:AD9D ganon_oam_attributes: .BYTE 0
ROM4:AD9E   .BYTE 0
ROM4:AD9F   .BYTE OAMAttributes_FlipHorizontally
ROM4:ADA0   .BYTE 0
ROM4:ADA1   .BYTE OAMAttributes_FlipVertically
ROM4:ADA2   .BYTE OAMAttributes_FlipHorizontally|OAMAttributes_FlipVertically
ROM4:ADA3   .BYTE OAMAttributes_FlipVertically
ROM4:ADA4   .BYTE 0
ROM4:ADA5   .BYTE OAMAttributes_FlipHorizontally
ROM4:ADA6   .BYTE 0
ROM4:ADA7 byte_12DA7: .BYTE 0
ROM4:ADA8   .BYTE 0
ROM4:ADA9   .BYTE $EE
ROM4:ADAA   .BYTE $EE
ROM4:ADAB   .BYTE $E8
ROM4:ADAC   .BYTE $30
ROM4:ADAD   .BYTE $30
ROM4:ADAE   .BYTE $E8
ROM4:ADAF   .BYTE $30
ROM4:ADB0   .BYTE $30
 
Subroutine update_monster_ganon_2a
ROM4:ADB1 update_monster_ganon_2a:
ROM4:ADB1 LDY #7
 
ROM4:ADB2 loop:
ROM4:ADB2 LDA object_x,X
ROM4:ADB3 CLC
ROM4:ADB4 ADC #4
ROM4:ADB5 STA object_x_2,Y
ROM4:ADB6 LDA object_y,X
ROM4:ADB7 ADC #4
ROM4:ADB8 STA object_y_2,Y
ROM4:ADB9 LDA byte_12D95,Y
ROM4:ADBA STA object_direction_1+1,Y
ROM4:ADBB DEY
ROM4:ADBC BPL loop
ROM4:ADBD RTS
 
Subroutine update_monster_ganon_2b
ROM4:ADCC update_monster_ganon_2b:
ROM4:ADCC LDA var_0 ; Save var_0
ROM4:ADCD PHA
ROM4:ADCE LDA var_1 ; Save var_1
ROM4:ADCF PHA
ROM4:ADD0 LDA #$C
ROM4:ADD1 LDY enemy_blind_projectile_timer,X
ROM4:ADD2 CPY #6
ROM4:ADD3 BCS loc_12DDD
ROM4:ADD4 LDA #$D
 
ROM4:ADDD loc_12DDD:
ROM4:ADDD LDY #0
ROM4:ADDE STY var_15
ROM4:ADDF JSR update_object_sprite_vertical
ROM4:ADE0 PLA
ROM4:ADE1 STA var_1 ; Restore var_0
ROM4:ADE2 PLA
ROM4:ADE3 STA var_0 ; Restore var_1
ROM4:ADE4 RTS
 
Function chunk for update_monster_ganon_2_main_combat
ROM4:ADEB loc_12DEB:
ROM4:ADEB LDA enemy_blind_projectile_timer,X
ROM4:ADEC BEQ loc_12DF9
ROM4:ADED LDA frame_counter
ROM4:ADEE AND #7
ROM4:ADEF BNE loc_12DF9
ROM4:ADF0 DEC enemy_blind_projectile_timer,X ; Decrement every 8 frames
 
ROM4:ADF9 loc_12DF9:
ROM4:ADF9 JSR ganon_set_var_0_to_ganon_x_minus_value
ROM4:ADFA JSR ganon_set_var_0_to_ganon_y_minus_value
ROM4:ADFB JSR update_monster_ganon_2b
ROM4:ADFC JSR ganon_set_var_0_to_ganon_x_plus_value
ROM4:ADFD JSR update_monster_ganon_2b
ROM4:ADFE JSR ganon_set_var_0_to_ganon_x_minus_value
ROM4:ADFF JSR ganon_set_var_0_to_ganon_y_plus_value
ROM4:AE00 JSR update_monster_ganon_2b
ROM4:AE01 JSR ganon_set_var_0_to_ganon_x_plus_value
ROM4:AE02 JSR update_monster_ganon_2b
ROM4:AE03 LDA object_x,X
ROM4:AE04 STA var_0 ; Set to Ganon's X position
ROM4:AE05 JSR ganon_set_var_0_to_ganon_y_minus_value
ROM4:AE06 JSR update_monster_ganon_2b
ROM4:AE07 JSR ganon_set_var_0_to_ganon_y_plus_value
ROM4:AE08 JSR update_monster_ganon_2b
ROM4:AE09 JSR ganon_set_var_0_to_ganon_x_minus_value
ROM4:AE0A LDA object_y,X
ROM4:AE0B STA var_1 ; Set to Ganon's Y position
ROM4:AE0C JSR update_monster_ganon_2b
ROM4:AE0D JSR ganon_set_var_0_to_ganon_x_plus_value
ROM4:AE0E JSR update_monster_ganon_2b
ROM4:AE0F LDA processing_object_index
ROM4:AE10 PHA
ROM4:AE11 LDX #2
 
ROM4:AE12 loop:
ROM4:AE12 STX processing_object_index
ROM4:AE13 CPX #5
ROM4:AE14 BCC loc_12E4E
ROM4:AE15 CPX #7
 
ROM4:AE46 loc_12E46:
ROM4:AE46 BEQ loc_12E4E
ROM4:AE47 LDA frame_counter
ROM4:AE48 AND #3
ROM4:AE49 BEQ loc_12E51
 
ROM4:AE4E loc_12E4E:
ROM4:AE4E JSR sub_11E9D
 
ROM4:AE51 loc_12E51: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:AE51 JSR set_var_0_to_object_position
ROM4:AE52 LDA frame_counter
ROM4:AE53 AND #3
ROM4:AE54 ORA ganon_oam_attributes,X
ROM4:AE55 STA var_3
ROM4:AE56 LDA byte_12DA7,X
ROM4:AE57 JSR setup_sprites_ganon_moldorm_lanmola
ROM4:AE58 INX
ROM4:AE59 CPX #$A
ROM4:AE5A BCC loop
ROM4:AE5B PLA
ROM4:AE5C STA processing_object_index
ROM4:AE5D RTS
 
Subroutine ganon_set_var_0_to_ganon_x_minus_value
ROM4:AE6D ganon_set_var_0_to_ganon_x_minus_value:
ROM4:AE6D LDA object_x,X
ROM4:AE6E SEC
ROM4:AE6F SBC enemy_blind_projectile_timer,X
ROM4:AE70 STA var_0
ROM4:AE71 RTS
 
Subroutine ganon_set_var_0_to_ganon_x_plus_value
ROM4:AE76 ganon_set_var_0_to_ganon_x_plus_value:
ROM4:AE76 LDA object_x,X
ROM4:AE77 CLC
ROM4:AE78 ADC enemy_blind_projectile_timer,X
ROM4:AE79 STA var_0
ROM4:AE7A RTS
 
Subroutine ganon_set_var_0_to_ganon_y_minus_value
ROM4:AE7F ganon_set_var_0_to_ganon_y_minus_value:
ROM4:AE7F LDA object_y,X
ROM4:AE80 SEC
ROM4:AE81 SBC enemy_blind_projectile_timer,X
ROM4:AE82 STA var_1
ROM4:AE83 RTS
 
Subroutine ganon_set_var_0_to_ganon_y_plus_value
ROM4:AE88 ganon_set_var_0_to_ganon_y_plus_value:
ROM4:AE88 LDA object_y,X
ROM4:AE89 CLC
ROM4:AE8A ADC enemy_blind_projectile_timer,X
ROM4:AE8B STA var_1
ROM4:AE8C RTS
 
ROM4:AE91 ganon_tile_set_frame_offsets: .BYTE 6
ROM4:AE92   .BYTE 8
ROM4:AE93   .BYTE 7
ROM4:AE94   .BYTE 9
ROM4:AE95   .BYTE 0
ROM4:AE96   .BYTE 0
ROM4:AE97   .BYTE 1
ROM4:AE98   .BYTE 1
ROM4:AE99   .BYTE 2
ROM4:AE9A   .BYTE 2
ROM4:AE9B   .BYTE 3
ROM4:AE9C   .BYTE 3
ROM4:AE9D   .BYTE 4
ROM4:AE9E   .BYTE 0
ROM4:AE9F   .BYTE 5
ROM4:AEA0   .BYTE 1
ROM4:AEA1   .BYTE 4
ROM4:AEA2   .BYTE 4
ROM4:AEA3   .BYTE 5
ROM4:AEA4   .BYTE 5
ROM4:AEA5   .BYTE 0
ROM4:AEA6   .BYTE 4
ROM4:AEA7   .BYTE 1
ROM4:AEA8   .BYTE 5
ROM4:AEA9 ganon_x_offset: .BYTE 0
ROM4:AEAA   .BYTE $10
ROM4:AEAB   .BYTE 0
ROM4:AEAC   .BYTE $10
ROM4:AEAD ganon_y_offset: .BYTE 0
ROM4:AEAE   .BYTE 0
ROM4:AEAF   .BYTE $10
ROM4:AEB0   .BYTE $10
ROM4:AEB1 ganon_tile_y_increment: .BYTE 0
ROM4:AEB2   .BYTE 1
ROM4:AEB3   .BYTE 0
ROM4:AEB4   .BYTE 1
 
Subroutine update_ganon_sprite
ROM4:AEB5 update_ganon_sprite:
ROM4:AEB5 LDY #3 ; Loop 4 times
 
ROM4:AEB6 loop:
ROM4:AEB6 LDA object_x,X
ROM4:AEB7 CLC
ROM4:AEB8 ADC ganon_x_offset,Y
ROM4:AEB9 STA var_0 ; Set Ganon tile X position
ROM4:AEBA LDA object_y,X
ROM4:AEBB CLC
ROM4:AEBC ADC ganon_y_offset,Y
ROM4:AEBD STA var_1 ; Set Ganon tile Y position
ROM4:AEBE LDA ganon_tile_y_increment,Y
ROM4:AEBF STA var_15 ; Set to 1 if this tile is offset to the right by half a tile.
ROM4:AEC0 TYA ; Save Y
ROM4:AEC1 PHA
ROM4:AEC2 STA var_7
ROM4:AEC3 LDA enemy_state_1,X
ROM4:AEC4 ASL A
ROM4:AEC5 ASL A
ROM4:AEC6 ADC var_7
ROM4:AEC7 TAY
ROM4:AEC8 LDA ganon_tile_set_frame_offsets,Y
ROM4:AEC9 JSR update_object_sprite_horizontal
ROM4:AECA PLA ; Restore Y
ROM4:AECB TAY
ROM4:AECC DEY
ROM4:AECD BPL loop
ROM4:AECE RTS
 
Subroutine update_monster_ganon_2g
ROM4:AEE4 update_monster_ganon_2g:
ROM4:AEE4 LDA object_x,X
ROM4:AEE5 CLC
ROM4:AEE6 ADC #$10
ROM4:AEE7 STA var_2
ROM4:AEE8 LDA object_y,X
ROM4:AEE9 CLC
ROM4:AEEA ADC #$10
ROM4:AEEB STA var_3
ROM4:AEEC LDA invincibility_frames ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:AEED BNE loc_12F04
ROM4:AEEE STA var_6 ; Set to 0
ROM4:AEEF STA var_9 ; Set to 0
ROM4:AEF0 STA var_12 ; Set to 0
ROM4:AEF1 LDY #0
ROM4:AEF2 STY var_0 ; Set to 0
ROM4:AEF3 JSR loc_107AC5
 
ROM4:AF04 loc_12F04:
ROM4:AF04 LDA walk_state_and_weapon_state,X
ROM4:AF05 BNE ganon_check_magic_arrow_hit
ROM4:AF06 LDA enemy_action_timers,X
ROM4:AF07 BNE locret_12F32
ROM4:AF08 LDY #var_13
ROM4:AF09 JSR check_attack_sword
ROM4:AF0A LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM4:AF0B BEQ loc_12F20
ROM4:AF0C LDA #$F0
ROM4:AF0D STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM4:AF0E DEC walk_state_and_weapon_state,X
ROM4:AF0F JSR update_monster_ganon_2g2
 
ROM4:AF20 loc_12F20: ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM4:AF20 LDA invincibility_frames,X
ROM4:AF21 BEQ loc_12F2C
ROM4:AF22 JSR play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:AF23 LDA #$40
ROM4:AF24 STA enemy_action_timers,X
 
ROM4:AF2C loc_12F2C: ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM4:AF2C JSR set_enemy_spawn_state_to_spawned
ROM4:AF2D JSR sub_107C96
 
ROM4:AF32 locret_12F32:
ROM4:AF32 RTS
 
ROM4:AF33 ganon_check_magic_arrow_hit: ; Ignore the non-magic arrow.
ROM4:AF33 LDA have_arrow_type
ROM4:AF34 CMP #2
ROM4:AF35 BNE locret_12F32
ROM4:AF36 LDA #0
ROM4:AF37 STA var_6
ROM4:AF38 LDY #$12
ROM4:AF39 LDA walk_state_and_weapon_state,Y
ROM4:AF3A CMP #$10
ROM4:AF3B BNE locret_12F32
ROM4:AF3C JSR check_attack_arrow
ROM4:AF3D LDA var_6
ROM4:AF3E BEQ locret_12F32
ROM4:AF3F INC enemy_state_4,X
ROM4:AF40 LDA #40
ROM4:AF41 STA invincibility_frames,X ; Set to 40
ROM4:AF42 LDA #8
ROM4:AF43 STA enemy_blind_projectile_timer,X ; Set to 8
ROM4:AF44 RTS
 
ROM4:AF5C ganon_ppu_data_1: .BYTE $3F
ROM4:AF5D   .BYTE $1C
ROM4:AF5E   .BYTE 4
ROM4:AF5F   .BYTE $F
ROM4:AF60   .BYTE 7
ROM4:AF61   .BYTE $17
ROM4:AF62   .BYTE $27
ROM4:AF63   .BYTE $FF
ROM4:AF64 ganon_ppu_data_2: .BYTE 7
ROM4:AF65   .BYTE $17
ROM4:AF66   .BYTE $30
ROM4:AF67   .BYTE $16
ROM4:AF68   .BYTE $2C
ROM4:AF69   .BYTE $3C
ROM4:AF6A   .BYTE $27
ROM4:AF6B   .BYTE 6
ROM4:AF6C   .BYTE $16
 
Subroutine update_monster_ganon_2g2
ROM4:AF6D update_monster_ganon_2g2:
ROM4:AF6D LDY #2
ROM4:AF6E BNE loc_12F77
 
ROM4:AF71 loc_12F71:
ROM4:AF71 LDY #5
ROM4:AF72 BNE loc_12F77
 
ROM4:AF75 loc_12F75:
ROM4:AF75 LDY #8
 
ROM4:AF77 loc_12F77:
ROM4:AF77 TYA
ROM4:AF78 PHA
ROM4:AF79 LDX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM4:AF7A LDY #0
 
ROM4:AF7E loc_12F7E:
ROM4:AF7E LDA ganon_ppu_data_1,Y
ROM4:AF7F STA ppu_command_buffer,X
ROM4:AF80 INX
ROM4:AF81 INY
ROM4:AF82 CPY #8
ROM4:AF83 BNE loc_12F7E
ROM4:AF84 STX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM4:AF85 PLA
ROM4:AF86 TAY
ROM4:AF87 LDX #2
 
ROM4:AF91 loc_12F91:
ROM4:AF91 LDA ganon_ppu_data_2,Y
ROM4:AF92 STA ppu_command_buffer_04,X
ROM4:AF93 DEY
ROM4:AF94 DEX
ROM4:AF95 BPL loc_12F91
ROM4:AF96 LDX processing_object_index
ROM4:AF97 RTS
 
Subroutine update_monster_ganon_2h
ROM4:AF9F update_monster_ganon_2h:
ROM4:AF9F JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:AFA0 LDA #$B
ROM4:AFA1 JMP update_object_sprite_horizontal
 
Subroutine update_monster_ganon_2i
ROM4:AFA7 update_monster_ganon_2i:
ROM4:AFA7 LDA current_room_floor_item_hidden
ROM4:AFA8 BEQ ret
ROM4:AFA9 JSR get_room_status_floor_item_picked_up
ROM4:AFAA BNE ret
ROM4:AFAB LDA #0
ROM4:AFAC STA current_room_floor_item_hidden ; Set to 0.
ROM4:AFAD LDA #Sound1_ItemAppeared
ROM4:AFAE STA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
 
ROM4:AFAF ret:
ROM4:AFAF RTS
 
ROM4:AFB0 Skipped empty chunk
Subroutine unpack_enemy_health
; If var_0 if even, return A & 0xF0. Otherwise, return (A << 4) (shifting 0x0F into 0xF0).
ROM4:B000 unpack_enemy_health:
ROM4:B000 PHA
ROM4:B001 LDA var_0 ; Load the object type
ROM4:B002 LSR A
ROM4:B003 BCS odd_object_type
ROM4:B004 PLA
ROM4:B005 AND #$F0
ROM4:B006 RTS
 
ROM4:B007 odd_object_type:
ROM4:B007 PLA
ROM4:B008 ASL A
ROM4:B009 ASL A
ROM4:B00A ASL A
ROM4:B00B ASL A
ROM4:B00C RTS
 
Subroutine play_boss_sound_1
ROM4:B010 play_boss_sound_1:
ROM4:B010 LDA #Sound0_BossPainSound
ROM4:B011 STA play_sound_0 ; Play Sound0_BossSound1
ROM4:B012 LDA #Sound2_StopBossRoar
ROM4:B013 STA play_sound_2 ; Set to a nonzero value to play a one-off sound effect
ROM4:B014 RTS
 
ROM4:B01B enemy_class_1_no_drops: .BYTE ObjectType_EnemyDeath
ROM4:B01C   .BYTE ObjectType_Gel1
ROM4:B01D   .BYTE ObjectType_Gel2
ROM4:B01E   .BYTE ObjectType_BlueKeese
ROM4:B01F   .BYTE ObjectType_RedKeese
ROM4:B020   .BYTE ObjectType_DarkKeese
ROM4:B021   .BYTE ObjectType_LikeLike
ROM4:B022 enemy_class_A: .BYTE ObjectType_RedOctorok ; The order of these classes is named to line up with
  ; the diagram at: http://redcandle.us/The_Legend_of_Zelda#Drops
ROM4:B023   .BYTE ObjectType_RedOctorokFast
ROM4:B024   .BYTE ObjectType_RedTektite
ROM4:B025   .BYTE ObjectType_RedMoblin
ROM4:B026   .BYTE ObjectType_BlueLeever
ROM4:B027   .BYTE ObjectType_BlueWizzrobe
ROM4:B028 enemy_class_C: .BYTE ObjectType_Ghini
ROM4:B029   .BYTE ObjectType_GhiniFromTombs ; Created by handle_spawning_armos_ghini_on_touch
ROM4:B02A   .BYTE ObjectType_BlueTektite
ROM4:B02B   .BYTE ObjectType_RedLeever
ROM4:B02C   .BYTE ObjectType_Zol
ROM4:B02D   .BYTE ObjectType_Rope
ROM4:B02E   .BYTE ObjectType_Stalfos
ROM4:B02F   .BYTE ObjectType_WallMaster
ROM4:B030   .BYTE ObjectType_PolsVoice
ROM4:B031 enemy_class_B: .BYTE ObjectType_BlueOctorok
ROM4:B032   .BYTE ObjectType_BlueOctorokFast
ROM4:B033   .BYTE ObjectType_BlueMoblin
ROM4:B034   .BYTE ObjectType_BlueLynel
ROM4:B035   .BYTE ObjectType_Vire
ROM4:B036   .BYTE ObjectType_RedGoriya
ROM4:B037   .BYTE ObjectType_RedDarknut
ROM4:B038   .BYTE ObjectType_RedWizzrobe
ROM4:B039   .BYTE ObjectType_Gibdo
ROM4:B03A drop_class_starting_index: .BYTE 0 ; A: Drops hearts, rupees and fairies
ROM4:B03B   .BYTE 10 ; C: Drops rupees, 5-rupees, hearts and clocks
ROM4:B03C   .BYTE 20 ; B: Drops hearts, rupees, clocks and bombs
ROM4:B03D   .BYTE 30 ; D: Drops hearts, fairies and hearts
ROM4:B03E drop_chance: .BYTE $50
ROM4:B03F   .BYTE $98
ROM4:B040   .BYTE $68
ROM4:B041   .BYTE $68
ROM4:B042 random_drops: .BYTE FloorItem_Heart
ROM4:B043   .BYTE FloorItem_Rupee
ROM4:B044   .BYTE FloorItem_Heart
ROM4:B045   .BYTE FloorItem_Rupee
ROM4:B046   .BYTE FloorItem_Fairy
ROM4:B047   .BYTE FloorItem_Rupee
ROM4:B048   .BYTE FloorItem_Heart
ROM4:B049   .BYTE FloorItem_Heart
ROM4:B04A   .BYTE FloorItem_Rupee
ROM4:B04B   .BYTE FloorItem_Rupee
ROM4:B04C   .BYTE FloorItem_5Rupee ; 10
ROM4:B04D   .BYTE FloorItem_Rupee
ROM4:B04E   .BYTE FloorItem_Heart
ROM4:B04F   .BYTE FloorItem_Rupee
ROM4:B050   .BYTE FloorItem_5Rupee
ROM4:B051   .BYTE FloorItem_Heart
ROM4:B052   .BYTE FloorItem_Clock
ROM4:B053   .BYTE FloorItem_Rupee
ROM4:B054   .BYTE FloorItem_Rupee
ROM4:B055   .BYTE FloorItem_Rupee
ROM4:B056   .BYTE FloorItem_Heart ; 20
ROM4:B057   .BYTE FloorItem_Bomb
ROM4:B058   .BYTE FloorItem_Rupee
ROM4:B059   .BYTE FloorItem_Clock
ROM4:B05A   .BYTE FloorItem_Rupee
ROM4:B05B   .BYTE FloorItem_Heart
ROM4:B05C   .BYTE FloorItem_Bomb
ROM4:B05D   .BYTE FloorItem_Rupee
ROM4:B05E   .BYTE FloorItem_Bomb
ROM4:B05F   .BYTE FloorItem_Heart
ROM4:B060   .BYTE FloorItem_Heart ; 30
ROM4:B061   .BYTE FloorItem_Heart
ROM4:B062   .BYTE FloorItem_Fairy
ROM4:B063   .BYTE FloorItem_Rupee
ROM4:B064   .BYTE FloorItem_Heart
ROM4:B065   .BYTE FloorItem_Fairy
ROM4:B066   .BYTE FloorItem_Heart
ROM4:B067   .BYTE FloorItem_Heart
ROM4:B068   .BYTE FloorItem_Heart
ROM4:B069   .BYTE FloorItem_Rupee
 
Subroutine enemy_killed
ROM4:B06A enemy_killed:
ROM4:B06A LDA #0 ; Figure out which drop class this enemy is in.
ROM4:B06B STA var_1 ; Set to 0
ROM4:B06C LDA enemy_state_0,X
ROM4:B06D LDY #6
 
ROM4:B06E loop1:
ROM4:B06E CMP enemy_class_1_no_drops,Y
ROM4:B06F BEQ despawn_object_thunk
ROM4:B070 DEY
ROM4:B071 BPL loop1
ROM4:B072 LDY #5
 
ROM4:B073 loop2:
ROM4:B073 CMP enemy_class_A,Y
ROM4:B074 BEQ done
ROM4:B075 DEY
ROM4:B076 BPL loop2
ROM4:B077 INC var_1 ; Set to 1
ROM4:B078 LDY #8
 
ROM4:B079 loop3:
ROM4:B079 CMP enemy_class_C,Y
ROM4:B07A BEQ done
ROM4:B07B DEY
ROM4:B07C BPL loop3
ROM4:B07D INC var_1 ; Set to 2
ROM4:B07E LDY #8
 
ROM4:B07F loop4:
ROM4:B07F CMP enemy_class_B,Y
ROM4:B080 BEQ done
ROM4:B081 DEY
ROM4:B082 BPL loop4
ROM4:B083 INC var_1 ; Set to 3
 
ROM4:B084 done: ; If the first enemy is a Stalfos or a Gibdo, it never drops
ROM4:B084 CPX #1 ; an item. This is probably to avoid conflicts with these
  ; enemies holding room items.
ROM4:B085 BNE not_first_enemy
ROM4:B086 CMP #ObjectType_Stalfos
ROM4:B087 BEQ despawn_object_thunk
ROM4:B088 CMP #ObjectType_Gibdo
ROM4:B089 BEQ despawn_object_thunk
 
ROM4:B08A not_first_enemy: ; Get the drop class
ROM4:B08A LDY var_1
ROM4:B08B LDA drop_class_starting_index,Y
ROM4:B08C CLC
ROM4:B08D ADC drop_counter ; Increment the drop counter
ROM4:B08E TAY
ROM4:B08F LDA random_drops,Y ; Get the random drop
ROM4:B090 STA var_0 ; Store random drop
ROM4:B091 LDA #FloorItem_Fairy ; If the consecutive kill counter is at 16, always drop a fairy.
ROM4:B092 LDY consecutive_kill_counter
ROM4:B093 CPY #16
ROM4:B094 BEQ forced_drop
ROM4:B095 LDA consecutive_ten_kill_counter ; Otherwise, if the ten kill counter is >= 10, always drop a 5 rupee or a bomb.
ROM4:B096 CMP #10
ROM4:B097 BCC consecutive_kill_counter_below_10 ; consecutive_ten_kill_counter < 10
ROM4:B098 LDA #FloorItem_5Rupee ; Forced 5-rupee
ROM4:B099 LDY reached_ten_kills_with_last_bomb ; If the 10th enemy was killed with a bomb (even if this is
  ; a later enemy), drop a bomb instead.
ROM4:B09A BEQ forced_drop
ROM4:B09B LDA #FloorItem_Bomb ; Forced bomb
 
ROM4:B09C forced_drop:
ROM4:B09C STA var_0
ROM4:B09D LDA #0
ROM4:B09E STA consecutive_ten_kill_counter ; Set to 0
ROM4:B09F STA reached_ten_kills_with_last_bomb ; Set to 0
ROM4:B0A0 BEQ skip_drop_chance_check ; Always branch
 
ROM4:B0A1 consecutive_kill_counter_below_10: ; Load the enemy drop class.
ROM4:B0A1 LDY var_1
ROM4:B0A2 LDA prng_0,X
ROM4:B0A3 CMP drop_chance,Y ; If prng < drop chance, just despawn this object.
ROM4:B0A4 BCS despawn_object_thunk
 
ROM4:B0A5 skip_drop_chance_check:
ROM4:B0A5 LDA #$FF
ROM4:B0A6 STA object_tile_offset_fraction,X ; Set to 0xFF
ROM4:B0A7 LDA var_0
ROM4:B0A8 STA walk_state_and_weapon_state,X ; Store the drop type
ROM4:B0A9 CMP #FloorItem_Fairy ; If we dropped a fairy, play the fairy sound and set it up
ROM4:B0AA BNE ret
ROM4:B0AB JMP init_fairy_drop
 
ROM4:B0AC ret:
ROM4:B0AC RTS
 
ROM4:B0F5 despawn_object_thunk: ; Remove the object at ID X.
ROM4:B0F5 JMP despawn_object
 
ROM4:B0F6   .BYTE 0
ROM4:B0F7   .BYTE $F
ROM4:B0F8   .BYTE $D
ROM4:B0F9   .BYTE $12
 
Subroutine update_monster_floor_pickup
ROM4:B0FC update_monster_floor_pickup:
ROM4:B0FC LDA frame_counter
ROM4:B0FD LSR A
ROM4:B0FE BCC even_frame ; skip if even frame
ROM4:B0FF DEC object_tile_offset_fraction,X
 
ROM4:B100 even_frame:
ROM4:B100 LDA object_tile_offset_fraction,X
ROM4:B101 BEQ despawn_object ; Branch if this object's timer has expired
ROM4:B102 LDA walk_state_and_weapon_state,X
ROM4:B103 CMP #FloorItem_Fairy
ROM4:B104 BEQ fairy
ROM4:B105 JSR setup_sprite
ROM4:B106 JMP not_fairy
 
ROM4:B107 fairy:
ROM4:B107 JSR update_monster_floor_pickup_fairy
 
ROM4:B108 not_fairy:
ROM4:B108 LDA walk_state_and_weapon_state
ROM4:B109 AND #$C0
ROM4:B10A CMP #$40
ROM4:B10B BEQ locret_1315E
ROM4:B10C LDA #4
ROM4:B10D STA var_13
 
ROM4:B124 loc_13124:
ROM4:B124 LDA object_x
ROM4:B125 PHA
ROM4:B126 LDA object_y
ROM4:B127 PHA
ROM4:B128 LDY var_13
ROM4:B129 LDX despawn_object_thunk+2,Y
ROM4:B12A LDA object_x,X
ROM4:B12B STA object_x
ROM4:B12C LDA object_y,X
ROM4:B12D STA object_y
ROM4:B12E CPX #0
ROM4:B12F BEQ loc_13141
ROM4:B130 LDA walk_state_and_weapon_state,X
ROM4:B131 BEQ loc_1314B
ROM4:B132 BMI loc_1314B
 
ROM4:B141 loc_13141:
ROM4:B141 LDX processing_object_index
ROM4:B142 LDA walk_state_and_weapon_state,X ; Load the FloorItem for this object and store it in var_4 for check_object_collision.
ROM4:B143 STA var_4
ROM4:B144 JSR check_object_collision ; var_4 is set to the item that colliding with this object will give.
 
ROM4:B14B loc_1314B:
ROM4:B14B PLA
ROM4:B14C STA object_y
ROM4:B14D PLA
 
ROM4:B14F loc_1314F:
ROM4:B14F STA object_x
ROM4:B150 LDX processing_object_index
ROM4:B151 LDA walk_state_and_weapon_state,X
ROM4:B152 CMP #$FF
ROM4:B153 BEQ despawn_object ; Remove the object at ID X.
ROM4:B154 DEC var_13
ROM4:B155 BNE loc_13124
 
ROM4:B15E locret_1315E:
ROM4:B15E RTS
 
Subroutine despawn_object
; Remove the object at ID X.
ROM4:B15F despawn_object:
ROM4:B15F LDA #0
ROM4:B160 STA object_type,X ; Set to 0
ROM4:B161 JSR clear_knockback2
ROM4:B162 STA enemy_action_timers,X ; Set to 0
ROM4:B163 STA walk_state_and_weapon_state,X ; Set to 0
ROM4:B164 STA invincibility_frames,X ; Set to 0
ROM4:B165 LDA #$FF
ROM4:B166 STA object_slot_in_use,X ; Set to 0xFF
ROM4:B167 LDA #1
ROM4:B168 STA enemy_spawn_state,X ; Set to 1
ROM4:B169 RTS
 
Subroutine create_object_at_another_object_2
; Create an object that's spawned at the position of another ; object, like projectiles and Keese when Vires are killed. ; ; A is the object type. The next available object slot ; is used. If we couldn't fire a projectile because there ; were no slots, CLC. Otherwise, SEC.
ROM4:B179 create_object_at_another_object_2:
ROM4:B179 STA var_0
ROM4:B17A LDA enemy_state_0,X
ROM4:B17B BEQ no_available_slots
 
ROM4:B180 create_object_at_another_object: ; Create an object that's spawned at the position of another
ROM4:B180 JSR find_last_available_object_idx ; object, like projectiles and Keese when Vires are killed.
 
  ; var_0 is the object type. The next available object slot
  ; is used. If we couldn't fire a projectile because there
  ; were no slots, CLC. Otherwise, SEC.
ROM4:B181 BEQ no_available_slots ; Skip if we don't have any object slots to put this.
ROM4:B182 LDA var_0
ROM4:B183 CMP #ObjectType_Octorok_Projectile
ROM4:B184 BCC create_object_at_another_object_with_slot ; If A < ObjectType_Octorok_Projectile, check the projectile
  ; count. This can be called to spawn things that aren't
  ; projectiles.
ROM4:B185 LDA enemy_projectile_count ; Load to check the number of active projectiles.
ROM4:B186 CMP #4
ROM4:B187 BCS no_available_slots ; Don't spawn more than 4 enemy projectiles.
ROM4:B188 INC enemy_projectile_count ; We're spawning a projectile.
 
ROM4:B195 create_object_at_another_object_with_slot: ; Create an object that's spawned at the position of another
ROM4:B195 LDX tmp_result ; object, like projectiles and Keese when Vires are killed.
 
  ; var_0 is the object type. tmp_result is the slot to put
  ; the enemy (found by calling find_last_available_object_idx).
  ; If we couldn't fire a projectile because there were no
  ; slots, CLC. Otherwise, SEC.
ROM4:B196 LDA var_0 ; Load the slot to put this enemy and the object type.
ROM4:B197 JSR create_enemy
ROM4:B198 LDY tmp_result ; Load the slot to put this enemy.
ROM4:B199 LDX processing_object_index ; The enemy firing this projectile?
ROM4:B19A LDA #$10
ROM4:B19B STA walk_state_and_weapon_state,Y ; Set to 0x10
ROM4:B19C LDA #0
ROM4:B19D STA enemy_action_timers,Y ; Set to 0
ROM4:B19E LDA object_direction,X
ROM4:B19F STA object_direction,Y ; Store the new object's direction
ROM4:B1A0 LDA object_x,X
ROM4:B1A1 STA object_x,Y ; Store the new object's X position
ROM4:B1A2 LDA object_y,X
ROM4:B1A3 STA object_y,Y ; Store the new object's Y position
ROM4:B1A4 SEC
ROM4:B1A5 RTS
 
ROM4:B1A6 no_available_slots:
ROM4:B1A6 CLC
ROM4:B1A7 RTS
 
Subroutine update_lighting_room
ROM4:B1BE update_lighting_room:
ROM4:B1BE LDA lighting_room_state
ROM4:B1BF JSR call_jump_table
 
ROM4:B1C0   .WORD update_lighting_room_0
ROM4:B1C2   .WORD update_lighting_room_1
ROM4:B1C4   .WORD locret_131DC
 
Subroutine update_lighting_room_0
ROM4:B1CA update_lighting_room_0:
ROM4:B1CA LDY map_location
ROM4:B1CB JSR check_if_room_is_dark
ROM4:B1CC BEQ locret_131DC ; Skip if the room isn't dark.
ROM4:B1CD LDA #$C0
ROM4:B1CE STA next_palette_cycle ; Set to 0xC0.
ROM4:B1CF INC paused_lighting_dungeon_room ; Set to 1 while the candle palette shift is happening.
 
ROM4:B1D9 advance_lighting_room_state_and_return:
ROM4:B1D9 INC lighting_room_state
 
ROM4:B1DC locret_131DC:
ROM4:B1DC RTS
 
Function chunk for update_lighting_room_1
ROM4:B1DD palette_cycle_is_zero:
ROM4:B1DD LDA #0
ROM4:B1DE STA paused_lighting_dungeon_room ; Set to 0
ROM4:B1DF BEQ advance_lighting_room_state_and_return ; Always branch
 
Subroutine update_lighting_room_1
ROM4:B1E4 update_lighting_room_1:
 
ROM4:B1E4 JSR update_timed_palette_cycle ; Update the palette cycling to light the room.
ROM4:B1E5 BEQ palette_cycle_is_zero ; If the palette cycle is finished, set currently_lighting_dungeon_room back to 0.
ROM4:B1E6 RTS
 
Subroutine check_if_room_is_dark
ROM4:B1EA check_if_room_is_dark:
ROM4:B1EA LDA dungeon_idx
ROM4:B1EB BEQ is_overworld
ROM4:B1EC LDA dungeon_screen_data_4,Y
ROM4:B1ED AND #ScreenData_Dungeon_4_Dark
 
ROM4:B1EE is_overworld:
ROM4:B1EE RTS
 
Subroutine init_fairy_drop
ROM4:B1F4 init_fairy_drop:
ROM4:B1F4 LDA #Sound1_Fairy
ROM4:B1F5 STA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
ROM4:B1F6 JSR clear_some_enemy_state
ROM4:B1F7 LDA #ControllerBits_Dpad_Up
ROM4:B1F8 STA object_direction,X
ROM4:B1F9 LDA #$7F
ROM4:B1FA STA enemy_projectile_speed_x,X
ROM4:B1FB LDA #$A0
ROM4:B1FC STA increase_enemy_speed_max ; Set to 0xA0.
ROM4:B1FD RTS
 
Subroutine clear_some_enemy_state
ROM4:B20B clear_some_enemy_state:
ROM4:B20B LDA #0
ROM4:B20C STA enemy_state_0,X ; Set to 0
ROM4:B20D STA enemy_state_4,X ; Set to 0
ROM4:B20E STA enemy_state_5,X ; Set to 0
ROM4:B20F STA enemy_state_6,X ; Set to 0
ROM4:B210 STA invincibility_frames,X ; Set to 0
ROM4:B211 RTS
 
Subroutine update_monster_floor_pickup_fairy
ROM4:B21D update_monster_floor_pickup_fairy:
ROM4:B21D JSR run_state
ROM4:B21E JSR reverse_walking_direction_if_out_of_bounds2 ; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
 
ROM4:B223 update_monster_fairy_animation: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM4:B223 JSR set_var_0_to_object_position
ROM4:B224 JSR store_palette_2_in_tile_attributes ; Store 0x2 in var_4 and var_5, and set A to 2.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM4:B225 ASL A ; A = 4
ROM4:B226 AND frame_counter ; frame & 4
ROM4:B227 LSR A ; (frame & 4) >> 1
ROM4:B228 LSR A ; A = (frame / 4) != 0
ROM4:B229 STA var_12
ROM4:B22A LDY #$14
ROM4:B22B JMP after_setting_some_frame_state
 
ROM4:B22C run_state:
ROM4:B22C LDA enemy_state_6,X
ROM4:B22D JSR call_jump_table
 
ROM4:B22E   .WORD increase_enemy_speed ; Increase the object's speed by one each frame. Once
  ; increase_enemy_speed_max is reached, switch to state 1.
ROM4:B230   .WORD update_monster_fairy_move_to_state_3 ; Just loop update_monster_45_degree_movement repeatedly.
ROM4:B232   .WORD locret_1324D ; This state is never reached.
ROM4:B234   .WORD update_monster_45_degree_movement ; Randomly change direction by 45, 0 or -45 degrees.
 
  ; This occurs each time the action timer expires, decrementing
  ; state_4, which is the number of cycles to stay in this mode.
  ; When state_4 reaches 0, switch to state 4.
 
Subroutine update_monster_fairy_move_to_state_3
ROM4:B243 update_monster_fairy_move_to_state_3:
ROM4:B243 LDA #3
ROM4:B244 STA enemy_state_6,X
ROM4:B245 LDA #6
ROM4:B246 STA enemy_state_4,X
 
ROM4:B24D locret_1324D:
ROM4:B24D RTS
 
ROM4:B24E directions_with_diagonals: .BYTE ControllerBits_Dpad_Up ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:B24F   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Up
ROM4:B250   .BYTE ControllerBits_Dpad_Right
ROM4:B251   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
ROM4:B252   .BYTE ControllerBits_Dpad_Down
ROM4:B253   .BYTE ControllerBits_Dpad_Left|ControllerBits_Dpad_Down
ROM4:B254   .BYTE ControllerBits_Dpad_Left
ROM4:B255   .BYTE ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
 
Subroutine reset_monster_state_after_npc_action_timers
ROM4:B256 reset_monster_state_after_npc_action_timers:
ROM4:B256 LDA enemy_action_timers,X
ROM4:B257 BNE ret
ROM4:B258 LDA #0
ROM4:B259 STA enemy_state_6,X
 
ROM4:B25A ret:
ROM4:B25A RTS
 
Subroutine decrease_enemy_speed
; Decrease the object's speed by one each frame. Once ; the speed is under 0x20, switch to state 5.
ROM4:B260 decrease_enemy_speed:
ROM4:B260 DEC enemy_projectile_speed_x,X
ROM4:B261 JMP continue
 
ROM4:B266 increase_enemy_speed: ; Increase the object's speed by one each frame. Once
ROM4:B266 INC enemy_projectile_speed_x,X ; increase_enemy_speed_max is reached, switch to state 1.
 
ROM4:B267 continue:
ROM4:B267 LDA enemy_projectile_speed_x,X
ROM4:B268 AND #$E0 ; 0b11100000
ROM4:B269 BNE check_max_speed
ROM4:B26A LDA prng_0,X ; Speed is under 0x20. This only happens when decreasing enemy
  ; speed, and this is the minimum speed to decelerate to. Set
  ; a random enemy timer, and switch to state 5.
ROM4:B26B AND #$3F
ROM4:B26C ORA #$40
ROM4:B26D STA enemy_action_timers,X ; Set enemy_action_timer[X] to 0x40-0x7F.
ROM4:B26E LDA #5 ; Set enemy_state_6 to 5.
 
ROM4:B27A set_enemy_state_6_to_A:
ROM4:B27A STA enemy_state_6,X
 
ROM4:B27B ret:
ROM4:B27B RTS
 
ROM4:B27C check_max_speed: ; Speed is 0x20 or higher. This happens when increasing speed.
ROM4:B27C CMP increase_enemy_speed_max ; If speed hasn't reached increase_enemy_speed_max then just
  ; return so we stay in this state and keep accelerating.
  ; Otherwise, switch to state 1.
ROM4:B27D BCC ret ; If we haven't reached max speed, return. We'll keep increasing speed.
ROM4:B27E LDA #1 ; Set enemy_state_6 to 1.
ROM4:B27F JMP set_enemy_state_6_to_A
 
Subroutine reverse_walking_direction_if_out_of_bounds2
; This calls reverse_walking_direction_if_out_of_bounds. I haven't traced the rest yet.
ROM4:B288 reverse_walking_direction_if_out_of_bounds2:
ROM4:B288 LDA enemy_projectile_speed_x,X
ROM4:B289 AND #$E0
ROM4:B28A CLC
ROM4:B28B ADC enemy_state_0,X
ROM4:B28C STA enemy_state_0,X
ROM4:B28D BCC locret_132CC
ROM4:B28E LDA #1
ROM4:B28F STA var_2
ROM4:B290 LDA object_direction,X
ROM4:B291 BIT var_2
ROM4:B292 BEQ loc_132A5
ROM4:B293 INC object_x,X
ROM4:B294 INC enemy_state_1,X
 
ROM4:B2A5 loc_132A5:
ROM4:B2A5 ASL var_2
ROM4:B2A6 BIT var_2
ROM4:B2A7 BEQ loc_132B0
ROM4:B2A8 DEC object_x,X
ROM4:B2A9 DEC enemy_state_1,X
 
ROM4:B2B0 loc_132B0:
ROM4:B2B0 ASL var_2
ROM4:B2B1 BIT var_2
ROM4:B2B2 BEQ loc_132BB
ROM4:B2B3 INC object_y,X
ROM4:B2B4 INC enemy_blind_projectile_timer,X
 
ROM4:B2BB loc_132BB:
ROM4:B2BB ASL var_2
ROM4:B2BC BIT var_2
ROM4:B2BD BEQ loc_132C6
ROM4:B2BE DEC object_y,X
ROM4:B2BF DEC enemy_blind_projectile_timer,X
 
ROM4:B2C6 loc_132C6:
ROM4:B2C6 INC enemy_state_5,X
ROM4:B2C7 JSR reverse_walking_direction_if_out_of_bounds ; If this object is walking out of the boundary of this
  ; screen, turn around.
 
ROM4:B2CC locret_132CC:
ROM4:B2CC RTS
 
Subroutine reverse_walking_direction_if_out_of_bounds
; If this object is walking out of the boundary of this ; screen, turn around.
ROM4:B2CD reverse_walking_direction_if_out_of_bounds:
ROM4:B2CD LDA object_direction,X
ROM4:B2CE STA var_15
ROM4:B2CF JSR check_object_against_screen_bounding_box_x ; If the current object is out of the bounding box for the
  ; current screen on the X axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction.
ROM4:B2D0 LDA object_type,X ; check if ObjectType_FallingRock
ROM4:B2D1 CMP #ObjectType_FallingRock
ROM4:B2D2 BEQ is_FallingRock ; Skip the bounding box check for FallingRocks, so they
  ; can fall out of the screen.
ROM4:B2D3 JSR check_object_against_screen_bounding_box_y ; If the current object is out of the bounding box for the
  ; current screen on the Y axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction.
 
ROM4:B2D4 is_FallingRock: ; If the boundary check didn't clear walking_state, keep
ROM4:B2D4 LDA var_15 ; moving in the same direction.
ROM4:B2D5 BNE locret_132F8 ; Otherwise, we can't move further in that direction. Fall
  ; through to reverse_walking_direction to switch to the opposite
  ; direction.
 
ROM4:B2E2 reverse_walking_direction: ; Set Y to the index in directions_with_diagonals for the
ROM4:B2E2 JSR find_direction_with_diagonals_for_object ; current object's direction, or 0 if none match.
ROM4:B2E3 TYA
ROM4:B2E4 CLC
ROM4:B2E5 ADC #4 ; Add 4 to get the opposite direction.
ROM4:B2E6 AND #7
ROM4:B2E7 TAY
ROM4:B2E8 LDA object_type,X ; check if ObjectType_Moldorm
ROM4:B2E9 CMP #ObjectType_Moldorm
ROM4:B2EA BEQ reverse_walking_direction_moldorm
ROM4:B2EB LDA directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:B2EC STA object_direction,X
 
ROM4:B2F8 locret_132F8:
ROM4:B2F8 RTS
 
ROM4:B2F9 reverse_walking_direction_moldorm: ; Only reverse object ID 5 and 10 for Moldorm, which are
ROM4:B2F9 CPX #5 ; probably the head pieces, and change object_walk_speed
  ; instead of object_direction.
ROM4:B2FA BEQ loc_13301
ROM4:B2FB CPX #$A
ROM4:B2FC BNE locret_13307
 
ROM4:B301 loc_13301: ; Direction combinations for objects that can move at
ROM4:B301 LDA directions_with_diagonals,Y ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:B302 STA object_walk_speed,X
 
ROM4:B307 locret_13307:
ROM4:B307 RTS
 
Subroutine update_monster_diagonal_movement_relative_to_seek
; Update the current enemy's direction relative to the seek ; position with diagonal movement. This isn't fully traced. ; ; This occurs each time the action timer expires, decrementing ; state_4, which is the number of cycles to stay in this mode. ; When state_4 reaches 0, switch to state 4.
ROM4:B308 update_monster_diagonal_movement_relative_to_seek:
ROM4:B308 LDA enemy_action_timers,X
ROM4:B309 BNE locret_13307 ; Stop if our timer hasn't expired.
ROM4:B30A DEC enemy_state_4,X ; Branch if state 4 is nonzero.
ROM4:B30B BNE continue
 
ROM4:B311 set_enemy_state_6_to_1:
ROM4:B311 LDA #1
ROM4:B312 JMP set_enemy_state_6_to_A ; Switch back to state 1.
 
ROM4:B313 continue:
ROM4:B313 LDA #16
ROM4:B314 STA enemy_action_timers,X ; Set to 16.
 
ROM4:B31A update_monster_diagonal_movement_relative_to_seek_from_digdogger:
ROM4:B31A LDY #0
ROM4:B31B STY var_0 ; var_0 will be 0 if the enemy's X == seek X, 1 if seek X > enemy X, or 2 if seek X < enemy X.
ROM4:B31C INY ; Y = 1
ROM4:B31D LDA enemy_behavior_seek_x
ROM4:B31E CMP object_x,X
ROM4:B31F BEQ x_aligned ; Branch if seek X == enemy X. This leaves var_0 at 0.
ROM4:B320 BCS seek_left_or_right ; Branch if seek X > enemy X
ROM4:B321 INY ; Y = 2 if seek < enemy position
 
ROM4:B322 seek_left_or_right: ; Set var_0 to 1 if seek X > enemy X, 2 seek X < enemy X.
ROM4:B322 STY var_0
 
ROM4:B323 x_aligned:
ROM4:B323 LDY #1
ROM4:B324 LDA enemy_behavior_seek_y
ROM4:B325 CMP object_y,X
ROM4:B326 BEQ y_aligned ; Branch if seek Y == enemy Y
ROM4:B327 BCS seek_up ; Branch if seek Y > enemy Y
ROM4:B328 INY
 
ROM4:B329 seek_up:
ROM4:B329 TYA
ROM4:B32A ASL A ; Y = A = 1 if seek Y > enemy Y, or 2 if seek Y < enemy Y.
  ; A <<= 2
ROM4:B32B ASL A
ROM4:B32C ORA var_0 ; Combine vertical movement in bits 0b1100 with horizontal
  ; movement in bits 0b0011.
ROM4:B32D STA var_0
 
ROM4:B32E y_aligned: ; Get the index for this object's current diagonal movement in Y.
ROM4:B32E JSR find_direction_with_diagonals_for_object
ROM4:B32F LDA #3 ; var_0 is the diagonal towards the current seek position.
  ; Y is the diagonal this enemy is currently moving.
  ; Check the next 4 diagonals to see if the seek direction is
  ; in the right 180 degree sweep from the current direction.
ROM4:B330 STA var_1 ; Set var_1 to 3 (loop counter)
ROM4:B331 INY ; Y++ (rotate right 45 degrees)
 
ROM4:B332 loop1:
ROM4:B332 TYA
ROM4:B333 AND #7 ; Y &= 0x7
ROM4:B334 TAY
ROM4:B335 LDA directions_with_diagonals,Y ; Get the movement bits for the current diagonal.
ROM4:B336 CMP var_0 ; var_0 is the diagonal towards seek.
  ; Compare this diagonal with the seek diagonal.
ROM4:B337 BEQ ret ; If it's equal, stop without changing the enemy's direction.
ROM4:B338 DEY ; Y-- (rotate left 45 degrees)
ROM4:B339 DEC var_1 ; Decrement the loop counter.
ROM4:B33A BNE loop1
ROM4:B33B LDA #3
ROM4:B33C STA var_1 ; Set var_1 to 3 (loop counter)
ROM4:B33D INY ; After the above 4 loops, Y is now pointing in the opposite
  ; direction of the seek position.
 
  ; Y++ (rotate right 45 degrees)
 
ROM4:B33E loop2:
ROM4:B33E TYA
ROM4:B33F AND #7 ; Y &= 0x7
ROM4:B340 TAY
ROM4:B341 LDA directions_with_diagonals,Y ; Get the movement bits for the current diagonal.
ROM4:B342 BIT var_0 ; Check if any movement bits (up, down, left, right) in
  ; this direction overlap with the seek direction.
ROM4:B343 BNE loc_13370
 
ROM4:B364 loc_13364: ; Y++ (rotate right 45 degrees)
ROM4:B364 INY
ROM4:B365 DEC var_1 ; Decrement the loop counter.
ROM4:B366 BNE loop2
ROM4:B367 DEY ; Y-- (rotate left 45 degrees)
 
ROM4:B36A keese_set_direction_to_y: ; Direction combinations for objects that can move at
ROM4:B36A LDA directions_with_diagonals,Y ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:B36B STA object_direction,X
 
ROM4:B36C ret:
ROM4:B36C RTS
 
ROM4:B370 loc_13370:
ROM4:B370 ORA var_0
ROM4:B371 CMP #7
ROM4:B372 BCS loc_13364
ROM4:B373 BCC keese_set_direction_to_y ; Always branch.
 
Subroutine update_monster_45_degree_movement
; Randomly change direction by 45, 0 or -45 degrees. ; ; This occurs each time the action timer expires, decrementing ; state_4, which is the number of cycles to stay in this mode. ; When state_4 reaches 0, switch to state 4.
ROM4:B378 update_monster_45_degree_movement:
ROM4:B378 LDA enemy_action_timers,X
ROM4:B379 BNE locret_133AC ; Stop if the enemy timer hasn't expired.
ROM4:B37A DEC enemy_state_4,X
ROM4:B37B BNE state_4_is_active
ROM4:B37C JMP set_enemy_state_6_to_1
 
ROM4:B37D state_4_is_active:
ROM4:B37D LDA #$10
ROM4:B37E STA enemy_action_timers,X ; Set to 16.
 
ROM4:B388 randomly_rotate_movement_by_45_degrees: ; Set Y to the index in directions_with_diagonals for the
ROM4:B388 JSR find_direction_with_diagonals_for_object ; current object's direction, or 0 if none match.
ROM4:B389 LDA prng_1,X
ROM4:B38A CMP #$A0
ROM4:B38B BCS set_direction ; Branch if prng >= 0xA0.
ROM4:B38C INY ; Y++, which rotates the movement direction 45 degrees clockwise.
ROM4:B38D CMP #$50
ROM4:B38E BCS set_direction ; Branch if prng >= 0x50.
ROM4:B38F DEY ; Y -= 2
ROM4:B390 DEY ; Y--, which rotates the movement direction 90 degrees counterclockwise.
 
ROM4:B391 set_direction:
ROM4:B391 TYA
ROM4:B392 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left|ControllerBits_Dpad_Down
ROM4:B393 TAY
ROM4:B394 JMP keese_set_direction_to_y
 
Subroutine find_direction_with_diagonals_for_object
; Set Y to the index in directions_with_diagonals for the ; current object's direction, or 0 if none match.
ROM4:B39F find_direction_with_diagonals_for_object:
ROM4:B39F LDY #7
 
ROM4:B3A0 loop:
ROM4:B3A0 LDA object_direction,X
ROM4:B3A1 CMP directions_with_diagonals,Y ; Direction combinations for objects that can move at
  ; a diagonal, like Tektites and Keese.
 
  ; The opposite direction for index N is index (N+4)&7.
ROM4:B3A2 BEQ locret_133AC
ROM4:B3A3 DEY
ROM4:B3A4 BPL loop
ROM4:B3A5 INY
 
ROM4:B3AC locret_133AC:
ROM4:B3AC RTS
 
ROM4:B3AD spinning_hearts_tile_offset_table: .BYTE 0
ROM4:B3AE   .BYTE $18
ROM4:B3AF   .BYTE $30
ROM4:B3B0   .BYTE $47
ROM4:B3B1   .BYTE $5A
ROM4:B3B2   .BYTE $6A
ROM4:B3B3   .BYTE $76
ROM4:B3B4   .BYTE $7D
ROM4:B3B5   .BYTE $80
ROM4:B3B6   .BYTE $7D
ROM4:B3B7   .BYTE $76
ROM4:B3B8   .BYTE $6A
ROM4:B3B9   .BYTE $5A
ROM4:B3BA   .BYTE $47
ROM4:B3BB   .BYTE $30
ROM4:B3BC   .BYTE $18
 
Subroutine update_spinning_hearts_patra_2
ROM4:B3BD update_spinning_hearts_patra_2:
ROM4:B3BD STA var_6
ROM4:B3BE STY var_5
ROM4:B3BF LDA object_tile_offset_whole,X
ROM4:B3C0 AND #$F
ROM4:B3C1 TAY
ROM4:B3C2 LDA spinning_hearts_tile_offset_table,Y
ROM4:B3C3 STA var_0
ROM4:B3C4 LDA object_walk_speed,X
ROM4:B3C5 LDY var_5
ROM4:B3C6 JSR update_spinning_hearts_patra_2a
ROM4:B3C7 LDA object_tile_offset_whole,X
ROM4:B3C8 AND #$18
ROM4:B3C9 CMP #$10
ROM4:B3CA BCC loc_133ED
ROM4:B3CB LDA enemy_state_0,X
ROM4:B3CC SEC
ROM4:B3CD SBC var_2
ROM4:B3CE STA enemy_state_0,X
ROM4:B3CF LDA object_x,X
ROM4:B3D0 SBC var_3
ROM4:B3D1 JMP loc_133FA
 
ROM4:B3ED loc_133ED:
ROM4:B3ED LDA enemy_state_0,X
ROM4:B3EE CLC
ROM4:B3EF ADC var_2
ROM4:B3F0 STA enemy_state_0,X
ROM4:B3F1 LDA object_x,X
ROM4:B3F2 ADC var_3
 
ROM4:B3FA loc_133FA:
ROM4:B3FA STA object_x,X
ROM4:B3FB LDA object_tile_offset_whole,X
ROM4:B3FC CLC
ROM4:B3FD ADC #8
ROM4:B3FE AND #$F
ROM4:B3FF TAY
ROM4:B400 LDA spinning_hearts_tile_offset_table,Y
ROM4:B401 STA var_0
ROM4:B402 LDA object_walk_speed,X
ROM4:B403 LDY var_6
ROM4:B404 JSR update_spinning_hearts_patra_2a
ROM4:B405 LDA object_tile_offset_whole,X
ROM4:B406 SEC
ROM4:B407 SBC #8
ROM4:B408 AND #$18
ROM4:B409 CMP #$10
ROM4:B40A BCC loc_1342C
ROM4:B40B LDA enemy_projectile_speed_x,X
ROM4:B40C SEC
ROM4:B40D SBC var_2
ROM4:B40E STA enemy_projectile_speed_x,X
ROM4:B40F LDA object_y,X
ROM4:B410 SBC var_3
ROM4:B411 RTS
 
ROM4:B42C loc_1342C:
ROM4:B42C LDA enemy_projectile_speed_x,X
ROM4:B42D CLC
ROM4:B42E ADC var_2
ROM4:B42F STA enemy_projectile_speed_x,X
ROM4:B430 LDA object_y,X
ROM4:B431 ADC var_3
ROM4:B432 RTS
 
Subroutine update_spinning_hearts_patra_2a
ROM4:B43A update_spinning_hearts_patra_2a:
ROM4:B43A STA var_1
ROM4:B43B LDA #0
ROM4:B43C STA var_2
ROM4:B43D STA var_3
 
ROM4:B43E loop:
ROM4:B43E ASL var_2
ROM4:B43F ROL var_3
ROM4:B440 ASL var_0
ROM4:B441 BCC skip
ROM4:B442 LDA var_2
ROM4:B443 CLC
ROM4:B444 ADC var_1
ROM4:B445 STA var_2
ROM4:B446 BCC skip
ROM4:B447 INC var_3
 
ROM4:B448 skip:
ROM4:B448 DEY
ROM4:B449 BNE loop
ROM4:B44A RTS
 
Subroutine update_spinning_hearts_patra_1
ROM4:B459 update_spinning_hearts_patra_1:
ROM4:B459 STA var_10 ; byte_380[X] -= A
ROM4:B45A LDA enemy_state_11,X
ROM4:B45B SEC
ROM4:B45C SBC var_10
ROM4:B45D STA enemy_state_11,X
ROM4:B45E LDA object_tile_offset_whole,X ; object_tile_offset_whole -= var_11
  ; object_tile_offset_whole &= 0x1F
ROM4:B45F SBC var_11
ROM4:B460 AND #$1F
ROM4:B461 STA object_tile_offset_whole,X
ROM4:B462 RTS
 
ROM4:B463 Skipped empty chunk
Subroutine rom4_OnReset
ROM4:BF50 rom4_OnReset:
ROM4:BF50 SEI
ROM4:BF51 CLD
ROM4:BF52 LDA #0
ROM4:BF53 STA PPUCTRL
ROM4:BF54 LDX #$FF
ROM4:BF55 TXS
 
ROM4:BF56 loop1:
ROM4:BF56 LDA PPUSTATUS
ROM4:BF57 AND #$80
ROM4:BF58 BEQ loop1
 
ROM4:BF59 loop2:
ROM4:BF59 LDA PPUSTATUS
ROM4:BF5A AND #$80
ROM4:BF5B BEQ loop2
ROM4:BF5C ORA #$FF
ROM4:BF5D STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BF5E STA loc_12000
ROM4:BF5F STA $C000
ROM4:BF60 STA $E000
ROM4:BF61 LDA #$F
ROM4:BF62 JSR rom4_set_mmc_control_register
ROM4:BF63 LDA #0
ROM4:BF64 STA loc_12000
ROM4:BF65 LSR A
ROM4:BF66 STA loc_12000
ROM4:BF67 LSR A
ROM4:BF68 STA loc_12000
ROM4:BF69 LSR A
ROM4:BF6A STA loc_12000
ROM4:BF6B LSR A
ROM4:BF6C STA loc_12000
ROM4:BF6D LDA #7
ROM4:BF6E JSR rom4_set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM4:BF6F JMP continue_setup
 
Subroutine rom4_set_mmc_control_register
ROM4:BF98 rom4_set_mmc_control_register:
ROM4:BF98 STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BF99 LSR A
ROM4:BF9A STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BF9B LSR A
ROM4:BF9C STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BF9D LSR A
ROM4:BF9E STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BF9F LSR A
ROM4:BFA0 STA play_boss_pain_sound_after_hit ; If the current enemy was just hit (has 16 invincibility
  ; frames), play Sound0_BossPainSound.
ROM4:BFA1 RTS
 
Subroutine rom4_set_prg_bank
; Map the ROM bank specified in A to $8000-$BFFF.
ROM4:BFAC rom4_set_prg_bank:
ROM4:BFAC STA $E000
ROM4:BFAD LSR A
ROM4:BFAE STA $E000
ROM4:BFAF LSR A
ROM4:BFB0 STA $E000
ROM4:BFB1 LSR A
ROM4:BFB2 STA $E000
ROM4:BFB3 LSR A
ROM4:BFB4 STA $E000
ROM4:BFB5 RTS
 
ROM4:BFB6 Skipped empty chunk
 
Segment: ROM5
 
Subroutine update_start_menu
ROM5:8000 update_start_menu:
ROM5:8000 JSR call_update_start_menu_state
ROM5:8001 JMP update_fairy_refill_rupees_and_hud ; Update fairy/triforce health refill, rupee gain/loss and parts of the HUD.
  ; This is called during the Triforce fanfare (probably for health refill).
  ; It's also called from update_start_menu.
 
ROM5:8002 call_update_start_menu_state:
ROM5:8002 LDA gameplay_menu_state
ROM5:8003 LDY dungeon_idx
ROM5:8004 BEQ update_start_menu_overworld ; branch if overworld
ROM5:8005 JSR call_jump_table
 
ROM5:8006   .WORD locret_14056
ROM5:8008   .WORD show_menu_2
ROM5:800A   .WORD show_menu_3
ROM5:800C   .WORD show_menu_4
ROM5:800E   .WORD show_menu_5
ROM5:8010   .WORD show_menu_6_dungeon
ROM5:8012   .WORD show_menu_7_dungeon
ROM5:8014   .WORD show_menu_8
ROM5:8016   .WORD show_menu_9
 
Subroutine update_start_menu_overworld
ROM5:8021 update_start_menu_overworld:
ROM5:8021 JSR call_jump_table
 
ROM5:8022   .WORD locret_14056
ROM5:8024   .WORD show_menu_1_overworld
ROM5:8026   .WORD show_menu_2
ROM5:8028   .WORD show_menu_3
ROM5:802A   .WORD show_menu_4
ROM5:802C   .WORD show_menu_5
ROM5:802E   .WORD show_menu_6_overworld
ROM5:8030   .WORD show_menu_7_overworld
ROM5:8032   .WORD show_menu_8
ROM5:8034   .WORD show_menu_9
 
Subroutine show_menu_2
ROM5:8038 show_menu_2:
ROM5:8038 JSR clear_oam ; Clear the OAM buffer.
ROM5:8039 JSR setup_minimap_triforce_position_unless_in_cellar_or_whirlwind
ROM5:803A JSR setup_minimap_triforce_position_if_holding_compass
ROM5:803B LDA #$EF
ROM5:803C STA desired_ppuscroll_y
ROM5:803D STA alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
ROM5:803E LDA #1
ROM5:803F JSR sub_14130
ROM5:8040 INC gameplay_menu_state
ROM5:8041 LDA #$2B
ROM5:8042 STA start_menu_scroll_progress ; Set to 0x2B.
ROM5:8043 LDA #$7F
ROM5:8044 STA start_menu_scroll_drawing_map_position ; Set to 0x7F.
 
ROM5:8056 locret_14056:
ROM5:8056 RTS
 
Subroutine show_menu_3
ROM5:8057 show_menu_3:
ROM5:8057 LDA #$48
 
ROM5:8059 loc_14059: ; Set to 0x48, 0x4A, 0x4C or 0x5C
ROM5:8059 STA current_ppu_command_index
 
ROM5:805B loc_1405B:
ROM5:805B INC gameplay_menu_state
ROM5:805C RTS
 
Subroutine show_menu_4
ROM5:805E show_menu_4:
ROM5:805E LDA #$4A
ROM5:805F BNE loc_14059
 
ROM5:8062 show_menu_5:
ROM5:8062 LDA #$4C
ROM5:8063 BNE loc_14059
 
ROM5:8066 show_menu_6_dungeon:
ROM5:8066 JSR send_start_menu_ppu_commands
ROM5:8067 JMP loc_1405B
 
Subroutine show_menu_6_overworld
ROM5:806C show_menu_6_overworld:
ROM5:806C LDA #$5C
ROM5:806D BNE loc_14059
 
ROM5:8070 show_menu_7_overworld:
ROM5:8070 JSR show_menu_6_7_overworld_sub
ROM5:8071 JMP loc_14079
 
Subroutine show_menu_7_dungeon
ROM5:8076 show_menu_7_dungeon:
ROM5:8076 JSR send_start_menu_ppu_commands
 
ROM5:8079 loc_14079:
ROM5:8079 LDA #3
ROM5:807A JSR sub_14130
ROM5:807B LDA desired_ppuscroll_y
ROM5:807C SEC
ROM5:807D SBC #3
ROM5:807E STA desired_ppuscroll_y
ROM5:807F CMP #$41
ROM5:8080 BNE locret_140D3
ROM5:8081 INC gameplay_menu_state
ROM5:8082 LDA dungeon_idx
ROM5:8083 BEQ locret_140D3
ROM5:8084 LDA game_mode
ROM5:8085 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM5:8086 BEQ locret_140D3
ROM5:8087 LDA map_location
ROM5:8088 AND #$F
ROM5:8089 ASL A
ROM5:808A ASL A
ROM5:808B ASL A
ROM5:808C STA var_0
ROM5:808D LDA ppu_data_for_current_dungeon.map_start_pos_x
ROM5:808E CMP #8
ROM5:808F BCC loc_140B3
ROM5:8090 LDA #$10
ROM5:8091 SBC ppu_data_for_current_dungeon.map_start_pos_x
ROM5:8092 ASL A
ROM5:8093 ASL A
ROM5:8094 ASL A
ROM5:8095 JSR inverse
ROM5:8096 JMP loc_140B6
 
ROM5:80B3 loc_140B3:
ROM5:80B3 ASL A
ROM5:80B4 ASL A
ROM5:80B5 ASL A
 
ROM5:80B6 loc_140B6:
ROM5:80B6 CLC
ROM5:80B7 ADC var_0
ROM5:80B8 CLC
ROM5:80B9 ADC #$62
ROM5:80BA STA sprite_oam_data_53
ROM5:80BB LDA map_location
ROM5:80BC AND #$F0
ROM5:80BD LSR A
ROM5:80BE ADC #$69
ROM5:80BF STA sprite_oam_data_50
ROM5:80C0 LDA #$3E
ROM5:80C1 STA sprite_oam_data_51
ROM5:80C2 LDA #0
ROM5:80C3 STA sprite_oam_data_52
 
ROM5:80D3 locret_140D3:
ROM5:80D3 RTS
 
Subroutine show_menu_8
ROM5:80D4 show_menu_8:
ROM5:80D4 JSR show_menu_8_1 ; This is related to drawing the inventory sprites on the start menu.
ROM5:80D5 JSR show_menu_8_2 ; This is related to drawing the inventory sprites on the start menu.
ROM5:80D6 LDA controller_2_cur ; P2 buttons being held
ROM5:80D7 AND #$88
ROM5:80D8 CMP #$88
ROM5:80D9 BNE loc_140F3
ROM5:80DA JSR clear_game_mode_task_and_state
ROM5:80DB STA gameplay_menu_state
ROM5:80DC LDA #8
ROM5:80DD STA game_mode
ROM5:80DE LDA #0
ROM5:80DF STA audio_misc_0619
ROM5:80E0 JMP loc_14A8E
 
ROM5:80F3 loc_140F3: ; P1 buttons pressed on this frame
ROM5:80F3 LDA controller_1_pressed
ROM5:80F4 AND #$10
ROM5:80F5 BEQ locret_14151
ROM5:80F6 LDA sprite_oam_data_54
ROM5:80F7 PHA
ROM5:80F8 LDA sprite_oam_data_58
ROM5:80F9 PHA
ROM5:80FA JSR clear_oam ; Clear the OAM buffer.
ROM5:80FB PLA
ROM5:80FC STA sprite_oam_data_58
ROM5:80FD PLA
ROM5:80FE STA sprite_oam_data_54
ROM5:80FF INC gameplay_menu_state
ROM5:8100 RTS
 
Subroutine show_menu_9
ROM5:810F show_menu_9:
ROM5:810F LDA #$FD
ROM5:8110 JSR sub_14130
ROM5:8111 LDA desired_ppuscroll_y
ROM5:8112 CLC
ROM5:8113 ADC #3
ROM5:8114 STA desired_ppuscroll_y
ROM5:8115 CMP #$F0
ROM5:8116 BCC locret_14151
ROM5:8117 STA alternate_ppu_nametable ; If true, the nametable will be swapped between 0x2000 and 0x2800 at the beginning of the next frame.
ROM5:8118 LDA dungeon_idx
ROM5:8119 BEQ loc_14128
ROM5:811A JSR setup_dungeon_only_sprites
 
ROM5:8128 loc_14128:
ROM5:8128 LDA #0
ROM5:8129 STA desired_ppuscroll_y
ROM5:812A STA gameplay_menu_state
ROM5:812B LDA #2
 
Subroutine sub_14130
ROM5:8130 sub_14130:
ROM5:8130 STA var_0
ROM5:8131 LDA sprite_oam_data_54
ROM5:8132 CMP #$F8
ROM5:8133 BEQ loc_1413F
ROM5:8134 CLC
ROM5:8135 ADC var_0
ROM5:8136 STA sprite_oam_data_54
 
ROM5:813F loc_1413F:
ROM5:813F LDA dungeon_idx
ROM5:8140 BEQ locret_14151
ROM5:8141 JSR check_has_compass_in_current_dungeon ; Set not equal if we have the compass for this dungeon.
ROM5:8142 BEQ locret_14151
ROM5:8143 LDA sprite_oam_data_58
ROM5:8144 CLC
ROM5:8145 ADC var_0
ROM5:8146 STA sprite_oam_data_58
 
ROM5:8151 locret_14151:
ROM5:8151 RTS
 
ROM5:8152 byte_14152: .BYTE 0
ROM5:8153   .BYTE 8
ROM5:8154   .BYTE 9
ROM5:8155   .BYTE 1
ROM5:8156   .BYTE $A
ROM5:8157   .BYTE $B
ROM5:8158   .BYTE $12
ROM5:8159   .BYTE $1E
ROM5:815A   .BYTE $1F
ROM5:815B   .BYTE $17
ROM5:815C   .BYTE $24
ROM5:815D   .BYTE $25
ROM5:815E   .BYTE $13
ROM5:815F   .BYTE $14
ROM5:8160   .BYTE $21
ROM5:8161   .BYTE $13
ROM5:8162   .BYTE $20
ROM5:8163   .BYTE $21
ROM5:8164   .BYTE $15
ROM5:8165   .BYTE $16
ROM5:8166   .BYTE $22
ROM5:8167   .BYTE $16
ROM5:8168   .BYTE $22
ROM5:8169   .BYTE $23
ROM5:816A unk_1416A: .BYTE $E7
ROM5:816B   .BYTE $E7
ROM5:816C   .BYTE $F5
ROM5:816D   .BYTE $E8
ROM5:816E   .BYTE $F5
ROM5:816F   .BYTE $E8
ROM5:8170   .BYTE $E7
ROM5:8171   .BYTE $E7
ROM5:8172   .BYTE $F5
ROM5:8173   .BYTE $E8
ROM5:8174   .BYTE $F5
ROM5:8175   .BYTE $E8
ROM5:8176   .BYTE $E5
ROM5:8177   .BYTE $F5
ROM5:8178   .BYTE $E5
ROM5:8179   .BYTE $E8
ROM5:817A   .BYTE $F5
ROM5:817B   .BYTE $E8
ROM5:817C   .BYTE $F5
ROM5:817D   .BYTE $E6
ROM5:817E   .BYTE $E6
ROM5:817F   .BYTE $E7
ROM5:8180   .BYTE $E7
ROM5:8181   .BYTE $F5
ROM5:8182 byte_14182: .BYTE $E9
ROM5:8183   .BYTE $E9
ROM5:8184   .BYTE $24
ROM5:8185   .BYTE $EA
ROM5:8186   .BYTE $24
ROM5:8187   .BYTE $EA
ROM5:8188   .BYTE $E9
ROM5:8189   .BYTE $E9
ROM5:818A   .BYTE $24
ROM5:818B   .BYTE $EA
ROM5:818C   .BYTE $24
ROM5:818D   .BYTE $EA
ROM5:818E   .BYTE $24
ROM5:818F   .BYTE $24
ROM5:8190   .BYTE $24
ROM5:8191   .BYTE $24
ROM5:8192   .BYTE $24
ROM5:8193   .BYTE $24
ROM5:8194   .BYTE $24
ROM5:8195   .BYTE $24
ROM5:8196   .BYTE $24
ROM5:8197   .BYTE $24
ROM5:8198   .BYTE $24
ROM5:8199   .BYTE $24
 
Subroutine show_menu_1_overworld
ROM5:819A show_menu_1_overworld:
ROM5:819A LDY #$17
 
ROM5:819C loc_1419C:
ROM5:819C LDX byte_14152,Y
ROM5:819D LDA byte_14182,Y
ROM5:819E STA unk_2684B,X
ROM5:819F DEY
ROM5:81A0 BPL loc_1419C
ROM5:81A1 INY
ROM5:81A2 LDA #1
ROM5:81A3 STA var_6
 
ROM5:81AD loc_141AD:
ROM5:81AD LDA #3
ROM5:81AE STA var_7
 
ROM5:81B1 loc_141B1:
ROM5:81B1 LDX byte_14152,Y
ROM5:81B2 LDA var_6
ROM5:81B3 BIT triforce_pieces_collected
ROM5:81B4 BEQ loc_141D1
ROM5:81B5 LDA unk_2684B,X
ROM5:81B6 CMP #$E5
ROM5:81B7 BEQ loc_141CC
ROM5:81B8 CMP #$E6
ROM5:81B9 BEQ loc_141CC
ROM5:81BA LDA unk_1416A,Y
ROM5:81BB JMP loc_141CE
 
ROM5:81CC loc_141CC:
ROM5:81CC LDA #$F5
 
ROM5:81CE loc_141CE:
ROM5:81CE STA unk_2684B,X
 
ROM5:81D1 loc_141D1:
ROM5:81D1 INY
ROM5:81D2 DEC var_7
ROM5:81D3 BNE loc_141B1
ROM5:81D4 ASL var_6
ROM5:81D5 BNE loc_141AD
ROM5:81D6 INC gameplay_menu_state
ROM5:81D7 RTS
 
Subroutine task1_Scroll_state_3a
ROM5:81DD task1_Scroll_state_3a:
 
ROM5:81DD LDA frame_counter
ROM5:81DE AND #3 ; A = frame & 3
ROM5:81DF LDY dungeon_idx
ROM5:81E0 BNE in_dungeon
ROM5:81E1 AND #1 ; A = frame & 1
 
ROM5:81E2 in_dungeon:
ROM5:81E2 CMP byte_E6
ROM5:81E3 BNE loc_14255
ROM5:81E4 LDA #ControllerBits_Dpad_Up
ROM5:81E5 BIT object_direction
ROM5:81E6 BEQ not_up
ROM5:81E7 DEC byte_E9
ROM5:81E8 LDA object_y
ROM5:81E9 CMP #$DD
ROM5:81EA BCS loc_141FD
ROM5:81EB ADC #8
ROM5:81EC STA object_y
 
ROM5:81FD loc_141FD:
ROM5:81FD LDA byte_E2
ROM5:81FE SEC
ROM5:81FF SBC #$20
ROM5:8200 STA byte_E2
ROM5:8201 BCS loc_14208
ROM5:8202 DEC byte_58
 
ROM5:8208 loc_14208:
ROM5:8208 CMP #$E0
ROM5:8209 BNE locret_1421E
ROM5:820A LDA byte_58
ROM5:820B CMP #$20
ROM5:820C BEQ loc_1421F
ROM5:820D CMP #$27
ROM5:820E BNE locret_1421E
ROM5:820F LDA #$23
ROM5:8210 STA byte_58
ROM5:8211 LDA #$A0
ROM5:8212 STA byte_E2
 
ROM5:821E locret_1421E:
ROM5:821E RTS
 
ROM5:821F loc_1421F:
ROM5:821F INC byte_58
 
ROM5:8220 loop:
ROM5:8220 LDA #0
ROM5:8221 STA byte_E2
 
ROM5:8225 loc_14225: ; Advance task_state and return.
ROM5:8225 INC task_state
ROM5:8226 RTS
 
ROM5:8227 not_up:
ROM5:8227 LSR A
ROM5:8228 BIT object_direction
ROM5:8229 BEQ loc_14255
ROM5:822A INC byte_E9
ROM5:822B LDA object_y
ROM5:822C CMP #$3E
ROM5:822D BCC loc_14239
ROM5:822E SBC #8
ROM5:822F STA object_y
 
ROM5:8239 loc_14239:
ROM5:8239 LDA byte_E2
ROM5:823A CLC
ROM5:823B ADC #$20
ROM5:823C STA byte_E2
ROM5:823D BCC loc_14244
ROM5:823E INC byte_58
 
ROM5:8244 loc_14244:
ROM5:8244 CMP #$C0
ROM5:8245 BNE locret_14287
ROM5:8246 LDA byte_58
ROM5:8247 CMP #$23
ROM5:8248 BNE locret_14287
ROM5:8249 LDA #$28
ROM5:824A STA byte_58
ROM5:824B JMP loop
 
ROM5:8255 loc_14255:
ROM5:8255 LDA #2
ROM5:8256 LDX #$FE
ROM5:8257 LDY dungeon_idx
ROM5:8258 BNE in_dungeon2
ROM5:8259 ASL A
ROM5:825A LDX #$FC
 
ROM5:825B in_dungeon2:
ROM5:825B STA var_0
ROM5:825C STX var_1
ROM5:825D LDA #ControllerBits_Dpad_Left
ROM5:825E BIT object_direction
ROM5:825F BEQ loc_14288 ; Branch if not left
ROM5:8260 DEC byte_E8
ROM5:8261 LDA object_x
ROM5:8262 CMP #$F0
ROM5:8263 BCS loc_14276 ; Skip increasing var_0 if X >= 0xF0
ROM5:8264 ADC var_0
ROM5:8265 STA object_x
 
ROM5:8276 loc_14276: ; Subtract var_0 from desired_ppuscroll_x.
ROM5:8276 LDA desired_ppuscroll_x
ROM5:8277 SEC
ROM5:8278 SBC var_0
ROM5:8279 STA desired_ppuscroll_x
ROM5:827A BEQ loc_14225 ; Advance task_state and return.
ROM5:827B CMP var_1
ROM5:827C BNE locret_14287
 
ROM5:8283 loc_14283:
ROM5:8283 LDA #PPUCTRLBits_BaseNametable_2400
ROM5:8284 STA byte_5F ; Set to PPUCTRLBits_BaseNametable_2400
 
ROM5:8287 locret_14287:
ROM5:8287 RTS
 
Function chunk for task1_Scroll_state_3a
ROM5:8288 loc_14288:
ROM5:8288 LSR A
ROM5:8289 BIT object_direction
ROM5:828A BEQ locret_14287
ROM5:828B INC byte_E8
ROM5:828C LDA object_x
ROM5:828D CMP #1
ROM5:828E BCC loc_14299
ROM5:828F SBC var_0
ROM5:8290 STA object_x
 
ROM5:8299 loc_14299:
ROM5:8299 LDA desired_ppuscroll_x
ROM5:829A CLC
ROM5:829B ADC var_0
ROM5:829C STA desired_ppuscroll_x
ROM5:829D BNE locret_14287
ROM5:829E JSR loc_14283
ROM5:829F JMP loc_14225 ; Advance task_state and return.
 
Subroutine task0_Scrolling_work
ROM5:82A8 task0_Scrolling_work:
ROM5:82A8 LDA task_state
ROM5:82A9 JSR call_jump_table
 
ROM5:82AA   .WORD task0_Scrolling_0
ROM5:82AC   .WORD task0_Scrolling_1
ROM5:82AE   .WORD task0_Scrolling_2
ROM5:82B0   .WORD task0_Scrolling_3
ROM5:82B2   .WORD task0_Scrolling_3
ROM5:82B4   .WORD task0_Scrolling_5
ROM5:82B6   .WORD task0_Scrolling_6
 
Subroutine task0_Scrolling_1
ROM5:82BB task0_Scrolling_1:
ROM5:82BB JSR update_minimap_and_link_sprite
ROM5:82BC JSR update_link_sprite_and_check_ladder_if_overworld ; Like update_link_sprite_and_check_ladder, but do nothing if
  ; we're in a dungeon.
ROM5:82BD LDA unlocked_door_directions ; Load to save to previous_unlocked_door_directions.
ROM5:82BE STA previous_unlocked_door_directions ; Set to unlocked_door_directions. This saves the directions
  ; that were unlocked before we call set_required_door_direction.
ROM5:82BF JSR set_required_door_direction ; The door opposite to the direction we're moving must be open. If we're moving up,
  ; the bottom door must be open, and so on. Set unlocked_door_directions to the direction
  ; that must be open.
ROM5:82C0 DEC byte_ED
ROM5:82C1 INC task_state
ROM5:82C2 JSR task0_Scrolling_1_subtask
ROM5:82C3 LDA map_location_transitioning_to
ROM5:82C4 BMI ret
ROM5:82C5 LDA map_location ; Push map_location.
ROM5:82C6 PHA
ROM5:82C7 LDY object_direction
ROM5:82C8 CPY #ControllerBits_Dpad_Up
ROM5:82C9 BEQ not_up
ROM5:82CA LDA map_location_transitioning_to
ROM5:82CB STA map_location
 
ROM5:82CC not_up:
ROM5:82CC JSR sub_143D7
ROM5:82CD LDA #$15
ROM5:82CE STA byte_E9 ; Set to 0x15
ROM5:82CF LDY object_direction
ROM5:82D0 CPY #ControllerBits_Dpad_Up
ROM5:82D1 BEQ is_up
ROM5:82D2 JSR sub_168C4
 
ROM5:82D3 pop_and_store_map_location:
ROM5:82D3 PLA
ROM5:82D4 STA map_location ; Restore map_location.
 
ROM5:82D5 ret:
ROM5:82D5 RTS
 
ROM5:82D6 is_up:
ROM5:82D6 JSR call_sub_164F6_with_previous_unlocked_door_directions
ROM5:82D7 JMP pop_and_store_map_location
 
Subroutine call_sub_164F6_with_previous_unlocked_door_directions
ROM5:82FB call_sub_164F6_with_previous_unlocked_door_directions:
ROM5:82FB LDA dungeon_idx ; Skip on the overworld.
ROM5:82FC BEQ ret
ROM5:82FD LDA unlocked_door_directions ; Save unlocked_door_directions.
ROM5:82FE PHA
ROM5:82FF LDA previous_unlocked_door_directions
ROM5:8300 STA unlocked_door_directions ; Set to previous_unlocked_door_directions.
ROM5:8301 JSR sub_164F6
ROM5:8302 PLA
ROM5:8303 STA unlocked_door_directions ; Restore unlocked_door_directions.
 
ROM5:8304 ret:
ROM5:8304 RTS
 
Subroutine task0_Scrolling_0
ROM5:830E task0_Scrolling_0:
 
ROM5:830E LDA held_by_recorder_whirlwind ; If 1, Link is outbound on the whirlwind.
  ; If 2, Link is inbound on the whirlwind.
ROM5:830F BEQ loc_14317
ROM5:8310 LDA displayed_map_location
ROM5:8311 STA map_location
 
ROM5:8317 loc_14317: ; 0 = closed, 0x01-0x0B=lake palette shift, 0x0C=open
ROM5:8317 LDA recorder_lake_state
ROM5:8318 BEQ loc_1433A
ROM5:8319 JMP loc_1FF34
 
Subroutine task0_Scrolling_2
ROM5:831F task0_Scrolling_2:
ROM5:831F JSR sub_16924
ROM5:8320 LDA ppu_command_buffer
ROM5:8321 AND #$F
ROM5:8322 CLC
ROM5:8323 ADC #$27
ROM5:8324 STA ppu_command_buffer
ROM5:8325 LDA object_direction
ROM5:8326 CMP #4
ROM5:8327 BCS loc_14336
ROM5:8328 INC ppu_command_buffer
 
ROM5:8336 loc_14336:
ROM5:8336 DEC byte_E9
ROM5:8337 BPL locret_1433C
 
ROM5:833A loc_1433A:
ROM5:833A INC task_state
 
ROM5:833C locret_1433C:
ROM5:833C RTS
 
Subroutine task0_Scrolling_3
ROM5:833D task0_Scrolling_3:
ROM5:833D LDA #8
ROM5:833E BIT object_direction
ROM5:833F BNE loc_14348
ROM5:8340 LSR A
ROM5:8341 BIT object_direction
 
ROM5:8346 loc_14346:
ROM5:8346 BEQ loc_14358
 
ROM5:8348 loc_14348:
ROM5:8348 LDA #$C0
 
ROM5:834A loc_1434A:
ROM5:834A LDY #$17
ROM5:834B LDX task_state
ROM5:834C CPX #3
ROM5:834D BEQ loc_14355
ROM5:834E JSR loc_1448C
 
ROM5:8355 loc_14355:
ROM5:8355 JMP loc_14CAE
 
ROM5:8358 loc_14358:
ROM5:8358 LDA #$D0
 
ROM5:835A loc_1435A:
ROM5:835A BNE loc_1434A
 
ROM5:835C task0_Scrolling_5:
ROM5:835C LDA #0
ROM5:835D STA next_palette_cycle
ROM5:835E LDA object_direction
ROM5:835F CMP #4
ROM5:8360 BCS loc_1436B
ROM5:8361 LDY #PPUCommandIndices_TextScrolling
ROM5:8362 STY current_ppu_command_index ; Set to PPUCommandIndices_TextScrolling.
 
ROM5:836B loc_1436B:
ROM5:836B CMP #8
ROM5:836C BNE loc_1437C
ROM5:836D LDA map_location
ROM5:836E PHA
ROM5:836F LDA map_location_transitioning_to
ROM5:8370 STA map_location
ROM5:8371 JSR sub_168C4
ROM5:8372 PLA
ROM5:8373 STA map_location
 
ROM5:837C loc_1437C:
ROM5:837C LDY map_location_transitioning_to
ROM5:837D JSR check_if_dark
ROM5:837E BEQ loc_143A3
ROM5:837F LDY map_location
ROM5:8380 JSR check_if_dark
ROM5:8381 BNE loc_14397
 
ROM5:838A loc_1438A:
ROM5:838A LDA #0
ROM5:838B STA lighting_room_state ; Set to 0.
ROM5:838C LDA #$40
ROM5:838D STA next_palette_cycle ; Set to 0x40.
ROM5:838E INC task_state
ROM5:838F RTS
 
ROM5:8397 loc_14397:
ROM5:8397 LDA lighting_room_state
ROM5:8398 BNE loc_1438A
ROM5:8399 BEQ loc_143A3
 
ROM5:839E task0_Scrolling_6:
ROM5:839E JSR update_timed_palette_cycle
ROM5:839F BNE locret_143AD
 
ROM5:83A3 loc_143A3:
ROM5:83A3 LDA map_location_transitioning_to
ROM5:83A4 STA map_location
ROM5:83A5 JSR set_oam_sprite_0_after_hud ; This puts a bomb sprite in the HUD overlapping the bomb
  ; in the background. This is used to trigger a sprite zero
  ; hit after the PPU finishes drawing the HUD and before it
  ; starts drawing the play field. OnNMI waits for this in
  ; wait_for_sprite_0_hit to allow changing PPU flags to
  ; scroll the play field during transitions without scrolling
  ; the HUD.
 
  ; https://wiki.nesdev.com/w/index.php/PPU_OAM#Sprite_zero_hits
ROM5:83A6 JSR start_task1 ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
 
ROM5:83AD locret_143AD:
ROM5:83AD RTS
 
ROM5:83AE bomb_sprite0_oam_sprite: .BYTE $27
ROM5:83AF   .BYTE $61
ROM5:83B0   .BYTE $20
ROM5:83B1   .BYTE $58
 
Subroutine set_oam_sprite_0_after_hud
; This puts a bomb sprite in the HUD overlapping the bomb ; in the background. This is used to trigger a sprite zero ; hit after the PPU finishes drawing the HUD and before it ; starts drawing the play field. OnNMI waits for this in ; wait_for_sprite_0_hit to allow changing PPU flags to ; scroll the play field during transitions without scrolling ; the HUD. ; ; https://wiki.nesdev.com/w/index.php/PPU_OAM#Sprite_zero_hits
ROM5:83B2 set_oam_sprite_0_after_hud:
ROM5:83B2 LDA #1
ROM5:83B3 STA do_ppu_work_after_sprite0_next_frame ; Set to 1.
ROM5:83B4 LDY #3
 
ROM5:83B5 loop:
ROM5:83B5 LDA bomb_sprite0_oam_sprite,Y
ROM5:83B6 STA sprite_oam_data,Y
ROM5:83B7 DEY
ROM5:83B8 BPL loop
ROM5:83B9 RTS
 
Subroutine set_required_door_direction
; The door opposite to the direction we're moving must be open. If we're moving up, ; the bottom door must be open, and so on. Set unlocked_door_directions to the direction ; that must be open.
ROM5:83C2 set_required_door_direction:
ROM5:83C2 LDA object_direction
ROM5:83C3 LSR A ; Shift left and up -> right and down and mask them out.
ROM5:83C4 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
ROM5:83C5 STA var_0
ROM5:83C6 LDA object_direction
ROM5:83C7 ASL A ; Shift right and down -> left and up and mask them out.
ROM5:83C8 AND #ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
ROM5:83C9 ORA var_0 ; Combine the two.
ROM5:83CA STA unlocked_door_directions ; Set to the direction that must be open due to the direction
  ; we entered the room.
ROM5:83CB RTS
 
ROM5:83D3 byte_143D3: .BYTE 0
ROM5:83D4   .BYTE $55
ROM5:83D5   .BYTE $AA
ROM5:83D6   .BYTE $FF
 
Subroutine sub_143D7
ROM5:83D7 sub_143D7:
ROM5:83D7 TAY
ROM5:83D8 LDA dungeon_screen_data_0,Y ; This is copied from dungeon_screen_attr_1Q_1, etc.
ROM5:83D9 AND #ScreenData_Overworld_0_Palette
ROM5:83DA TAX
ROM5:83DB LDA byte_143D3,X
ROM5:83DC LDX #$2F
 
ROM5:83DD loop:
ROM5:83DD STA temp_ppu_command_buffer,X
ROM5:83DE DEX
ROM5:83DF BPL loop
ROM5:83E0 LDA dungeon_screen_data_1,Y
ROM5:83E1 AND #ScreenDataOverworld_1_Palette
ROM5:83E2 TAX
ROM5:83E3 LDY #9
 
ROM5:83F1 loc_143F1:
ROM5:83F1 TYA
ROM5:83F2 AND #7
ROM5:83F3 BEQ loc_14404
ROM5:83F4 CMP #7
ROM5:83F5 BEQ loc_14404
ROM5:83F6 CPY #$21
ROM5:83F7 BCS loc_1440A
ROM5:83F8 LDA byte_143D3,X
ROM5:83F9 STA temp_ppu_command_buffer,Y
 
ROM5:8404 loc_14404:
ROM5:8404 INY
ROM5:8405 CPY #$27
ROM5:8406 BCC loc_143F1
ROM5:8407 RTS
 
ROM5:840A loc_1440A:
ROM5:840A LDA byte_143D3,X
ROM5:840B AND #$F
ROM5:840C STA var_0
ROM5:840D LDA temp_ppu_command_buffer,Y
ROM5:840E AND #$F0
ROM5:840F ORA var_0
ROM5:8410 STA temp_ppu_command_buffer,Y
ROM5:8411 JMP loc_14404
 
Subroutine task1_Scroll_run_task_state_and_continue
ROM5:841E task1_Scroll_run_task_state_and_continue:
ROM5:841E JSR task1_Scroll_run_task_state
ROM5:841F JMP update_link_sprite_and_check_ladder_if_overworld ; Like update_link_sprite_and_check_ladder, but do nothing if
  ; we're in a dungeon.
 
Subroutine task1_Scroll_run_task_state
ROM5:8424 task1_Scroll_run_task_state:
ROM5:8424 LDA task_state
ROM5:8425 JSR call_jump_table
 
ROM5:8426   .WORD task1_Scroll_state_0
ROM5:8428   .WORD task1_Scroll_state_1
ROM5:842A   .WORD task1_Scroll_state_2
ROM5:842C   .WORD task1_Scroll_state_3
ROM5:842E   .WORD task1_Scroll_state_4
ROM5:8430   .WORD task1_Scroll_state_5
ROM5:8432   .WORD task1_Scroll_state_6
ROM5:8434   .WORD task1_Scroll_state_7
 
Subroutine task1_Scroll_state_0
ROM5:8439 task1_Scroll_state_0:
ROM5:8439 LDA #0
ROM5:843A STA byte_E2
ROM5:843B STA desired_ppuscroll_x
ROM5:843C LDA #ControllerBits_Dpad_Up
ROM5:843D BIT object_direction
ROM5:843E BNE loc_14471
ROM5:843F LSR A
ROM5:8440 BIT object_direction
ROM5:8441 BEQ loc_14457
ROM5:8442 LDA #$21
ROM5:8443 STA byte_58
ROM5:8444 LDA #$FF
ROM5:8445 STA byte_E9 ; Set to 0xFF
 
ROM5:8452 task1_Scroll_advance_task_by_2:
ROM5:8452 INC task_state
ROM5:8453 INC task_state
ROM5:8454 RTS
 
ROM5:8457 loc_14457:
ROM5:8457 LDY #$A0
ROM5:8458 LDX dungeon_idx
ROM5:8459 BNE in_dungeon
ROM5:845A LDY #$E0
 
ROM5:845B in_dungeon:
ROM5:845B LSR A
ROM5:845C BIT object_direction
ROM5:845D BEQ loc_1446C
ROM5:845E LDY #$81
ROM5:845F LDX dungeon_idx
ROM5:8460 BNE loc_1446C
ROM5:8461 LDY #$41
 
ROM5:846C loc_1446C:
ROM5:846C STY byte_E8
ROM5:846D JMP task1_Scroll_advance_task_by_2
 
ROM5:8471 loc_14471:
ROM5:8471 LDA #$28
ROM5:8472 STA byte_58 ; Set to 0x28
ROM5:8473 LDA #$16
ROM5:8474 STA byte_E9 ; Set to 0x16
ROM5:8475 LDA map_location
ROM5:8476 JSR sub_143D7
 
ROM5:847E task1_Scroll_state_1:
ROM5:847E JSR sub_14484
ROM5:847F JMP sub_14501
 
Subroutine sub_14484
ROM5:8484 sub_14484:
ROM5:8484 LDA #$D0
ROM5:8485 LDY #$17
ROM5:8486 LDX task_state
ROM5:8487 BEQ ret ; SKip if task_state is 0.
 
ROM5:848C loc_1448C:
ROM5:848C LDY #$2F
ROM5:848D CLC
ROM5:848E ADC #$18
 
ROM5:848F ret:
ROM5:848F RTS
 
Subroutine task1_Scroll_state_2
ROM5:8492 task1_Scroll_state_2:
ROM5:8492 INC task_state
ROM5:8493 LDA frame_counter
ROM5:8494 CLC
ROM5:8495 ADC #1
ROM5:8496 AND #3
ROM5:8497 LDY dungeon_idx
ROM5:8498 BNE in_dungeon
ROM5:8499 AND #1
 
ROM5:849A in_dungeon:
ROM5:849A STA byte_E6
ROM5:849B RTS
 
Subroutine task1_Scroll_state_3
ROM5:84A4 task1_Scroll_state_3:
ROM5:84A4 JSR task1_Scroll_state_3a
ROM5:84A5 JSR task1_Scroll_state_3b
ROM5:84A6 LDA task_state
ROM5:84A7 CMP #3
ROM5:84A8 BEQ ret
ROM5:84A9 LDY #$FF
ROM5:84AA STY byte_E9 ; Set to 0xFF
ROM5:84AB STY byte_ED ; Set to 0xFF
ROM5:84AC INY
ROM5:84AD STY byte_E8 ; Set to 0
 
ROM5:84AE ret:
ROM5:84AE RTS
 
Subroutine task1_Scroll_state_6
ROM5:84BA task1_Scroll_state_6:
ROM5:84BA LDA dungeon_idx
ROM5:84BB BEQ task1_Scroll_state_7
ROM5:84BC LDY map_location
ROM5:84BD JSR check_if_dark
ROM5:84BE BEQ task1_Scroll_state_7
ROM5:84BF LDA #0
ROM5:84C0 STA byte_E9 ; Set to 0
ROM5:84C1 INC task_state
ROM5:84C2 RTS
 
ROM5:84CC task1_Scroll_state_7:
ROM5:84CC LDA #1
ROM5:84CD STA task_state ; Set to 1
ROM5:84CE LSR A
ROM5:84CF STA active_game_mode_task ; Set to 0
ROM5:84D0 STA byte_10C ; Set to 0
ROM5:84D1 STA transitioning_direction ; Set to 0
ROM5:84D2 STA do_ppu_work_after_sprite0_next_frame ; Set to 0
ROM5:84D3 LDA #GameMode_FinishScroll
ROM5:84D4 STA game_mode ; Set GameMode_FinishScroll
ROM5:84D5 RTS
 
Subroutine task1_Scroll_state_4
ROM5:84DF task1_Scroll_state_4:
ROM5:84DF LDA #8
ROM5:84E0 BIT object_direction
ROM5:84E1 BEQ task1_Scroll_state_5
ROM5:84E2 JMP task1_Scroll_advance_task_by_2
 
ROM5:84E8 task1_Scroll_state_5:
ROM5:84E8 LDA #$D0
ROM5:84E9 LDY #$17
ROM5:84EA LDX task_state
ROM5:84EB CPX #4
ROM5:84EC BEQ sub_14501
ROM5:84ED PHA
ROM5:84EE LDA object_direction
ROM5:84EF CMP #ControllerBits_Dpad_Down
ROM5:84F0 BCS vertical
ROM5:84F1 LDA #0
ROM5:84F2 STA byte_5F ; Set to 0
 
ROM5:84F3 vertical:
ROM5:84F3 PLA
ROM5:84F4 JSR loc_1448C
 
Subroutine sub_14501
ROM5:8501 sub_14501:
ROM5:8501 LDX #$23
ROM5:8502 JMP loc_14CB0
 
Subroutine task1_Scroll_state_3b
ROM5:8506 task1_Scroll_state_3b:
ROM5:8506 LDA byte_E9
ROM5:8507 CMP #$16
ROM5:8508 BCS loc_14515
ROM5:8509 CMP byte_ED
ROM5:850A BEQ ret
ROM5:850B STA byte_ED
ROM5:850C JMP sub_16924
 
ROM5:8515 loc_14515:
ROM5:8515 LDA byte_E8
ROM5:8516 BEQ ret
ROM5:8517 CMP #$21
ROM5:8518 BCS ret
ROM5:8519 JMP copy_background_column_to_ppu ; This copies a column of background tiles to the PPU.
  ; This is used for curtains opening and horizontal scrolling.
 
ROM5:851A ret:
ROM5:851A RTS
 
Subroutine ppu_work_after_sprite_0_hit
; This function is related to scrolling the screen during ; screen transitions. This waits for a sprite 0 hit and ; then has a bunch of hard delays, so it seems tightly ; synchronized with PPU rendering.
ROM5:8521 ppu_work_after_sprite_0_hit:
ROM5:8521 LDA PPUSTATUS
 
  ; Wait for a sprite 0 hit. During scrolling, when do_ppu_work_after_sprite0_next_frame
  ; is set, a sprite is placed overlapping the bomb sprite in the HUD, which will cause this
  ; to loop until the PPU has finished drawing the HUD.
 
ROM5:8522 AND #PPUStatusBits_Sprite0Hit
ROM5:8523 BEQ ppu_work_after_sprite_0_hit ; Wait for sprite0hit
ROM5:8524 LDA PPUSTATUS
ROM5:8525 LDY #3
 
ROM5:8526 loop1: ; This is a simple busy delay loop
ROM5:8526 LDX #$30
 
ROM5:8527 loop2:
ROM5:8527 DEX
ROM5:8528 BPL loop2
ROM5:8529 DEY
ROM5:852A BPL loop1
ROM5:852B NOP ; Delay some more
ROM5:852C NOP
ROM5:852D NOP
ROM5:852E NOP
ROM5:852F NOP
ROM5:8530 NOP
ROM5:8531 NOP
ROM5:8532 NOP
ROM5:8533 NOP
ROM5:8534 LDA game_mode
ROM5:8535 CMP #GameMode_GameOverMenu
ROM5:8536 BCS game_over_menu_mode_or_greater
ROM5:8537 LDA task_state
ROM5:8538 BEQ ret
ROM5:8539 LDA object_direction
ROM5:853A CMP #ControllerBits_Dpad_Down
ROM5:853B BCC horizontal ; Branch if right or left
ROM5:853C LDY #94
 
ROM5:853D loop3: ; Another delay loop
ROM5:853D NOP
ROM5:853E DEY
ROM5:853F BPL loop3
ROM5:8540 NOP
ROM5:8541 NOP
ROM5:8542 NOP
ROM5:8543 NOP
ROM5:8544 NOP
ROM5:8545 LDA PPUSTATUS
ROM5:8546 LDA byte_58
ROM5:8547 LDY byte_E2
ROM5:8548 STA PPUADDR ; Write PPU address high byte
ROM5:8549 STY PPUADDR ; Write PPU address low byte
ROM5:854A LDA PPUDATA
ROM5:854B LDA PPUDATA
ROM5:854C RTS
 
ROM5:854D horizontal:
ROM5:854D LDY #94
 
ROM5:854E loop4: ; Another delay loop
ROM5:854E NOP
ROM5:854F DEY
ROM5:8550 BPL loop4
ROM5:8551 NOP
ROM5:8552 NOP
ROM5:8553 NOP
ROM5:8554 LDA current_ppuctrl
ROM5:8555 AND #$FE ; Clear PPUCTRLBits_BaseNametable_2400
ROM5:8556 ORA byte_5F ; Mask into current_ppuctrl
ROM5:8557 STA current_ppuctrl
ROM5:8558 STA PPUCTRL
ROM5:8559 LDA desired_ppuscroll_x
ROM5:855A STA PPUSCROLL
ROM5:855B LDA #0
ROM5:855C STA PPUSCROLL
 
ROM5:855D ret:
ROM5:855D RTS
 
ROM5:855E game_over_menu_mode_or_greater:
ROM5:855E CMP #GameMode_JustDied
ROM5:855F BCS loc_14593
ROM5:8560 JMP clear_ppumask
 
ROM5:8593 loc_14593:
ROM5:8593 LDA current_ppuctrl
ROM5:8594 ORA #PPUCTRLBits_BaseNametable_2400
ROM5:8595 STA current_ppuctrl
ROM5:8596 STA PPUCTRL
ROM5:8597 RTS
 
ROM5:8598 Skipped empty chunk
Subroutine task0_GameOverMenu
ROM5:8600 task0_GameOverMenu:
ROM5:8600 JSR clear_ppumask
ROM5:8601 LDA task_state
ROM5:8602 BNE task0_GameOverMenu_0
ROM5:8603 STA is_in_cellar ; Set to 0.
ROM5:8604 JSR clear_nametables
ROM5:8605 JSR loc_1EA2B
ROM5:8606 JMP clear_screen_history_and_clear_force_beam_sword
 
ROM5:8607 task0_GameOverMenu_0:
ROM5:8607 LDA #PPUCommandIndices_GameOverMenu
ROM5:8608 STA current_ppu_command_index ; Set to PPUCommandIndices_GameOverMenu.
ROM5:8609 JMP start_task1 ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
 
Subroutine task0_EndCredits
ROM5:861A task0_EndCredits:
ROM5:861A JSR clear_nametables
ROM5:861B JSR check_sram
ROM5:861C BCS do_reset
ROM5:861D JMP start_task1 ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
 
ROM5:861E do_reset: ; This is the initial entry point. It also comes back
ROM5:861E JMP OnReset ; here to do a complete reset after the end credits finish.
 
  ; This only does basic bootstrapping. The main entry point
  ; for frame updates is OnNMI.
 
Subroutine task0_EnteringDoor
ROM5:8628 task0_EnteringDoor:
ROM5:8628 LDX #0
ROM5:8629 JSR set_tile_walking_onto_1 ; Set tile_walking_onto for the current object.
ROM5:862A CMP #$24
ROM5:862B BNE loc_14643 ; Set to 1
ROM5:862C LDA #0
ROM5:862D STA audio_misc_0619
ROM5:862E LDA #Sound2_EnteredDoor
ROM5:862F STA play_sound_2 ; Play Sound2_EnteredDoor
ROM5:8630 LDA object_y
ROM5:8631 CLC
ROM5:8632 ADC #$10
ROM5:8633 STA enemy_state_0
 
ROM5:8643 loc_14643: ; Set to 1
ROM5:8643 INC active_game_mode_task
ROM5:8644 RTS
 
ROM5:8646 spawn_position_ptr_low: .BYTE $4E ; Right
ROM5:8647   .BYTE $57 ; Left
ROM5:8648   .BYTE $60 ; Down
ROM5:8649   .BYTE $69 ; Up
ROM5:864A spawn_position_ptr_high: .BYTE $86 ; Right
ROM5:864B   .BYTE $86 ; Left
ROM5:864C   .BYTE $86 ; Down
ROM5:864D   .BYTE $86 ; Up
ROM5:864E spawn_positions_when_link_facing_right: .BYTE $55
ROM5:864F   .BYTE $B5
ROM5:8650   .BYTE $78
ROM5:8651   .BYTE $98
ROM5:8652   .BYTE $7A
ROM5:8653   .BYTE $9A
ROM5:8654   .BYTE $6C
ROM5:8655   .BYTE $AC
ROM5:8656   .BYTE $8D
ROM5:8657 spawn_positions_when_link_facing_left: .BYTE $82
ROM5:8658   .BYTE $63
ROM5:8659   .BYTE $A3
ROM5:865A   .BYTE $75
ROM5:865B   .BYTE $95
ROM5:865C   .BYTE $77
ROM5:865D   .BYTE $97
ROM5:865E   .BYTE $5A
ROM5:865F   .BYTE $BA
ROM5:8660 spawn_positions_when_link_facing_down: .BYTE $A3
ROM5:8661   .BYTE $75
ROM5:8662   .BYTE $B5
ROM5:8663   .BYTE $96
ROM5:8664   .BYTE $87
ROM5:8665   .BYTE $99
ROM5:8666   .BYTE $7A
ROM5:8667   .BYTE $BA
ROM5:8668   .BYTE $AC
ROM5:8669 spawn_positions_when_link_facing_up: .BYTE $63
ROM5:866A   .BYTE $55
ROM5:866B   .BYTE $95
ROM5:866C   .BYTE $76
ROM5:866D   .BYTE $88
ROM5:866E   .BYTE $79
ROM5:866F   .BYTE $5A
ROM5:8670   .BYTE $9A
ROM5:8671   .BYTE $6C
ROM5:8672 byte_14672: .BYTE $18
ROM5:8673   .BYTE $E8
ROM5:8674   .BYTE $28
ROM5:8675   .BYTE $D8
ROM5:8676 enemy_list_00: .BYTE ObjectType_BlueMoblin
ROM5:8677   .BYTE ObjectType_BlueMoblin
ROM5:8678   .BYTE ObjectType_RedMoblin
ROM5:8679   .BYTE ObjectType_BlueMoblin
ROM5:867A   .BYTE ObjectType_RedMoblin
ROM5:867B enemy_list_01: .BYTE ObjectType_BlueMoblin
ROM5:867C   .BYTE ObjectType_RedMoblin
ROM5:867D   .BYTE ObjectType_BlueMoblin
ROM5:867E   .BYTE ObjectType_RedMoblin
ROM5:867F enemy_list_02: .BYTE ObjectType_Peahat
ROM5:8680   .BYTE ObjectType_Peahat
ROM5:8681   .BYTE ObjectType_RedLynel
ROM5:8682   .BYTE ObjectType_BlueLynel
ROM5:8683   .BYTE ObjectType_RedLynel
ROM5:8684   .BYTE ObjectType_BlueLynel
ROM5:8685 enemy_list_03: .BYTE ObjectType_BlueLynel
ROM5:8686   .BYTE ObjectType_RedLynel
ROM5:8687   .BYTE ObjectType_BlueLynel
ROM5:8688   .BYTE ObjectType_RedLynel
ROM5:8689 enemy_list_04: .BYTE ObjectType_BlueLynel
ROM5:868A   .BYTE ObjectType_BlueLeever
ROM5:868B   .BYTE ObjectType_RedLynel
ROM5:868C   .BYTE ObjectType_BlueLynel
ROM5:868D   .BYTE ObjectType_RedLeever
ROM5:868E   .BYTE ObjectType_RedLynel
ROM5:868F enemy_list_05: .BYTE ObjectType_BlueLeever
ROM5:8690   .BYTE ObjectType_Peahat
ROM5:8691   .BYTE ObjectType_RedLeever
ROM5:8692   .BYTE ObjectType_Peahat
ROM5:8693   .BYTE ObjectType_BlueLeever
ROM5:8694   .BYTE ObjectType_Peahat
ROM5:8695 enemy_list_06: .BYTE ObjectType_BlueOctorok
ROM5:8696   .BYTE ObjectType_RedOctorokFast
ROM5:8697   .BYTE ObjectType_RedOctorokFast
ROM5:8698   .BYTE ObjectType_RedOctorokFast
ROM5:8699   .BYTE ObjectType_RedOctorokFast
ROM5:869A enemy_list_07: .BYTE ObjectType_RedOctorokFast
ROM5:869B   .BYTE ObjectType_RedOctorok
ROM5:869C   .BYTE ObjectType_RedOctorokFast
ROM5:869D   .BYTE ObjectType_RedOctorok
ROM5:869E enemy_list_08: .BYTE ObjectType_RedOctorokFast
ROM5:869F   .BYTE ObjectType_BlueOctorok
ROM5:86A0   .BYTE ObjectType_RedOctorokFast
ROM5:86A1   .BYTE ObjectType_BlueOctorok
ROM5:86A2   .BYTE ObjectType_RedOctorokFast
ROM5:86A3 enemy_list_09: .BYTE ObjectType_BlueOctorokFast
ROM5:86A4   .BYTE ObjectType_RedOctorok
ROM5:86A5   .BYTE ObjectType_BlueOctorokFast
ROM5:86A6   .BYTE ObjectType_RedOctorok
ROM5:86A7   .BYTE ObjectType_RedOctorok
ROM5:86A8 enemy_list_10: .BYTE ObjectType_BlueMoblin
ROM5:86A9   .BYTE ObjectType_BlueOctorokFast
ROM5:86AA   .BYTE ObjectType_RedMoblin
ROM5:86AB   .BYTE ObjectType_BlueOctorokFast
ROM5:86AC   .BYTE ObjectType_RedMoblin
ROM5:86AD   .BYTE ObjectType_RedMoblin
ROM5:86AE enemy_list_11: .BYTE ObjectType_WallTrap_Horiz
ROM5:86AF   .BYTE ObjectType_None ; Empty slots for spawned wall traps
ROM5:86B0   .BYTE ObjectType_None
ROM5:86B1   .BYTE ObjectType_None
ROM5:86B2   .BYTE ObjectType_Zol
ROM5:86B3   .BYTE ObjectType_Zol
ROM5:86B4   .BYTE ObjectType_None
ROM5:86B5   .BYTE ObjectType_Zol
ROM5:86B6 enemy_list_12: .BYTE ObjectType_WallTrap_Horiz
ROM5:86B7   .BYTE ObjectType_None ; Empty slots for spawned wall traps
ROM5:86B8   .BYTE ObjectType_None
ROM5:86B9   .BYTE ObjectType_None
ROM5:86BA   .BYTE ObjectType_BlueKeese
ROM5:86BB   .BYTE ObjectType_BlueKeese
ROM5:86BC   .BYTE ObjectType_BlueKeese
ROM5:86BD   .BYTE ObjectType_BlueKeese
ROM5:86BE enemy_list_13: .BYTE ObjectType_Bubble
ROM5:86BF   .BYTE ObjectType_Bubble
ROM5:86C0   .BYTE ObjectType_Bubble
ROM5:86C1   .BYTE ObjectType_Zol
ROM5:86C2   .BYTE ObjectType_Zol
ROM5:86C3   .BYTE ObjectType_BlueKeese
ROM5:86C4   .BYTE ObjectType_BlueKeese
ROM5:86C5   .BYTE ObjectType_BlueKeese
ROM5:86C6 enemy_list_14: .BYTE ObjectType_PolsVoice
ROM5:86C7   .BYTE ObjectType_Gibdo
ROM5:86C8   .BYTE ObjectType_Gibdo
ROM5:86C9   .BYTE ObjectType_BlueKeese
ROM5:86CA   .BYTE ObjectType_BlueKeese
ROM5:86CB   .BYTE ObjectType_PolsVoice
ROM5:86CC   .BYTE ObjectType_None
ROM5:86CD   .BYTE ObjectType_None
ROM5:86CE enemy_list_15: .BYTE ObjectType_Bubble
ROM5:86CF   .BYTE ObjectType_Bubble
ROM5:86D0   .BYTE ObjectType_Bubble
ROM5:86D1   .BYTE ObjectType_BlueWizzrobe
ROM5:86D2   .BYTE ObjectType_BlueWizzrobe
ROM5:86D3   .BYTE ObjectType_RedWizzrobe
ROM5:86D4   .BYTE ObjectType_BlueWizzrobe
ROM5:86D5   .BYTE ObjectType_RedWizzrobe
ROM5:86D6 enemy_list_16: .BYTE ObjectType_Bubble
ROM5:86D7   .BYTE ObjectType_Bubble
ROM5:86D8   .BYTE ObjectType_Vire
ROM5:86D9   .BYTE ObjectType_Vire
ROM5:86DA   .BYTE ObjectType_Vire
ROM5:86DB   .BYTE ObjectType_None
ROM5:86DC   .BYTE ObjectType_None
ROM5:86DD   .BYTE ObjectType_None
ROM5:86DE enemy_list_17: .BYTE ObjectType_Bubble
ROM5:86DF   .BYTE ObjectType_Bubble
ROM5:86E0   .BYTE ObjectType_Zol
ROM5:86E1   .BYTE ObjectType_Zol
ROM5:86E2   .BYTE ObjectType_LikeLike
ROM5:86E3   .BYTE ObjectType_LikeLike
ROM5:86E4 enemy_list_18: .BYTE ObjectType_Bubble
ROM5:86E5   .BYTE ObjectType_Bubble
ROM5:86E6   .BYTE ObjectType_BlueDarknut
ROM5:86E7   .BYTE ObjectType_RedDarknut
ROM5:86E8   .BYTE ObjectType_RedDarknut
ROM5:86E9   .BYTE ObjectType_Gibdo
ROM5:86EA   .BYTE ObjectType_Gibdo
ROM5:86EB   .BYTE ObjectType_Gibdo
ROM5:86EC enemy_list_19: .BYTE ObjectType_Bubble
ROM5:86ED   .BYTE ObjectType_Bubble
ROM5:86EE   .BYTE ObjectType_BlueGoriya
ROM5:86EF   .BYTE ObjectType_BlueGoriya
ROM5:86F0   .BYTE ObjectType_BlueGoriya
ROM5:86F1   .BYTE ObjectType_BlueKeese
ROM5:86F2   .BYTE ObjectType_BlueKeese
ROM5:86F3   .BYTE ObjectType_BlueKeese
ROM5:86F4 enemy_list_20: .BYTE ObjectType_WallTrap_Horiz
ROM5:86F5   .BYTE ObjectType_None ; Empty slots for spawned wall traps
ROM5:86F6   .BYTE ObjectType_None
ROM5:86F7   .BYTE ObjectType_None
ROM5:86F8   .BYTE ObjectType_LikeLike
ROM5:86F9   .BYTE ObjectType_LikeLike
ROM5:86FA   .BYTE ObjectType_LikeLike
ROM5:86FB   .BYTE ObjectType_LikeLike
ROM5:86FC enemy_list_21: .BYTE ObjectType_WallTrap_Horiz
ROM5:86FD   .BYTE ObjectType_None ; Empty slots for spawned wall traps
ROM5:86FE   .BYTE ObjectType_None
ROM5:86FF   .BYTE ObjectType_None
ROM5:8700   .BYTE ObjectType_BlueWizzrobe
ROM5:8701   .BYTE ObjectType_RedWizzrobe
ROM5:8702   .BYTE ObjectType_BlueWizzrobe
ROM5:8703   .BYTE ObjectType_RedWizzrobe
ROM5:8704 enemy_list_22: .BYTE ObjectType_PolsVoice
ROM5:8705   .BYTE ObjectType_BlueDarknut
ROM5:8706   .BYTE ObjectType_RedDarknut
ROM5:8707   .BYTE ObjectType_BlueDarknut
ROM5:8708   .BYTE ObjectType_RedDarknut
ROM5:8709   .BYTE ObjectType_PolsVoice
ROM5:870A enemy_list_23: .BYTE ObjectType_Bubble
ROM5:870B   .BYTE ObjectType_Bubble
ROM5:870C   .BYTE ObjectType_Bubble
ROM5:870D   .BYTE ObjectType_WallMaster
ROM5:870E   .BYTE ObjectType_WallMaster
ROM5:870F   .BYTE ObjectType_WallMaster
ROM5:8710   .BYTE ObjectType_WallMaster
ROM5:8711   .BYTE ObjectType_WallMaster
ROM5:8712 enemy_list_24: .BYTE ObjectType_BlueGoriya
ROM5:8713   .BYTE ObjectType_RedGoriya
ROM5:8714   .BYTE ObjectType_RedGoriya
ROM5:8715   .BYTE ObjectType_BlueGoriya
ROM5:8716   .BYTE ObjectType_RedGoriya
ROM5:8717   .BYTE ObjectType_BlueGoriya
ROM5:8718   .BYTE ObjectType_None
ROM5:8719   .BYTE ObjectType_None
ROM5:871A enemy_list_25: .BYTE ObjectType_BlueWizzrobe
ROM5:871B   .BYTE ObjectType_BlueWizzrobe
ROM5:871C   .BYTE ObjectType_RedWizzrobe
ROM5:871D   .BYTE ObjectType_BlueWizzrobe
ROM5:871E   .BYTE ObjectType_RedWizzrobe
ROM5:871F enemy_list_26: .BYTE ObjectType_Bubble
ROM5:8720   .BYTE ObjectType_LikeLike
ROM5:8721   .BYTE ObjectType_BlueWizzrobe
ROM5:8722   .BYTE ObjectType_BlueWizzrobe
ROM5:8723   .BYTE ObjectType_LikeLike
ROM5:8724   .BYTE ObjectType_RedWizzrobe
ROM5:8725   .BYTE ObjectType_LikeLike
ROM5:8726   .BYTE ObjectType_RedWizzrobe
ROM5:8727 enemy_list_27: .BYTE ObjectType_RedBubble
ROM5:8728   .BYTE ObjectType_RedBubble
ROM5:8729   .BYTE ObjectType_RedBubble
ROM5:872A   .BYTE ObjectType_BlueBubble
ROM5:872B   .BYTE ObjectType_BlueWizzrobe
ROM5:872C   .BYTE ObjectType_RedWizzrobe
ROM5:872D   .BYTE ObjectType_BlueWizzrobe
ROM5:872E   .BYTE ObjectType_RedWizzrobe
ROM5:872F enemy_list_28: .BYTE ObjectType_RedBubble
ROM5:8730   .BYTE ObjectType_RedBubble
ROM5:8731   .BYTE ObjectType_RedBubble
ROM5:8732   .BYTE ObjectType_BlueBubble
ROM5:8733   .BYTE ObjectType_BlueDarknut
ROM5:8734   .BYTE ObjectType_RedDarknut
ROM5:8735   .BYTE ObjectType_BlueDarknut
ROM5:8736   .BYTE ObjectType_RedDarknut
ROM5:8737 enemy_list_29: .BYTE ObjectType_RedBubble
ROM5:8738   .BYTE ObjectType_RedBubble
ROM5:8739   .BYTE ObjectType_RedBubble
ROM5:873A   .BYTE ObjectType_BlueBubble
ROM5:873B   .BYTE ObjectType_WallMaster
ROM5:873C   .BYTE ObjectType_WallMaster
ROM5:873D   .BYTE ObjectType_WallMaster
ROM5:873E   .BYTE ObjectType_WallMaster
ROM5:873F enemy_list_pointers: .WORD enemy_list_00
ROM5:8741   .WORD enemy_list_01
ROM5:8743   .WORD enemy_list_02
ROM5:8745   .WORD enemy_list_03
ROM5:8747   .WORD enemy_list_04
ROM5:8749   .WORD enemy_list_05
ROM5:874B   .WORD enemy_list_06
ROM5:874D   .WORD enemy_list_07
ROM5:874F   .WORD enemy_list_08
ROM5:8751   .WORD enemy_list_09
ROM5:8753   .WORD enemy_list_10
ROM5:8755   .WORD enemy_list_11
ROM5:8757   .WORD enemy_list_12
ROM5:8759   .WORD enemy_list_13
ROM5:875B   .WORD enemy_list_14
ROM5:875D   .WORD enemy_list_15
ROM5:875F   .WORD enemy_list_16
ROM5:8761   .WORD enemy_list_17
ROM5:8763   .WORD enemy_list_18
ROM5:8765   .WORD enemy_list_19
ROM5:8767   .WORD enemy_list_20
ROM5:8769   .WORD enemy_list_21
ROM5:876B   .WORD enemy_list_22
ROM5:876D   .WORD enemy_list_23
ROM5:876F   .WORD enemy_list_24
ROM5:8771   .WORD enemy_list_25
ROM5:8773   .WORD enemy_list_26
ROM5:8775   .WORD enemy_list_27
ROM5:8777   .WORD enemy_list_28
ROM5:8779   .WORD enemy_list_29
 
Subroutine task0_FinishingScroll
; Objects are created in here (probably other stuff happens)
ROM5:877B task0_FinishingScroll:
ROM5:877B LDX task_state
ROM5:877C BEQ task0_FinishingTransition_state_0 ; Branch if zero
ROM5:877D DEX ; Decrement next_work_values_idx
ROM5:877E BNE state_2 ; Branch if > 0 (originally >= 2)
ROM5:877F LDA byte_E9
ROM5:8780 BMI loc_1478B
ROM5:8781 JSR sub_16C16
ROM5:8782 BCC ret
 
ROM5:878B loc_1478B: ; Set to 1 to run state_2 next time
ROM5:878B INC task_state
 
ROM5:878C ret:
ROM5:878C RTS
 
ROM5:878D state_2:
ROM5:878D DEX
ROM5:878E BNE state_3
ROM5:878F LDY map_location
ROM5:8790 JSR check_if_dark
ROM5:8791 BNE loc_147BE
ROM5:8792 LDA object_direction
ROM5:8793 JSR sub_17560
ROM5:8794 SEC
ROM5:8795 SBC map_location
ROM5:8796 JSR inverse
ROM5:8797 CLC
ROM5:8798 ADC map_location
ROM5:8799 TAY
ROM5:879A JSR check_if_dark
ROM5:879B BEQ loc_147BE ; Branch if not dark
ROM5:879C LDA lighting_room_state
ROM5:879D BNE loc_147BE
ROM5:879E LDA #$C0
 
ROM5:87B3 set_next_palette_cycle_and_advance_task_state:
ROM5:87B3 STA next_palette_cycle
ROM5:87B4 INC task_state
 
ROM5:87B8 locret_147B8:
ROM5:87B8 RTS
 
ROM5:87B9 state_3:
ROM5:87B9 JSR update_timed_palette_cycle
ROM5:87BA BNE locret_147B8
 
ROM5:87BE loc_147BE:
ROM5:87BE LDA #0
ROM5:87BF STA task_state ; Set to 0
ROM5:87C0 STA lighting_room_state ; Set to 0
ROM5:87C1 RTS
 
Subroutine task0_FinishingTransition_state_0
; This is called as the task0, state 0 task for each ; game mode that transitions screens.
ROM5:87C6 task0_FinishingTransition_state_0:
ROM5:87C6 JSR update_minimap_and_link_sprite
ROM5:87C7 JSR deactivate_clock_and_walk_state
ROM5:87C8 LDA #5 ; Set the end of RAM that should be cleared by reset_room_state.
  ; This is set to a higher value for init_memory's call to
  ; clear more.
ROM5:87C9 LDY #$1F
ROM5:87CA JSR reset_room_state ; Clear out room-specific data as we enter a new room.
ROM5:87CB LDA #0
ROM5:87CC STA byte_54 ; Set to 0
ROM5:87CD STA bombing_or_unlocking_door_direction ; Set to 0
ROM5:87CE LDY map_location
ROM5:87CF LDA dungeon_screen_data_5,Y
ROM5:87D0 STA current_screen_data_5 ; Set to dungeon_screen_data_5[room]
ROM5:87D1 JSR clear_ladder_and_player_projectiles
ROM5:87D2 LDA is_in_cellar ; Branch if we're entering this screen not coming out of a cellar.
ROM5:87D3 BEQ not_in_cellar
ROM5:87D4 LDA dungeon_idx
ROM5:87D5 BNE in_dungeon ; Branch if we're in a dungeon.
ROM5:87D6 LDY map_location ; We're exiting a cellar on the overworld. Load the
  ; position to place Link after exiting a cellar.
ROM5:87D7 LDA dungeon_screen_data_0,Y ; Overworld table 0
ROM5:87D8 AND #ScreenData_Overworld_0_CaveExitX
ROM5:87D9 STA object_x ; Store the X position we exit the cave at
ROM5:87DA LDA dungeon_screen_data_5,Y
ROM5:87DB AND #ScreenData_Overworld_5_CaveExitY
ROM5:87DC ASL A ; Y position <<= 4
ROM5:87DD ASL A
ROM5:87DE ASL A
ROM5:87DF ASL A
ROM5:87E0 ADC #77 ; Move down by 77 (probably the size of the HUD)
ROM5:87E1 STA object_y ; Store the Y position we exit the cave at
ROM5:87E2 LDY link_most_recent_overworld_tile_type ; Check if we're exiting a cave/dungeon that we entered
  ; via a OverworldTiles_CaveOrDungeonEntrance tile.
ROM5:87E3 CPY #OverworldTiles_CaveOrDungeonEntrance
ROM5:87E4 BNE in_dungeon
ROM5:87E5 STA enemy_state_0 ; Store the target Y position for the animation of walking
  ; up out of the door. This is used by task1_CurtainsOpening.
ROM5:87E6 CLC
ROM5:87E7 ADC #16 ; Move Link down by one full tile for walking up out of the
  ; door after walking out.
ROM5:87E8 STA object_y
ROM5:87E9 LDA #Sound2_EnteredDoor
ROM5:87EA STA play_sound_2 ; Play Sound2_EnteredDoor
 
ROM5:87EB in_dungeon:
ROM5:87EB LDA #ControllerBits_Dpad_Down
ROM5:87EC STA object_direction ; Face Link downwards after exiting a cave.
ROM5:87ED LDA #0
ROM5:87EE STA in_dungeon_door ; Set to 0
ROM5:87EF JMP loc_14859
 
ROM5:87F0 not_in_cellar:
ROM5:87F0 LDA object_direction
ROM5:87F1 STA in_dungeon_door ; Set to object_direction
ROM5:87F2 JSR get_opposite_direction_and_index ; Set bombing_or_unlocking_door_direction = (opposite direction & unlocked_door_directions).
ROM5:87F3 AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:87F4 STA bombing_or_unlocking_door_direction
ROM5:87F5 BEQ skip_if_not_opening_door ; Branch if the resulting mask was 0.
ROM5:87F6 LDA #2
ROM5:87F7 STA byte_54 ; Set to 2
 
ROM5:87F8 skip_if_not_opening_door:
ROM5:87F8 LDA dungeon_idx
ROM5:87F9 BEQ loc_14859
ROM5:87FA LDY #0
ROM5:87FB LDA object_direction
ROM5:87FC AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM5:87FD BEQ loc_14845
ROM5:87FE AND #ControllerBits_Dpad_Right
ROM5:87FF BNE loc_14843
ROM5:8800 LDY #$F0
 
ROM5:8843 loc_14843:
ROM5:8843 STY object_x
 
ROM5:8845 loc_14845:
ROM5:8845 JSR sub_170C3
ROM5:8846 AND #7
ROM5:8847 BEQ loc_14856
ROM5:8848 CMP #DungeonDoor_LockedDoor
ROM5:8849 BEQ loc_14856
ROM5:884A CMP #DungeonDoor_LockedDoor2
ROM5:884B BEQ loc_14856
ROM5:884C INY
ROM5:884D INY
 
ROM5:8856 loc_14856:
ROM5:8856 LDA byte_14672,Y
 
ROM5:8859 loc_14859:
ROM5:8859 STA object_tile_offset_whole
ROM5:885A JSR setup_screen_bounds
ROM5:885B LDX #$B
ROM5:885C STX processing_object_index ; Set to 0xB
 
ROM5:8864 loc_14864:
ROM5:8864 DEC object_slot_in_use,X
ROM5:8865 JSR clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
ROM5:8866 STA walk_state_and_weapon_state,X
ROM5:8867 STA object_direction,X
ROM5:8868 STA enemy_stun,X
ROM5:8869 INC object_animation_frame_timer,X
ROM5:886A INC enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM5:886B LDA #$20
ROM5:886C STA object_walk_speed,X
ROM5:886D DEX
ROM5:886E BNE loc_14864
ROM5:886F LDY map_location
ROM5:8870 LDA dungeon_screen_data_2,Y ; Load the enemy count and code
ROM5:8871 PHA
ROM5:8872 AND #ScreenData_Overworld_2_EnemyCode
ROM5:8873 STA var_2
ROM5:8874 LDA dungeon_screen_data_3,Y ; Load to read "mixed type" flag
ROM5:8875 ASL A
ROM5:8876 BCC not_mixed ; Branch if the 0x80 mixed enemy type flag is clear
ROM5:8877 LDA var_2 ; Restore the enemy code
ROM5:8878 CLC
ROM5:8879 ADC #$40 ; Add 0x40 to the enemy code for mixed type enemies
ROM5:887A STA var_2 ; Save the modified enemy code
 
ROM5:887B not_mixed: ; Restore the enemy count and code
ROM5:887B PLA
ROM5:887C AND #ScreenData_Overworld_2_CountCode
ROM5:887D CLC
ROM5:887E ROL A ; Rotate the count code from 0b11000000 to 0b00000110
ROM5:887F ROL A ; Doesn't this just get overwritten below?
ROM5:8880 ROL A
ROM5:8881 TAY
ROM5:8882 LDA ppu_data_for_current_dungeon.enemy_count,Y
ROM5:8883 LDY var_2 ; Load the enemy code
ROM5:8884 CPY #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM5:8885 BCS loc_148AC ; Store the number of enemies to spawn
ROM5:8886 CPY #ObjectType_DodongoBoss
ROM5:8887 BCC loc_148AC ; Store the number of enemies to spawn
ROM5:8888 LDA #1 ; Only load one of ObjectType_DodongoBoss <= code < ObjectType_Unknown_62
 
ROM5:88AC loc_148AC: ; Store the number of enemies to spawn
ROM5:88AC STA var_3
ROM5:88AD LDA dungeon_idx
ROM5:88AE BNE in_dungeon3 ; Branch if not overworld
ROM5:88AF JSR check_overworld_map_history
ROM5:88B0 JMP not_game_mode_9 ; Load the number of enemies to spawn
 
ROM5:88B1 in_dungeon3: ; This is only called in dungeons.
ROM5:88B1 JSR sub_1529D
ROM5:88B2 LDA game_mode
ROM5:88B3 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM5:88B4 BNE not_game_mode_9 ; Load the number of enemies to spawn
ROM5:88B5 LDA #0 ; don't spawn anything in game mode 9
ROM5:88B6 STA var_2
ROM5:88B7 STA var_3
 
ROM5:88C7 not_game_mode_9: ; Load the number of enemies to spawn
ROM5:88C7 LDA var_3
ROM5:88C8 STA total_enemies_spawned_in_room ; Store the number of enemies to spawn
ROM5:88C9 BEQ loc_14909 ; Branch if no enemies
ROM5:88CA LDA var_2
ROM5:88CB BEQ loc_14909 ; Branch if no enemies
ROM5:88CC CMP #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM5:88CD BCS is_mixed_enemies ; Branch if >= ObjectType_PowerBracelet_Secret_1
ROM5:88CE LDX #0 ; If object type < ObjectType_PowerBracelet_Secret_1, spawn var_3 of that enemy.
 
ROM5:88CF loop: ; Spawn var_3 of object var_2.
ROM5:88CF LDA var_2
ROM5:88D0 STA object_type_1,X
ROM5:88D1 INX
ROM5:88D2 DEC var_3
ROM5:88D3 BNE loop
ROM5:88D4 JMP store_first_object_type
 
ROM5:88D5 is_mixed_enemies: ; For object type >= ObjectType_PowerBracelet_Secret_1, subtract
ROM5:88D5 LDA var_2 ; ObjectType_PowerBracelet_Secret_1 to get the enemy list index.
  ; This isn't related to the ObjectType_PowerBracelet_Secret_1
  ; object type, it's just the index where we start using a fixed
  ; list of enemies instead of a single enemy type and a count.
ROM5:88D6 SEC
ROM5:88D7 SBC #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM5:88D8 ASL A
ROM5:88D9 TAY
ROM5:88DA LDA enemy_list_pointers,Y
ROM5:88DB STA var_4
ROM5:88DC INY
ROM5:88DD LDA enemy_list_pointers,Y
ROM5:88DE STA var_5
ROM5:88DF LDY #0
 
ROM5:88E0 set_next_enemy:
ROM5:88E0 LDA (var_4),Y
ROM5:88E1 STA object_type_1,Y
ROM5:88E2 INY
ROM5:88E3 CPY var_3
ROM5:88E4 BNE set_next_enemy
 
ROM5:88E5 store_first_object_type:
ROM5:88E5 LDA object_type_1
ROM5:88E6 STA first_object_type ; The first object type on the screen at screen load time. This is only set in dungeons.
 
ROM5:8909 loc_14909: ; This sets up enemy positions, handles spawning Keese in
ROM5:8909 JSR task0_FinishingTransition_setup_room ; cellars, and handles spawning overworld cave event objects.
ROM5:890A LDA dungeon_idx
ROM5:890B BNE in_dungeon2
ROM5:890C JSR task0_FinishingTransition_setup_room_overworld
 
ROM5:890D in_dungeon2:
ROM5:890D JSR setup_minimap_triforce_position_unless_in_cellar_or_whirlwind
ROM5:890E LDA #0
ROM5:890F STA enemy_stun ; Set to 0.
ROM5:8910 STA object_knockback ; Set to 0.
ROM5:8911 STA knockback_frames ; Set to 0.
ROM5:8912 LDA #4
ROM5:8913 STA object_animation_frame_timer ; Set to 4.
ROM5:8914 JSR update_link_walking_speed
ROM5:8915 JSR task0_Normal_2
 
Subroutine update_link_sprite_and_other_stuff
; This calls update_link_sprite_and_check_ladder_if_overworld (if not in GameMode_InOverworldCellar ; or GameMode_ExitingOverworldCellar), and does some other things that I haven't traced. They seem ; to be sprite update-related.
ROM5:8929 update_link_sprite_and_other_stuff:
ROM5:8929 JSR reset_sprite_index_to_zero ; Set next_sprite_index to 0.
ROM5:892A LDA game_mode
ROM5:892B CMP #GameMode_InOverworldCellar ; We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal.
  ; The map location doesn't change.
ROM5:892C BEQ in_cellar
ROM5:892D CMP #GameMode_ExitingOverworldCellar
ROM5:892E BEQ in_cellar
ROM5:892F JSR update_link_sprite_and_check_ladder_if_overworld ; Like update_link_sprite_and_check_ladder, but do nothing if
  ; we're in a dungeon.
 
ROM5:8930 in_cellar:
ROM5:8930 LDA is_in_cellar
ROM5:8931 BEQ ret
ROM5:8932 JSR set_0x20_in_oam_data
 
ROM5:8933 ret:
ROM5:8933 RTS
 
Subroutine task0_FinishingTransition_setup_room_overworld
ROM5:8941 task0_FinishingTransition_setup_room_overworld:
ROM5:8941 LDA map_location
 
ROM5:8943 raft_location_1: ; Raft location 1
ROM5:8943 CMP #$3F
ROM5:8944 BEQ is_raft_location
 
ROM5:8947 raft_location_2: ; Raft location 2
ROM5:8947 CMP #$55
ROM5:8948 BNE not_raft_location
 
ROM5:8949 is_raft_location: ; An overworld raft spot.
ROM5:8949 LDA #ObjectType_OverworldSecret_Raft
ROM5:894A JMP loc_1495D
 
ROM5:894B not_raft_location:
ROM5:894B LDA overworld_room_object_x
ROM5:894C STA object_x_11
ROM5:894D LDA overworld_room_object_y
ROM5:894E STA object_y_11
ROM5:894F LDA overworld_room_object_type
 
ROM5:895D loc_1495D: ; Store the room's object type
ROM5:895D STA object_type_B
ROM5:895E JSR clear_overworld_room_object_info
ROM5:895F STA byte_B7 ; Set to 0
ROM5:8960 RTS
 
ROM5:8966 cellar_keese_x_positions: .BYTE $20
ROM5:8967   .BYTE $60
ROM5:8968   .BYTE $90
ROM5:8969   .BYTE $D0
ROM5:896A cellar_keese_y_positions: .BYTE $9D
ROM5:896B   .BYTE $5D
ROM5:896C   .BYTE $7D
ROM5:896D   .BYTE $9D
 
Subroutine task0_FinishingTransition_setup_room
; This sets up enemy positions, handles spawning Keese in ; cellars, and handles spawning overworld cave event objects.
ROM5:896E task0_FinishingTransition_setup_room:
ROM5:896E LDY total_enemies_spawned_in_room
ROM5:896F LDA var_2
ROM5:8970 BEQ skip_enemy_positioning_setup
ROM5:8971 CMP #ObjectType_Zelda
ROM5:8972 BEQ skip_enemy_positioning_setup
ROM5:8973 LDA dungeon_idx ; Skip testing the enter from side flag when in dungeons
  ; (overworld flag only).
ROM5:8974 BNE in_dungeon
ROM5:8975 LDA current_screen_data_5 ; Skip assigning enemy locations if enemies enter from the side.
ROM5:8976 AND #ScreenData_Overworld_5_MonstersEnterFromSide
ROM5:8977 BNE skip_enemy_positioning_setup
 
ROM5:8978 in_dungeon: ; Skip if no enemies were spawned in this room.
ROM5:8978 LDA total_enemies_spawned_in_room
ROM5:8979 BEQ skip_enemy_positioning_setup
ROM5:897A LDA object_direction ; Get an index for the direction Link is facing: 0: right, 1: left, 2: down, 3: up
ROM5:897B LDY #$FF
 
ROM5:897C direction_loop:
ROM5:897C INY
ROM5:897D LSR A
ROM5:897E BCC direction_loop
ROM5:897F LDA spawn_position_ptr_low,Y ; This points to 0x864E, 0x8657, 0x8660 and 0x8669
ROM5:8980 STA var_6
ROM5:8981 LDA spawn_position_ptr_high,Y
ROM5:8982 STA var_7
ROM5:8983 LDY spawn_position_counter ; Get the spawn position counter. We'll start reading positions
  ; from the spawn position list at this index.
ROM5:8984 LDX #1
 
ROM5:8985 set_enemy_positions: ; Read the next spawn position.
ROM5:8985 LDA (var_6),Y
ROM5:8986 PHA ; Save the position.
ROM5:8987 ASL A ; Shift 0x0F to 0xF0 to get the X spawn position.
ROM5:8988 ASL A
ROM5:8989 ASL A
ROM5:898A ASL A
ROM5:898B STA object_x,X
ROM5:898C PLA ; Restore the position.
ROM5:898D AND #$F0 ; Mask out 0xF0 to get the Y spawn position.
ROM5:898E ORA #$D
ROM5:898F STA object_y,X
ROM5:8990 JSR check_if_spawn_is_near_link_or_in_solid_object ; Check if we're spawning the enemy too close to Link or
  ; inside a solid object.
ROM5:8991 BCS enemy_in_invalid_spawn_position ; If we are, skip advancing X so we'll try a different
  ; position for this enemy.
ROM5:8992 INX ; Advance to save this enemy's spawn position.
 
ROM5:8993 enemy_in_invalid_spawn_position:
ROM5:8993 INY
ROM5:8994 CPY #9 ; Advance to the next spawn position.
ROM5:8995 BCC no_wrap
ROM5:8996 LDY #0 ; Wrap the spawn position index back to 0.
 
ROM5:8997 no_wrap:
ROM5:8997 CPX #$A
ROM5:8998 BCC set_enemy_positions
ROM5:8999 STY spawn_position_counter ; Save the next spawn position to use, so we don't
  ; always spawn enemies in the same places.
 
ROM5:899A skip_enemy_positioning_setup:
ROM5:899A LDA game_mode
ROM5:899B CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM5:899C BNE not_in_cellar
ROM5:899D LDX #3 ; Spawn 4 Keese in cellars.
 
ROM5:899E keese_spawn_loop:
ROM5:899E LDA #ObjectType_BlueKeese
ROM5:899F STA object_type_1,X
ROM5:89A0 LDA cellar_keese_x_positions,X
ROM5:89A1 STA object_x_1,X
ROM5:89A2 LDA cellar_keese_y_positions,Y
ROM5:89A3 STA object_y_1,X
ROM5:89A4 DEX
ROM5:89A5 BPL keese_spawn_loop
ROM5:89A6 RTS
 
ROM5:89A7 not_in_cellar: ; We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal.
ROM5:89A7 CMP #GameMode_InOverworldCellar ; The map location doesn't change.
ROM5:89A8 BEQ finished_stairs_or_exiting_cave
ROM5:89A9 CMP #GameMode_ExitingOverworldCellar
ROM5:89AA BNE ret
 
ROM5:89AB finished_stairs_or_exiting_cave:
ROM5:89AB LDX #7
ROM5:89AC LDA #0
 
ROM5:89AD clear_objects_loop: ; Clear objects
ROM5:89AD STA object_type_1,X
ROM5:89AE DEX
ROM5:89AF BPL clear_objects_loop
ROM5:89B0 LDY map_location
ROM5:89B1 LDA dungeon_screen_data_1,Y ; We're entering an overworld cave. Load the event type.
ROM5:89B2 AND #$FC ; Mask out 0b11111100, which is the overworld cave contents
ROM5:89B3 SEC
ROM5:89B4 SBC #$40 ; Convert to object type, eg. ObjectType_OldMan
ROM5:89B5 LSR A
ROM5:89B6 LSR A
ROM5:89B7 CLC
ROM5:89B8 ADC #ObjectType_OldMan_WoodSword
ROM5:89B9 STA object_type_1
 
ROM5:89BA ret:
ROM5:89BA RTS
 
Subroutine check_if_spawn_is_near_link_or_in_solid_object
; Check if the current enemy is close to Link, or inside ; a solid object. Set carry if in an invalid position, ; or clear carry otherwise.
ROM5:8A04 check_if_spawn_is_near_link_or_in_solid_object:
ROM5:8A04 TYA
ROM5:8A05 PHA
ROM5:8A06 JSR set_tile_walking_onto_1 ; Set tile_walking_onto for the current object.
ROM5:8A07 PLA
ROM5:8A08 TAY
ROM5:8A09 LDA tile_walking_onto,X
ROM5:8A0A CMP screen_first_solid_tile_id
ROM5:8A0B BCS near_link
 
ROM5:8A13 check_if_spawn_is_near_link: ; Check if the current enemy is close to Link. Set carry if close, clear carry otherwise.
ROM5:8A13 LDA object_x
ROM5:8A14 SEC
ROM5:8A15 SBC object_x,X
ROM5:8A16 JSR absolute_value ; A = abs(A)
ROM5:8A17 CMP #34
ROM5:8A18 BCS not_near_link
ROM5:8A19 LDA object_y
ROM5:8A1A SEC
ROM5:8A1B SBC object_y,X
ROM5:8A1C JSR absolute_value ; A = abs(A)
ROM5:8A1D CMP #34
ROM5:8A1E BCC near_link
 
ROM5:8A1F not_near_link:
ROM5:8A1F CLC
ROM5:8A20 RTS
 
ROM5:8A21 near_link:
ROM5:8A21 SEC
ROM5:8A22 RTS
 
Subroutine task0_JustDied
ROM5:8A2F task0_JustDied:
ROM5:8A2F LDX #0
ROM5:8A30 JSR decrease_invincibility_frames ; Reduce the i-frames for object X.
ROM5:8A31 JSR update_link_sprite_and_check_ladder ; This handles a couple things: updating Link's walking sprite
  ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
ROM5:8A32 LDA task_state
ROM5:8A33 BNE loc_14A60
ROM5:8A34 JSR clear_oam ; Clear the OAM buffer.
ROM5:8A35 JSR setup_minimap_triforce_position_if_holding_compass
ROM5:8A36 JSR update_link_sprite_and_other_stuff ; This calls update_link_sprite_and_check_ladder_if_overworld (if not in GameMode_InOverworldCellar
  ; or GameMode_ExitingOverworldCellar), and does some other things that I haven't traced. They seem
  ; to be sprite update-related.
ROM5:8A37 JSR check_if_item_selection_is_valid
ROM5:8A38 JSR disable_greyscale
ROM5:8A39 LDA #var_0
ROM5:8A3A STA paused
ROM5:8A3B STA partial_heart ; Half heart if < 0x80, and a timer for potion refills
ROM5:8A3C JSR no_pending_rupees_to_subtract
ROM5:8A3D INC task_state
ROM5:8A3E LDA #$10
ROM5:8A3F STA invincibility_frames ; set 0x10
ROM5:8A40 LDA #$21
ROM5:8A41 STA enemy_action_timers ; set 0x21
ROM5:8A42 RTS
 
ROM5:8A60 loc_14A60:
ROM5:8A60 LDA enemy_action_timers
ROM5:8A61 BNE locret_14A96
ROM5:8A62 JSR dungeon_get_screen_code ; Set A to the screen code of the current location when in a dungeon.
ROM5:8A63 AND #$3E
ROM5:8A64 CMP #$3E
ROM5:8A65 BEQ loc_14A75
ROM5:8A66 LDA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:8A67 STA previous_unlocked_door_directions ; Set to unlocked_door_directions. This just makes the below
  ; call leave unlocked_door_directions alone, since it temporarily
  ; sets it to temporary_unlocked_door_directions.
ROM5:8A68 JSR call_sub_164F6_with_previous_unlocked_door_directions
 
ROM5:8A75 loc_14A75:
ROM5:8A75 LDA #$60
ROM5:8A76 STA next_palette_cycle
ROM5:8A77 LDA #2
ROM5:8A78 STA death_cutscene_timer_1 ; Set to 2.
ROM5:8A79 LDA #0
ROM5:8A7A STA task_state
ROM5:8A7B STA byte_E9
ROM5:8A7C STA walk_state_and_weapon_state
ROM5:8A7D LDA #4
ROM5:8A7E STA byte_E5
ROM5:8A7F STA object_direction
ROM5:8A80 INC active_game_mode_task ; Set to 1
 
ROM5:8A8E loc_14A8E:
ROM5:8A8E LDA #Sound3_Stop
ROM5:8A8F STA play_sound_3 ; Set Sound3_Stop
ROM5:8A90 STA play_sound_2 ; Set Sound3_Stop
 
ROM5:8A96 locret_14A96:
ROM5:8A96 RTS
 
Subroutine screen_status_bit_set_X
; Add (1 << A) to the current screen's status.
ROM5:8A97 screen_status_bit_set_X:
ROM5:8A97 JSR get_screen_status ; Out Y = map location
  ; Out A = screen status for the current screen
  ; Out var_0 = pointer to screen status for this dungeon
  ; Bits 0x0F (dungeons): direction mask for bombed/opened doors
  ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM5:8A98 ORA powers_of_two,X
ROM5:8A99 STA (var_0),Y
ROM5:8A9A RTS
 
Subroutine screen_status_clear_bit_X
; Remove (1 << A) to the current screen's status.
ROM5:8AA0 screen_status_clear_bit_X:
ROM5:8AA0 JSR get_screen_status ; Out Y = map location
  ; Out A = screen status for the current screen
  ; Out var_0 = pointer to screen status for this dungeon
  ; Bits 0x0F (dungeons): direction mask for bombed/opened doors
  ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM5:8AA1 LDA powers_of_two,X
ROM5:8AA2 EOR #$FF
ROM5:8AA3 AND (var_0),Y
ROM5:8AA4 STA (var_0),Y
ROM5:8AA5 RTS
 
Subroutine handle_open_doors_in_dungeon_room
; If open_doors_in_room is set, open all doors in this dungeon room.
ROM5:8AAD handle_open_doors_in_dungeon_room:
ROM5:8AAD LDA open_doors_in_room
ROM5:8AAE BEQ clear_open_doors_in_room
ROM5:8AAF LDA #ControllerBits_Dpad_Up ; Find the next shutter door in the room which is still
  ; closed. This will open one door per call.
ROM5:8AB0 STA var_14
 
ROM5:8AB1 loop:
ROM5:8AB1 LDA var_14
ROM5:8AB2 AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:8AB3 BEQ door_direction_not_open
 
ROM5:8AB4 not_shutter:
ROM5:8AB4 LSR var_14
ROM5:8AB5 LDA var_14
ROM5:8AB6 BNE loop ; Loop for each direction.
 
ROM5:8AB7 clear_open_doors_in_room:
ROM5:8AB7 LDA #0
ROM5:8AB8 STA open_doors_in_room
ROM5:8AB9 RTS
 
ROM5:8ABA door_direction_not_open:
ROM5:8ABA LDA var_14
ROM5:8ABB STA var_2 ; Set the direction we're testing to var_2 for get_dungeon_door_type.
ROM5:8ABC JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:8ABD CMP #DungeonDoor_ShutterDoor
ROM5:8ABE BNE not_shutter ; We're only looking for shutter doors.
ROM5:8ABF LDA byte_54 ; Stop if opening a door is already active (don't do this
  ; if we're currently bombing a bomb door).
ROM5:8AC0 BNE ret
ROM5:8AC1 LDA var_2
 
ROM5:8ADA start_opening_key_or_bomb_door:
ROM5:8ADA STA bombing_or_unlocking_door_direction
ROM5:8ADB LDA #6
ROM5:8ADC STA byte_54 ; Set to 6
 
ROM5:8ADD ret:
ROM5:8ADD RTS
 
ROM5:8AE3 byte_14AE3: .BYTE $F3
ROM5:8AE4   .BYTE 2
ROM5:8AE5   .BYTE $50
ROM5:8AE6 byte_14AE6: .BYTE $27
ROM5:8AE7   .BYTE $37
ROM5:8AE8   .BYTE $47
ROM5:8AE9 game_mode_list_from_next_work_values: .BYTE 3
ROM5:8AEA   .BYTE $D
ROM5:8AEB   .BYTE 0
ROM5:8AEC byte_14AEC: .BYTE $23
ROM5:8AED   .BYTE $D2
ROM5:8AEE   .BYTE $43
ROM5:8AEF   .BYTE 0
ROM5:8AF0   .BYTE $FF
ROM5:8AF1 byte_14AF1: .BYTE $CB
ROM5:8AF2   .BYTE $CB
ROM5:8AF3   .BYTE $D3
ROM5:8AF4 byte_14AF4: .BYTE 5
ROM5:8AF5   .BYTE $50
ROM5:8AF6   .BYTE $55
 
Function chunk for task1_GameOverMenu
ROM5:8AF7 task1_GameOverMenu_main:
ROM5:8AF7 LDA task_state
ROM5:8AF8 ASL A
ROM5:8AF9 BCS loc_14B38
ROM5:8AFA LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM5:8AFB AND #ControllerBits_Start
ROM5:8AFC BNE loc_14B2D
ROM5:8AFD LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM5:8AFE AND #ControllerBits_Select
ROM5:8AFF BEQ loc_14B19
ROM5:8B00 LDA #Sound3_ShieldTing
ROM5:8B01 STA play_sound_3 ; Play Sound3_ShieldTing
ROM5:8B02 INC task_state
ROM5:8B03 LDA task_state
ROM5:8B04 CMP #3
ROM5:8B05 BNE loc_14B19
ROM5:8B06 LDA #0
ROM5:8B07 STA task_state
 
ROM5:8B19 loc_14B19:
ROM5:8B19 LDY #2
 
ROM5:8B1B loc_14B1B:
ROM5:8B1B LDA byte_14AE3,Y
ROM5:8B1C STA sprite_oam_data.tile,Y
ROM5:8B1D DEY
ROM5:8B1E BPL loc_14B1B
ROM5:8B1F LDY task_state
ROM5:8B20 LDA byte_14AE6,Y
ROM5:8B21 STA sprite_oam_data.y_pos
ROM5:8B22 RTS
 
ROM5:8B2D loc_14B2D:
ROM5:8B2D LDA task_state
ROM5:8B2E ORA #$80
ROM5:8B2F STA task_state
ROM5:8B30 LDA #$40
ROM5:8B31 STA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM5:8B32 RTS
 
ROM5:8B38 loc_14B38: ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM5:8B38 LDA npc_action_timer_1
ROM5:8B39 BEQ loc_14B67
ROM5:8B3A LDY #4
 
ROM5:8B3E loc_14B3E:
ROM5:8B3E LDA byte_14AEC,Y
ROM5:8B3F STA ppu_command_buffer,Y
ROM5:8B40 DEY
ROM5:8B41 BPL loc_14B3E
ROM5:8B42 LDA task_state
ROM5:8B43 AND #3
ROM5:8B44 TAY
ROM5:8B45 LDA byte_14AF1,Y
ROM5:8B46 STA ppu_command_buffer_01
ROM5:8B47 LDY #0
ROM5:8B48 LDA npc_action_timer_1 ; Enemy code that expects to be the only active object at index 1 references this array entry directly.
ROM5:8B49 AND #4
ROM5:8B4A BEQ loc_14B63
ROM5:8B4B LDA task_state
ROM5:8B4C AND #3
ROM5:8B4D TAY
ROM5:8B4E LDA byte_14AF4,Y
ROM5:8B4F TAY
 
ROM5:8B63 loc_14B63:
ROM5:8B63 STY ppu_command_buffer_03
ROM5:8B64 RTS
 
ROM5:8B67 loc_14B67:
ROM5:8B67 LDA task_state
ROM5:8B68 AND #3
ROM5:8B69 STA task_state
ROM5:8B6A JSR deactivate_clock_and_walk_state
ROM5:8B6B LDY task_state
ROM5:8B6C LDA game_mode_list_from_next_work_values,Y
ROM5:8B6D STA game_mode ; set from game_mode_list_from_next_work_values
ROM5:8B6E LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM5:8B6F AND #$F0
ROM5:8B70 ORA #2
ROM5:8B71 STA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM5:8B72 LDA #$FF
ROM5:8B73 STA partial_heart ; Half heart if < 0x80, and a timer for potion refills
ROM5:8B74 JSR clear_game_mode_task_and_state
ROM5:8B75 CPY #2
ROM5:8B76 BNE loc_14B92
ROM5:8B77 DEY
ROM5:8B78 STY task_state
ROM5:8B79 INC active_game_mode_task ; If 0, we run task0 for the current game_mode. If 1, we run task1.
 
ROM5:8B92 loc_14B92:
ROM5:8B92 JMP stop_sounds
 
Function chunk for task1_EnteringDoor
ROM5:8B93 task1_EnteringDoor_main: ; Check if 0x24
ROM5:8B93 LDA tile_walking_onto
ROM5:8B94 CMP #$24
ROM5:8B95 BNE loc_14BAB
ROM5:8B96 LDA frame_counter
ROM5:8B97 AND #3
ROM5:8B98 BNE loc_14BB2 ; Skip if the frame number isn't divisible by 4
ROM5:8B99 INC object_y
ROM5:8B9A LDA object_y
ROM5:8B9B CMP enemy_state_0
ROM5:8B9C BNE loc_14BB2
 
ROM5:8BAB loc_14BAB:
ROM5:8BAB LDA next_game_mode
ROM5:8BAC STA game_mode ; set from next_game_mode
ROM5:8BAD JSR clear_game_mode_task_and_state
 
ROM5:8BB2 loc_14BB2: ; This handles a couple things: updating Link's walking sprite
ROM5:8BB2 JSR update_link_sprite_and_check_ladder ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
 
ROM5:8BB5 set_0x20_in_oam_data:
ROM5:8BB5 LDA sprite_oam_data_4A
ROM5:8BB6 ORA #$20
ROM5:8BB7 STA sprite_oam_data_4A
ROM5:8BB8 LDA sprite_oam_data_4E
ROM5:8BB9 ORA #$20
ROM5:8BBA STA sprite_oam_data_4E
ROM5:8BBB RTS
 
Subroutine dungeon_only_handle_secrets_and_shutters
ROM5:8BC6 dungeon_only_handle_secrets_and_shutters:
ROM5:8BC6 JSR check_if_room_cleared ; Set room_clear to 1 if all enemies in the room are dead.
ROM5:8BC7 LDA current_screen_data_5 ; This is the dungeon_screen_data_5 value for the
  ; current room. This has different interpretations
  ; for the overworld and dungeons.
ROM5:8BC8 AND #7
ROM5:8BC9 BEQ skip
ROM5:8BCA JSR call_secrets_handler ; Call the door/secrets handler for this screen.
 
  ; Return carry set if any room item should appear, or clear
  ; if the room item shouldn't be spawned yet.
ROM5:8BCB BCC skip
ROM5:8BCC LDA current_screen_data_5 ; This is the dungeon_screen_data_5 value for the
  ; current room. This has different interpretations
  ; for the overworld and dungeons.
ROM5:8BCD AND #7
ROM5:8BCE CMP #ScreenData_Dungeon_5_KillingEverythingOpensDoorAndSpawnsItem
ROM5:8BCF BNE skip
ROM5:8BD0 LDA current_room_floor_item_hidden
ROM5:8BD1 BEQ skip ; Branch if current_room_floor_item_hidden == 0.
ROM5:8BD2 JSR get_room_status_floor_item_picked_up
ROM5:8BD3 BNE skip ; Branch if the item has already been taken.
ROM5:8BD4 LDA #0
ROM5:8BD5 STA current_room_floor_item_hidden ; Set to 0 to show the room item.
ROM5:8BD6 LDA #Sound1_ItemAppeared
ROM5:8BD7 STA play_sound_1 ; Play Sound1_ItemAppeared
 
ROM5:8BD8 skip:
ROM5:8BD8 RTS
 
ROM5:8BD9 call_secrets_handler: ; Call the door/secrets handler for this screen.
ROM5:8BD9 JSR call_jump_table
  ; Return carry set if any room item should appear, or clear
  ; if the room item shouldn't be spawned yet.
 
ROM5:8BDA   .WORD skip ; ScreenData_Dungeon_5_NoRoomItem
ROM5:8BDC   .WORD room_handler_killing_enemies_opens_doors ; ScreenData_Dungeon_5_KillingEverythingOpensDoors
ROM5:8BDE   .WORD room_handler_master_enemy_opens_doors_and_kills_everything ; ScreenData_Dungeon_5_MasterEnemyOpensDoorsAndKillsEverything
ROM5:8BE0   .WORD room_handler_ganon_triforce_opens_doors ; ScreenData_Dungeon_5_GanonTriforceOpensDoors
ROM5:8BE2   .WORD room_handler_push_block_opens_doors ; ScreenData_Dungeon_5_PushBlockOpensDoors
ROM5:8BE4   .WORD room_handler_push_block_shows_staircase ; ScreenData_Dungeon_5_PushBlockShowsStaircase
ROM5:8BE6   .WORD room_handler_master_enemy_opens_doors ; ScreenData_Dungeon_5_MasterEnemyOpensDoors
ROM5:8BE8   .WORD room_handler_killing_enemies_opens_doors ; ScreenData_Dungeon_5_KillingEverythingOpensDoorAndSpawnsItem
 
Subroutine check_if_room_cleared
; Set room_clear to 1 if all enemies in the room are dead.
ROM5:8C04 check_if_room_cleared:
ROM5:8C04 LDY processing_object_index
 
ROM5:8C05 loop: ; Check each active object and see if there are any
ROM5:8C05 LDA object_type_1,Y ; remaining killable enemies. This excludes things like
  ; bubbles, whirlwinds and old men.
ROM5:8C06 BEQ continue
ROM5:8C07 CMP #ObjectType_Bubble
ROM5:8C08 BCC ret ; < ObjectType_Bubble (0x2A)
ROM5:8C09 CMP #ObjectType_Whirlwind ; A >= ObjectType_Bubble
ROM5:8C0A BCC continue ; < ObjectType_Whirlwind (0x2E)
ROM5:8C0B CMP #ObjectType_WallTrap_Vert
ROM5:8C0C BCC ret ; < ObjectType_WallTrap_Vert (0x49)
 
ROM5:8C0D continue: ; A is any Bubble, or >= ObjectType_WallTrap_Vert
ROM5:8C0D DEY
ROM5:8C0E BPL loop
ROM5:8C0F LDA #0
ROM5:8C10 STA held_by_like_like ; Set to 0
ROM5:8C11 INC room_clear ; All enemies on the room are dead (or there weren't any to begin with)
 
ROM5:8C12 ret:
ROM5:8C12 RTS
 
Subroutine room_handler_killing_enemies_opens_doors
; Open doors and spawn the room item after all enemies in the room have been killed.
ROM5:8C24 room_handler_killing_enemies_opens_doors:
ROM5:8C24 LDA room_clear ; Check if all enemies are dead
ROM5:8C25 BEQ return_wall_unpassable ; Don't open doors if there are still killable enemies.
 
ROM5:8C29 open_doors_and_spawn_room_item: ; Trigger opening all doors in the room, and return passable.
ROM5:8C29 LDA #1
ROM5:8C2A STA open_doors_in_room ; Set to 1
ROM5:8C2B SEC
ROM5:8C2C RTS
 
Subroutine return_wall_unpassable
ROM5:8C30 return_wall_unpassable:
ROM5:8C30 CLC
ROM5:8C31 RTS
 
Subroutine room_handler_master_enemy_opens_doors_and_kills_everything
; If the first enemy in the room has been killed, kill all ; other enemies and allow the room item to be spawned.
ROM5:8C32 room_handler_master_enemy_opens_doors_and_kills_everything:
ROM5:8C32 LDA object_type_1
ROM5:8C33 BEQ master_enemy_is_dead ; The master enemy is the first object. Check if the first
  ; object is gone, or if the object there is a projectile (which
  ; means it died and another object was spawned there).
ROM5:8C34 CMP #ObjectType_Octorok_Projectile
ROM5:8C35 BCC return_wall_unpassable ; < ObjectType_Octorok_Projectile
 
ROM5:8C36 master_enemy_is_dead:
ROM5:8C36 LDY processing_object_index
 
ROM5:8C37 loop:
ROM5:8C37 LDA object_type_1,Y
ROM5:8C38 BEQ continue ; Skip if zero
ROM5:8C39 CMP #ObjectType_Octorok_Projectile
ROM5:8C3A BCS continue ; Skip if >= ObjectType_Octorok_Projectile. Projectiles
  ; don't die when the master enemy is killed.
ROM5:8C3B LDA enemy_spawn_state_1,Y
ROM5:8C3C BNE continue
ROM5:8C3D LDA #$10 ; Mark this enemy dead.
ROM5:8C3E STA enemy_spawn_state_1,Y
 
ROM5:8C3F continue:
ROM5:8C3F DEY
ROM5:8C40 BPL loop
ROM5:8C41 SEC
ROM5:8C42 RTS
 
Subroutine room_handler_push_block_opens_doors
; If a push block in the room has been pushed, trigger opening ; all doors and return passable. Otherwise, return unpassable.
ROM5:8C56 room_handler_push_block_opens_doors:
ROM5:8C56 LDA pushed_dungeon_push_block
ROM5:8C57 BEQ return_wall_unpassable ; Branch if the push block in this room hasn't been pushed yet.
ROM5:8C58 BNE open_doors_and_spawn_room_item ; Always branches.
 
Subroutine room_handler_push_block_shows_staircase
ROM5:8C5D room_handler_push_block_shows_staircase:
ROM5:8C5D LDA pushed_dungeon_push_block
ROM5:8C5E BEQ return_wall_unpassable ; Return unpassable if pushed_dungeon_push_block == 0.
ROM5:8C5F LSR A
ROM5:8C60 BCC return_wall_unpassable ; Return unpassable if (pushed_dungeon_push_block & 1) == 0.
ROM5:8C61 INC pushed_dungeon_push_block ; Set pushed_dungeon_push_block to 2. The push block is still
  ; marked as pushed, but the above test will exit on future calls.
ROM5:8C62 LDX #$B ; This is changing a tile in the top-right corner of the room,
  ; so this is probably setting the stairway tile.
ROM5:8C63 LDA #208
ROM5:8C64 STA object_x,X
ROM5:8C65 LDA #96
ROM5:8C66 STA object_y,X
ROM5:8C67 LDA #$70
ROM5:8C68 JSR change_background_tile_at_current_object_position ; Change the background tile at the screen position of the
  ; current object to A. This is used to remove things like
  ; Armos statues and candle spots after they've been activated.
 
  ; This is called from both ROM4 and ROM5.
 
  ; If ppu_unknown_task_returns_to_ROM4 is set, this is being
  ; called from ROM4 and needs to reset bank 0 to ROM4 before
  ; it returns.
 
  ; Otherwise, it's being called from ROM5 and will set bank ROM5
  ; before returning.
ROM5:8C69 SEC ; Return passable.
ROM5:8C6A RTS
 
Subroutine room_handler_ganon_triforce_opens_doors
; Is this only used for Ganon's room?
ROM5:8C79 room_handler_ganon_triforce_opens_doors:
ROM5:8C79 LDA has_ganon_triforce
ROM5:8C7A BNE open_doors_and_spawn_room_item ; Trigger opening all doors in the room, and return passable.
ROM5:8C7B CLC
ROM5:8C7C RTS
 
Subroutine room_handler_master_enemy_opens_doors
; If the first enemy has been killed, open doors and return ; passable. Otherwise, return unpassable. This doesn't kill ; other enemies on the screen. This is probably used for boss ; rooms.
ROM5:8C80 room_handler_master_enemy_opens_doors:
ROM5:8C80 LDA object_type_1
ROM5:8C81 BEQ open_doors_and_spawn_room_item ; Trigger opening all doors in the room, and return passable.
ROM5:8C82 CLC
ROM5:8C83 RTS
 
Function chunk for task1_JustDied
ROM5:8C84 task1_JustDied_main:
ROM5:8C84 LDA task_state
ROM5:8C85 JSR call_jump_table
 
ROM5:8C86   .WORD task1_JustDied_0
ROM5:8C88   .WORD task1_JustDied_1
ROM5:8C8A   .WORD task1_JustDied_2
ROM5:8C8C   .WORD task1_JustDied_3
ROM5:8C8E   .WORD task1_JustDied_4
ROM5:8C90   .WORD task1_JustDied_5
ROM5:8C92   .WORD task1_JustDied_6
ROM5:8C94   .WORD task1_JustDied_7
ROM5:8C96   .WORD task1_JustDied_8
ROM5:8C98   .WORD task1_JustDied_9
ROM5:8C9A   .WORD task1_JustDied_10
ROM5:8C9C   .WORD task1_JustDied_11
ROM5:8C9E   .WORD task1_JustDied_12
 
Subroutine task1_JustDied_1
ROM5:8CA6 task1_JustDied_1:
ROM5:8CA6 LDA #Sound1_LinkDiedMusic
ROM5:8CA7 STA play_sound_1 ; Play Sound1_LinkDiedMusic
 
ROM5:8CAB task1_JustDied_0:
ROM5:8CAB JSR sub_14484
 
ROM5:8CAE loc_14CAE: ; Is this value used? The call below seems to clobber X.
ROM5:8CAE LDX #$2B
 
ROM5:8CB0 loc_14CB0:
ROM5:8CB0 JSR task1_JustDied_store_ppu_command_ending_at_Y
ROM5:8CB1 INC task_state
ROM5:8CB2 RTS
 
Subroutine task1_JustDied_2
ROM5:8CB6 task1_JustDied_2:
ROM5:8CB6 JSR task0_InOverworldCellar_4
ROM5:8CB7 BCC add_8_to_ppu_command_buffer
ROM5:8CB8 JSR set_oam_sprite_0_after_hud ; This puts a bomb sprite in the HUD overlapping the bomb
  ; in the background. This is used to trigger a sprite zero
  ; hit after the PPU finishes drawing the HUD and before it
  ; starts drawing the play field. OnNMI waits for this in
  ; wait_for_sprite_0_hit to allow changing PPU flags to
  ; scroll the play field during transitions without scrolling
  ; the HUD.
 
  ; https://wiki.nesdev.com/w/index.php/PPU_OAM#Sprite_zero_hits
 
ROM5:8CB9 add_8_to_ppu_command_buffer:
ROM5:8CB9 LDA ppu_command_buffer
ROM5:8CBA CLC
ROM5:8CBB ADC #8
ROM5:8CBC STA ppu_command_buffer
ROM5:8CBD RTS
 
Subroutine task1_JustDied_3
ROM5:8CC8 task1_JustDied_3:
ROM5:8CC8 LDA #PPUCommandIndices_JustDied_3
 
ROM5:8CCA loc_14CCA: ; Set to PPUCommandIndices_Cellar, PPUCommandIndices_JustDied_3 or PPUCommandIndices_JustDied_4 or PPUCommandIndices_JustDied_5
ROM5:8CCA JMP set_current_ppu_command_index_and_advance_task_state
 
Subroutine task1_JustDied_4
ROM5:8CCD task1_JustDied_4:
ROM5:8CCD LDA #PPUCommandIndices_JustDied_4
ROM5:8CCE JMP loc_14CCA
 
Subroutine task1_JustDied_5
ROM5:8CD2 task1_JustDied_5:
ROM5:8CD2 LDA #0
ROM5:8CD3 STA do_ppu_work_after_sprite0_next_frame ; Set to 0.
ROM5:8CD4 LDA #PPUCommandIndices_JustDied_5
ROM5:8CD5 JMP loc_14CCA
 
Subroutine task1_JustDied_6
ROM5:8CDB task1_JustDied_6:
ROM5:8CDB LDA current_ppuctrl
ROM5:8CDC AND #$FE
ROM5:8CDD STA current_ppuctrl
 
ROM5:8CE1 increment_work_value_and_return_2:
ROM5:8CE1 INC task_state
ROM5:8CE2 RTS
 
Subroutine task1_JustDied_7
ROM5:8CE4 task1_JustDied_7:
ROM5:8CE4 LDA byte_E5
ROM5:8CE5 BEQ increment_work_value_and_return_2
ROM5:8CE6 LDA death_cutscene_timer_2
ROM5:8CE7 BNE loc_14CFC
ROM5:8CE8 LDA #5
ROM5:8CE9 STA death_cutscene_timer_2
ROM5:8CEA LDA object_direction
ROM5:8CEB LSR A
ROM5:8CEC LSR A
ROM5:8CED BCC loc_14CFF
ROM5:8CEE DEC byte_E5
ROM5:8CEF LDA #4
 
ROM5:8CFA loc_14CFA:
ROM5:8CFA STA object_direction
 
ROM5:8CFC loc_14CFC: ; This handles a couple things: updating Link's walking sprite
ROM5:8CFC JMP update_link_sprite_and_check_ladder ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
 
ROM5:8CFF loc_14CFF:
ROM5:8CFF BNE loc_14CFA
ROM5:8D00 LDA #8
ROM5:8D01 BNE loc_14CFA
 
Subroutine task1_JustDied_8
ROM5:8D05 task1_JustDied_8:
ROM5:8D05 JSR update_timed_palette_cycle
ROM5:8D06 BEQ increment_work_value_and_return_2
ROM5:8D07 RTS
 
Subroutine task1_JustDied_9
ROM5:8D0B task1_JustDied_9:
ROM5:8D0B LDA #PPUCommandIndices_JustDied_SetLinkGreyscale
ROM5:8D0C STA current_ppu_command_index ; Set to PPUCommandIndices_JustDied_SetLinkGreyscale.
ROM5:8D0D LDA #$F
ROM5:8D0E STA byte_E5
ROM5:8D0F LDA #$18
ROM5:8D10 BNE loc_14D5B
 
ROM5:8D17 task1_JustDied_10:
ROM5:8D17 LDA death_cutscene_timer_2
ROM5:8D18 BNE locret_14D5F
ROM5:8D19 LDX #$62
ROM5:8D1A LDA byte_E5
ROM5:8D1B CMP #6
ROM5:8D1C BCS loc_14D25
ROM5:8D1D LDX #$64
 
ROM5:8D25 loc_14D25:
ROM5:8D25 LDA object_y
ROM5:8D26 STA sprite_oam_data_48
ROM5:8D27 STA sprite_oam_data_4C
ROM5:8D28 STX sprite_oam_data_49
ROM5:8D29 STX sprite_oam_data_4D
ROM5:8D2A LDA #1
ROM5:8D2B STA sprite_oam_data_4A
ROM5:8D2C LDA #$41
ROM5:8D2D STA sprite_oam_data_4E
ROM5:8D2E LDA object_x
ROM5:8D2F STA sprite_oam_data_4B
ROM5:8D30 CLC
ROM5:8D31 ADC #8
ROM5:8D32 STA sprite_oam_data_4F
ROM5:8D33 DEC byte_E5
ROM5:8D34 BNE locret_14D5F
ROM5:8D35 LDA #Sound3_GainRupee
ROM5:8D36 STA play_sound_3 ; Play Sound3_GainRupee
ROM5:8D37 LDA #$F8
ROM5:8D38 STA sprite_oam_data_48
ROM5:8D39 STA sprite_oam_data_4C
ROM5:8D3A LDA #$2E
 
ROM5:8D5B loc_14D5B:
ROM5:8D5B STA death_cutscene_timer_2
ROM5:8D5C INC task_state
 
ROM5:8D5F locret_14D5F:
ROM5:8D5F RTS
 
Subroutine task1_JustDied_11
ROM5:8D60 task1_JustDied_11:
ROM5:8D60 LDA death_cutscene_timer_2
ROM5:8D61 BNE locret_14D5F
ROM5:8D62 LDA #$60
ROM5:8D63 STA death_cutscene_timer_2
ROM5:8D64 LDA #$46
ROM5:8D65 JMP loc_14CCA
 
Subroutine task1_JustDied_12
ROM5:8D6D task1_JustDied_12:
ROM5:8D6D LDA death_cutscene_timer_2
ROM5:8D6E BNE locret_14D89
ROM5:8D6F JSR clear_game_mode_task_and_state
ROM5:8D70 LDA #GameMode_GameOverMenu
ROM5:8D71 STA game_mode ; set GameMode_GameOverMenu
ROM5:8D72 LDA #Sound1_EndlessDeathMusic
ROM5:8D73 STA play_sound_1 ; Play Sound1_EndlessDeathMusic
ROM5:8D74 LDX current_save_slot
ROM5:8D75 LDA deaths_per_save_slot,X
ROM5:8D76 CMP #$FF
ROM5:8D77 BEQ locret_14D89
ROM5:8D78 INC deaths_per_save_slot,X ; Increase the death counter.
 
ROM5:8D89 locret_14D89:
ROM5:8D89 RTS
 
ROM5:8D8A item_and_sword_screen_limits: .BYTE 214 ; Down: Screen bounds to prevent the sword in the overworld
ROM5:8D8B   .BYTE 69 ; Up
ROM5:8D8C   .BYTE 233 ; Right
ROM5:8D8D   .BYTE 7 ; Left
ROM5:8D8E   .BYTE 198 ; Down: Screen bounds to prevent the sword in dungeons
ROM5:8D8F   .BYTE 85 ; Up
ROM5:8D90   .BYTE 217 ; Right
ROM5:8D91   .BYTE 23 ; Left
ROM5:8D92   .BYTE 190 ; Down: Screen bounds to prevent items everywhere
ROM5:8D93   .BYTE 84 ; Up
ROM5:8D94   .BYTE 209 ; Right
ROM5:8D95   .BYTE 31 ; Left
 
Subroutine prevent_item_and_sword_when_near_screen_edge
; If Link is close to the edge of the screen and facing in that ; direction, prevent using items or the sword. ; ; The threshold for preventing items and the sword is different, ; and the sword threshold is different in the overworld and in ; dungeon.
ROM5:8D96 prevent_item_and_sword_when_near_screen_edge:
ROM5:8D96 LDA object_direction
ROM5:8D97 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM5:8D98 STA var_0 ; Store the opposite direction of object_direction
ROM5:8D99 JSR get_opposite_direction_and_index ; Y = direction index of var_0
ROM5:8D9A LDA object_x
ROM5:8D9B CPY #2 ; Down: 0, Up: 1, Right: 2, Left: 3
ROM5:8D9C BCS facing_horizontal ; Branch if Y >= 2 (facing horizontal) with A = Link's X position
ROM5:8D9D LDA object_y ; Facing vertical
 
ROM5:8D9E facing_horizontal: ; Object X or Y position
ROM5:8D9E STA var_2
ROM5:8D9F TYA
ROM5:8DA0 PHA ; Push direction index
ROM5:8DA1 CLC
ROM5:8DA2 ADC #8 ; Y = direction index + 8 (index into byte_14D8A)
ROM5:8DA3 TAY
ROM5:8DA4 LDA #ControllerBits_A ; A = ControllerBits_A. This bounds check allows A (sword), but
  ; masks away items (ControllerBits_B).
ROM5:8DA5 JSR check_screen_bounds ; This will set var_1.
ROM5:8DA6 PLA ; Restore direction index into Y, this time without +8 offset
ROM5:8DA7 TAY
ROM5:8DA8 LDA var_1 ; If var_1 is 0xFF, we were in bounds for the check_screen_bounds call
ROM5:8DA9 CMP #$FF
ROM5:8DAA BNE was_out_of_bounds ; Branch if var_1 != 0xFF, which means check_screen_bounds was
  ; out of bounds.
ROM5:8DAB LDA object_direction
ROM5:8DAC STA var_0 ; var_0 = object_direction. Previously, it was the opposite
  ; of object_direction.
ROM5:8DAD JSR get_opposite_direction_and_index ; Y = direction index of var_0
 
ROM5:8DAE was_out_of_bounds:
ROM5:8DAE LDA dungeon_idx
ROM5:8DAF BEQ is_overworld ; In overworld, skip offset + 4
ROM5:8DB0 TYA ; Y = direction index + 4 (index into item_and_sword_screen_limits)
ROM5:8DB1 CLC
ROM5:8DB2 ADC #4
ROM5:8DB3 TAY
 
ROM5:8DB4 is_overworld: ; Now run the same routine with A = 0, so it blocks both items and the sword.
ROM5:8DB4 LDA #0
 
ROM5:8DB5 check_screen_bounds: ; var_1 is a mask of buttons that should be allowed if we're
ROM5:8DB5 STA var_1 ; out of the current bounds. This is ControllerBits_A if
  ; we should allow the sword but not items, or 0 if we
  ; shouldn't allow either.
 
  ; Out var_1 != 0xFF (left unchanged) if we're outside of the
  ; bounds we're testing, or 0xFF if we're in bounds.
ROM5:8DB6 LDA var_0 ; Load opposite direction from object_direction
ROM5:8DB7 AND #ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
ROM5:8DB8 BEQ right_or_down
ROM5:8DB9 LDA var_2 ; X or Y position
ROM5:8DBA CMP item_and_sword_screen_limits,Y
ROM5:8DBB BCC return_not_out_of_bounds ; Position < item_and_sword_screen_limits[Y]
 
ROM5:8DBC position_matched: ; We get here if var_0 is right or down and var_2 < pos,
ROM5:8DBC LDA controller_1_pressed ; or var_0 is left or up and var_2 >= pos.
 
  ; Mask away buttons that aren't in var_1. This either prevents
  ; items or both items and the sword.
ROM5:8DBD AND var_1
ROM5:8DBE STA controller_1_pressed ; P1 buttons pressed on this frame
ROM5:8DBF LDA dungeon_idx
ROM5:8DC0 BEQ ret ; Skip if overworld
ROM5:8DC1 LDA var_1
ROM5:8DC2 BNE ret ; Return if var_1 != 0, eg. this is the initial ControllerBits_A call.
ROM5:8DC3 LDY #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:8DC4 LDA object_direction
ROM5:8DC5 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:8DC6 BNE mask_walking_directions ; If we're facing vertically, mask the walking direction to up and down.
ROM5:8DC7 LDY #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left ; Otherwise, mask to left and right.
 
  ; This prevents changing direction when near the edge
  ; of the screen in dungeons. That's also done by
  ; lock_movement_to_dungeon_door.
 
ROM5:8DC8 mask_walking_directions:
ROM5:8DC8 TYA
ROM5:8DC9 AND walking_directions
ROM5:8DCA STA walking_directions
 
ROM5:8DCB ret:
ROM5:8DCB RTS
 
ROM5:8DCC right_or_down: ; X or Y position
ROM5:8DCC LDA var_2
ROM5:8DCD CMP item_and_sword_screen_limits,Y
ROM5:8DCE BCC position_matched ; Position < item_and_sword_screen_limits[Y]
 
ROM5:8DCF return_not_out_of_bounds: ; We're not out of bounds on the direction we're testing.
ROM5:8DCF LDA #$FF ; Set var_1 to 0xFF.
ROM5:8DD0 STA var_1
 
ROM5:8E09 locret_14E09:
ROM5:8E09 RTS
 
Subroutine link_swing_sword
ROM5:8E0A link_swing_sword:
ROM5:8E0A LDA sword_type
ROM5:8E0B BEQ locret_14E09
ROM5:8E0C LDX #$D
ROM5:8E0D LDA walk_state_and_weapon_state,X
ROM5:8E0E BNE locret_14E09
ROM5:8E0F LDA #5
ROM5:8E10 STA object_animation_frame_timer,X
ROM5:8E11 LDA #1
ROM5:8E12 JSR sub_14E99
ROM5:8E13 LDA #Sound2_SwingSword
ROM5:8E14 JMP add_play_sound_2 ; Play Sound2_SwingSword
 
ROM5:8E24 boomerang_throw_distances: .BYTE $31
ROM5:8E25   .BYTE $FF
 
Subroutine use_item
ROM5:8E26 use_item:
ROM5:8E26 LDA current_item
ROM5:8E27 CMP #$F
ROM5:8E28 BEQ locret_14E7B
ROM5:8E29 JSR call_jump_table
 
ROM5:8E2A   .WORD use_item_boomerang
ROM5:8E2C   .WORD use_item_bomb ; Load to see if we have any bombs
ROM5:8E2E   .WORD use_item_bow
ROM5:8E30   .WORD locret_14EB0
ROM5:8E32   .WORD use_item_candle
ROM5:8E34   .WORD use_item_recorder
ROM5:8E36   .WORD use_item_meat
ROM5:8E38   .WORD use_item_potion
ROM5:8E3A   .WORD use_item_rod
 
Subroutine use_item_boomerang
ROM5:8E42 use_item_boomerang:
ROM5:8E42 LDA have_boomerang
ROM5:8E43 ORA have_magic_boomerang
ROM5:8E44 BEQ locret_14E7B ; Exit if we don't have either boomerang
ROM5:8E45 LDX #$F
ROM5:8E46 LDA walk_state_and_weapon_state,X
ROM5:8E47 BEQ loc_14E53
ROM5:8E48 ASL A
ROM5:8E49 BCC locret_14E7B
 
ROM5:8E53 loc_14E53:
ROM5:8E53 LDA #$10
ROM5:8E54 STA walk_state_and_weapon_state,X
ROM5:8E55 LDY have_magic_boomerang
ROM5:8E56 LDA boomerang_throw_distances,Y
ROM5:8E57 STA enemy_state_11,X ; Store boomerang throw distance
ROM5:8E58 JSR loc_10711B
ROM5:8E59 LDA #$C0
ROM5:8E5A STA object_walk_speed,X
ROM5:8E5B LDA #3
ROM5:8E5C STA object_animation_frame_timer,X
ROM5:8E5D LDA #1
ROM5:8E5E STA object_animation_frame_timer
ROM5:8E5F LDA walking_directions
ROM5:8E60 BNE loc_14E79
ROM5:8E61 LDA object_direction
 
ROM5:8E79 loc_14E79:
ROM5:8E79 STA object_direction,X
 
ROM5:8E7B locret_14E7B:
ROM5:8E7B RTS
 
Subroutine use_item_bow
ROM5:8E7C use_item_bow:
ROM5:8E7C LDA have_bow
ROM5:8E7D BEQ locret_14EB0
ROM5:8E7E LDX #$12
ROM5:8E7F LDA walk_state_and_weapon_state,X
ROM5:8E80 BEQ loc_14E8A ; Load rupees to see if we can fire an arrow
ROM5:8E81 ASL A
ROM5:8E82 BCC locret_14EB0
 
ROM5:8E8A loc_14E8A: ; Load rupees to see if we can fire an arrow
ROM5:8E8A LDA num_rupees
ROM5:8E8B BEQ locret_14EB0 ; No ammo
ROM5:8E8C LDA #Sound2_FireArrow
ROM5:8E8D JSR add_play_sound_2 ; Play Sound2_FireArrow
ROM5:8E8E INC pending_rupees_sub ; Subtract rupee after firing arrow
ROM5:8E8F LDA #$10
 
Subroutine sub_14E99
; A is 1 for sword, 0x31 for wand
ROM5:8E99 sub_14E99:
ROM5:8E99 STA walk_state_and_weapon_state,X
ROM5:8E9A LDA #$C0
ROM5:8E9B STA object_walk_speed,X
ROM5:8E9C JSR sub_107116
ROM5:8E9D LDA object_direction,X
ROM5:8E9E AND #$C
ROM5:8E9F BEQ locret_14EB0
ROM5:8EA0 LDA object_x,X
ROM5:8EA1 CLC
ROM5:8EA2 ADC #3
ROM5:8EA3 STA object_x,X
 
ROM5:8EB0 locret_14EB0:
ROM5:8EB0 RTS
 
Subroutine use_item_meat
ROM5:8EB1 use_item_meat:
ROM5:8EB1 LDX #$F
ROM5:8EB2 LDA walk_state_and_weapon_state,X
ROM5:8EB3 BNE locret_14ED0
ROM5:8EB4 LDA #$FF
ROM5:8EB5 STA enemy_action_timers,X ; set to 0xFF
ROM5:8EB6 LDA #$80
ROM5:8EB7 JMP loc_107114
 
Subroutine use_item_potion
ROM5:8EC0 use_item_potion:
ROM5:8EC0 LDA have_potion_type
ROM5:8EC1 BEQ locret_14ED0
ROM5:8EC2 DEC have_potion_type
ROM5:8EC3 LDA #1
ROM5:8EC4 STA health_refill ; Set to 1 for potion refill
ROM5:8EC5 LDA #2
ROM5:8EC6 STA paused ; Set to 2 to lock pause during potion refill
 
Function chunk for check_for_cellar_exit
ROM5:8ED0 locret_14ED0:
ROM5:8ED0 RTS
 
Subroutine use_item_rod
ROM5:8ED1 use_item_rod:
ROM5:8ED1 LDX #game_mode
ROM5:8ED2 LDA walk_state_and_weapon_state,X
ROM5:8ED3 BNE locret_14ED0 ; Stop if this slot is already being used
ROM5:8ED4 LDA #5
ROM5:8ED5 STA object_animation_frame_timer,X
ROM5:8ED6 LDA #$31
ROM5:8ED7 JMP sub_14E99
 
Subroutine check_for_cellar_exit
; This is called in GameMode_InDungeonCellar, GameMode_InOverworldCellar ; and GameMode_ExitingOverworldCellar. ; ; Check if we're exiting a cellar. This will change game_mode ; if a screen transition is triggered.
ROM5:8EE1 check_for_cellar_exit:
 
ROM5:8EE1 LDA game_mode
ROM5:8EE2 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM5:8EE3 BNE not_in_cellar
ROM5:8EE4 LDA object_y
ROM5:8EE5 CMP #$40
ROM5:8EE6 BCS locret_14ED0 ; Stop if Link isn't high enough on the screen to exit (Y >= 0x40).
ROM5:8EE7 LDA walking_directions
ROM5:8EE8 AND #ControllerBits_Dpad_Up
ROM5:8EE9 BEQ locret_14ED0 ; Branch if Up isn't being held.
ROM5:8EEA LDY #6
ROM5:8EEB LDA map_location
ROM5:8EEC PHA ; Push map location
 
ROM5:8EED loop: ; Find the current room in stairs_loc. The index that we
ROM5:8EED DEY ; find is the room holding this cellar's screen data.
ROM5:8EEE CMP ppu_data_for_current_dungeon.stairs_loc,Y
ROM5:8EEF BNE loop
ROM5:8EF0 TAY
ROM5:8EF1 LDA object_x ; Get Link's X position to check whether we're exiting on
  ; the left or right side.
ROM5:8EF2 CMP #$80
ROM5:8EF3 BCS use_right_cellar_exit ; If Link's X >= 0x80, he's using the right side cellar exit.
ROM5:8EF4 LDA dungeon_screen_data_0,Y ; Load cellar exit screen number
ROM5:8EF5 JMP use_left_cellar_exit
 
ROM5:8EF6 use_right_cellar_exit: ; Load right cellar exit
ROM5:8EF6 LDA dungeon_screen_data_1,Y
 
ROM5:8EF7 use_left_cellar_exit: ; A is the target screen number.
ROM5:8EF7 JSR exit_cellar
ROM5:8EF8 PLA ; Pop map location
ROM5:8EF9 TAY
ROM5:8EFA LDA dungeon_screen_data_2,Y
ROM5:8EFB PHA ; Push dungeon exit position
ROM5:8EFC AND #$F0 ; Mask out cellar exit X position
ROM5:8EFD STA object_x ; Set Link's X position to the cellar exit
ROM5:8EFE PLA ; Pop dungeon exit position
ROM5:8EFF ASL A ; Shift cellar exit Y position left to 0xF0
ROM5:8F00 ASL A
ROM5:8F01 ASL A
ROM5:8F02 ASL A
ROM5:8F03 ORA #$D
ROM5:8F04 STA object_y ; Set Link's Y position to the cellar exit
ROM5:8F05 RTS
 
ROM5:8F06 not_in_cellar:
ROM5:8F06 PHA
ROM5:8F07 JSR stop_walking_to_top_half_of_screen ; If walking_state is Up and we're Y < 0x0x8E, stop walking.
  ; This is used for old men/hungry goriya that block walking
  ; onto their half of the screen.
ROM5:8F08 PLA
ROM5:8F09 CMP #$C
ROM5:8F0A BNE check_screen_transition
ROM5:8F0B LDA object_tile_offset_whole
ROM5:8F0C BNE ret
ROM5:8F0D LDA object_y
ROM5:8F0E CMP #$9D
ROM5:8F0F BNE check_screen_transition
ROM5:8F10 LDY #1
ROM5:8F11 LDA object_x
ROM5:8F12 CMP #$50
ROM5:8F13 BEQ loc_14F4C
ROM5:8F14 INY
ROM5:8F15 CMP #$80
ROM5:8F16 BEQ loc_14F4C
ROM5:8F17 INY
ROM5:8F18 CMP #$B0
ROM5:8F19 BNE ret
 
ROM5:8F4C loc_14F4C:
ROM5:8F4C STY var_0
ROM5:8F4D LDY #$FF
ROM5:8F4E LDA map_location
 
ROM5:8F4F find_current_location_stair_index:
ROM5:8F4F INY
ROM5:8F50 CMP ppu_data_for_current_dungeon.stairs_loc,Y
ROM5:8F51 BNE find_current_location_stair_index
ROM5:8F52 TYA
ROM5:8F53 CLC
ROM5:8F54 ADC var_0
ROM5:8F55 AND #3
ROM5:8F56 TAY
ROM5:8F57 LDA ppu_data_for_current_dungeon.stairs_loc,Y
 
ROM5:8F58 exit_cellar:
ROM5:8F58 STA map_location
ROM5:8F59 JSR mark_map_location_visited
 
ROM5:8F67 switch_to_exiting_cellar: ; Exiting a dungeon cellar, or after ExitingOverworldCellar when exiting an overworld cave.
ROM5:8F67 LDA #GameMode_ExitingCellar
ROM5:8F68 STA game_mode ; Set GameMode_ExitingCellar.
 
ROM5:8F6B clear_task_state:
ROM5:8F6B LDA #0
ROM5:8F6C STA task_state ; Set to 0
ROM5:8F6D STA active_game_mode_task ; Set to 0
ROM5:8F6E STA var_15 ; Set to 0
ROM5:8F6F STA walk_state_and_weapon_state ; Set to 0
ROM5:8F70 STA object_knockback ; Set to 0
ROM5:8F71 STA knockback_frames ; Set to 0
ROM5:8F72 STA invincibility_frames ; Set to 0
 
ROM5:8F73 ret:
ROM5:8F73 RTS
 
Function chunk for check_for_cellar_exit
ROM5:8F74 check_screen_transition:
ROM5:8F74 JSR check_if_walked_onto_screen_boundary_cellar
ROM5:8F75 LDA active_game_mode_task ; If the above call started a screen transition, it will have
  ; set active_game_mode_task to 0.
ROM5:8F76 BEQ switch_to_exiting_cellar ; Branch if we're transitioning.
ROM5:8F77 RTS
 
Subroutine check_remove_ladder
; If we're using the ladder, check if the ladder should be removed. ; In X: the object ID of the ladder.
ROM5:8F85 check_remove_ladder:
ROM5:8F85 LDX ladder_object_id ; Skip if we're not using the ladder.
ROM5:8F86 BEQ ret
ROM5:8F87 LDA walk_state_and_weapon_state,X
ROM5:8F88 BEQ remove_ladder
ROM5:8F89 LDA object_direction,X
ROM5:8F8A AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:8F8B BEQ horizontal
ROM5:8F8C LDA object_x ; If Link is moving vertically and Link's X position is different
  ; from the ladder, remove the ladder.
ROM5:8F8D CMP object_x,X
ROM5:8F8E BNE remove_ladder
ROM5:8F8F LDA object_y
ROM5:8F90 CLC
ROM5:8F91 ADC #3
ROM5:8F92 SEC
ROM5:8F93 SBC object_y,X
ROM5:8F94 JMP continue
 
ROM5:8F95 horizontal: ; If Link is moving horizontally and Link's Y position is different
ROM5:8F95 LDA object_y ; from the ladder, remove the ladder.
ROM5:8F96 CLC
ROM5:8F97 ADC #3
ROM5:8F98 CMP object_y,X
ROM5:8F99 BNE remove_ladder
ROM5:8F9A LDA object_x
ROM5:8F9B SEC
ROM5:8F9C SBC object_x,X
 
ROM5:8F9D continue: ; A = abs(A)
ROM5:8F9D JSR absolute_value
ROM5:8F9E STA var_0
ROM5:8F9F CMP #$10
ROM5:8FA0 BCC loc_14FD3
ROM5:8FA1 CMP #$10
ROM5:8FA2 BNE remove_ladder
ROM5:8FA3 LDA object_direction
ROM5:8FA4 CMP object_direction,X
ROM5:8FA5 BNE remove_ladder
ROM5:8FA6 LDA walk_state_and_weapon_state,X
ROM5:8FA7 CMP #1
ROM5:8FA8 BEQ loc_14FD7
 
ROM5:8FA9 remove_ladder:
ROM5:8FA9 LDA #0
ROM5:8FAA STA ladder_object_id ; We're no longer using the ladder.
ROM5:8FAB JSR delete_enemy ; Delete the ladder.
 
ROM5:8FAC ret:
ROM5:8FAC RTS
 
ROM5:8FD3 loc_14FD3:
ROM5:8FD3 LDA #2
ROM5:8FD4 STA walk_state_and_weapon_state,X
 
ROM5:8FD7 loc_14FD7:
ROM5:8FD7 LDA walking_directions
ROM5:8FD8 BEQ loc_1501B
ROM5:8FD9 LDA object_direction
ROM5:8FDA LDY var_0
ROM5:8FDB BEQ loc_14FE6
ROM5:8FDC CMP object_direction,X
ROM5:8FDD BEQ loc_1501B
 
ROM5:8FE6 loc_14FE6:
ROM5:8FE6 LDA object_direction,X
ROM5:8FE7 CMP var_15
ROM5:8FE8 BEQ loc_1501B
ROM5:8FE9 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM5:8FEA CMP object_direction
ROM5:8FEB BEQ loc_1501B
ROM5:8FEC CMP #4
ROM5:8FED BNE loc_15019
ROM5:8FEE LDA walking_directions
ROM5:8FEF CMP #8
ROM5:8FF0 BNE loc_15019
ROM5:8FF1 JSR sub_15029
ROM5:8FF2 LDA object_y
ROM5:8FF3 PHA
ROM5:8FF4 SEC
ROM5:8FF5 SBC #8
ROM5:8FF6 STA object_y
ROM5:8FF7 JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM5:8FF8 PLA
ROM5:8FF9 STA object_y
ROM5:8FFA LDA var_15
ROM5:8FFB LDY tile_walking_onto ; Compare to unknown_346_4
ROM5:8FFC CPY screen_first_solid_tile_id ; Compare to walking_collision_flags
ROM5:8FFD BCC loc_14FD7
 
ROM5:9019 loc_15019:
ROM5:9019 LDA #0
 
ROM5:901B loc_1501B:
ROM5:901B PHA
ROM5:901C LDX ladder_object_id
ROM5:901D JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM5:901E LDY #$C
ROM5:901F LDA #0 ; OAM attributes
ROM5:9020 JSR sub_10790C
ROM5:9021 PLA
 
Subroutine sub_15029
ROM5:9029 sub_15029:
ROM5:9029 STA var_15
ROM5:902A LDX #0
ROM5:902B RTS
 
Subroutine get_next_spawn_from_side_position
ROM5:902E get_next_spawn_from_side_position:
ROM5:902E LDA spawn_from_side_position
ROM5:902F STA var_10
 
ROM5:9033 loc_15033:
ROM5:9033 LDY #$10
ROM5:9034 LDA var_10
ROM5:9035 AND #$F
ROM5:9036 BEQ loc_15041
ROM5:9037 LDY #$F0
ROM5:9038 CMP #$F
ROM5:9039 BNE loc_15047
 
ROM5:9041 loc_15041:
ROM5:9041 TYA
ROM5:9042 CLC
ROM5:9043 ADC var_10
ROM5:9044 STA var_10
 
ROM5:9047 loc_15047:
ROM5:9047 LDA var_10
ROM5:9048 AND #$F0
ROM5:9049 CMP #$E0
ROM5:904A BNE loc_15054
ROM5:904B INC var_10
ROM5:904C JMP loc_1505A
 
ROM5:9054 loc_15054:
ROM5:9054 CMP #$40
ROM5:9055 BNE loc_1505A
ROM5:9056 DEC var_10
 
ROM5:905A loc_1505A: ; Set 16-bit var0 to room_tiles_x_00 (0x6530), which is
ROM5:905A JSR set_var0_to_current_tile_data ; the memory block holding the current room's tile data.
ROM5:905B LDA var_10
ROM5:905C AND #$F
ROM5:905D TAY
ROM5:905E BEQ loc_1506C
 
ROM5:9064 loc_15064:
ROM5:9064 LDA #$2C
ROM5:9065 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:9066 DEY
ROM5:9067 BNE loc_15064
 
ROM5:906C loc_1506C:
ROM5:906C LDA var_10
ROM5:906D AND #$F0
ROM5:906E SEC
ROM5:906F SBC #$40
ROM5:9070 LSR A
ROM5:9071 LSR A
ROM5:9072 LSR A
ROM5:9073 TAY
ROM5:9074 LDA (var_0),Y
ROM5:9075 CMP #$84
ROM5:9076 BCC loc_15084
ROM5:9077 LDA var_10
ROM5:9078 CMP spawn_from_side_position
ROM5:9079 BNE loc_15033
 
ROM5:9084 loc_15084:
ROM5:9084 LDA var_10
ROM5:9085 STA spawn_from_side_position
ROM5:9086 RTS
 
Subroutine task0_InOverworldCellar
ROM5:908A task0_InOverworldCellar:
ROM5:908A LDA task_state
ROM5:908B JSR call_jump_table
 
ROM5:908C   .WORD task0_InOverworldCellar_0 ; This is the first task0 task of InOverworldCellar, ExitingOverworldCellar, InDungeonCellar and ExitingCellar.
ROM5:908E   .WORD task0_InOverworldCellar_1
ROM5:9090   .WORD increment_task_state_and_return
ROM5:9092   .WORD task0_InOverworldCellar_3
ROM5:9094   .WORD task0_InOverworldCellar_4
ROM5:9096   .WORD task0_InOverworldCellar_5
ROM5:9098   .WORD task0_InOverworldCellar_6
ROM5:909A   .WORD task0_InOverworldCellar_7
ROM5:909C   .WORD task0_InOverworldCellar_8
 
Subroutine task0_ExitingOverworldCellar
ROM5:90A1 task0_ExitingOverworldCellar:
ROM5:90A1 LDA task_state
ROM5:90A2 JSR call_jump_table
 
ROM5:90A3   .WORD task0_InOverworldCellar_0 ; This is the first task0 task of InOverworldCellar, ExitingOverworldCellar, InDungeonCellar and ExitingCellar.
ROM5:90A5   .WORD task0_InOverworldCellar_1
ROM5:90A7   .WORD increment_task_state_and_return
ROM5:90A9   .WORD task0_ExitingOverworldCellar_3 ; This is the only state that's different from task0_InOverworldCellar, and it
  ; just sends different PPU data.
ROM5:90AB   .WORD task0_InOverworldCellar_4
ROM5:90AD   .WORD task0_InOverworldCellar_5
ROM5:90AF   .WORD task0_InOverworldCellar_6
ROM5:90B1   .WORD task0_InOverworldCellar_7
ROM5:90B3   .WORD task0_InOverworldCellar_8
 
Subroutine check_overworld_map_history
ROM5:90B8 check_overworld_map_history:
ROM5:90B8 LDY #5 ; Check each map history entry.
ROM5:90B9 LDA map_location
 
ROM5:90BA check_each_history_entry: ; Is this history entry the current screen?
ROM5:90BA CMP screen_history_0,Y
ROM5:90BB BEQ found_entry
ROM5:90BC DEY
ROM5:90BD BPL check_each_history_entry
ROM5:90BE JSR get_screen_status ; Load to check ScreenStatusOverworld_AllEnemiesKilled
ROM5:90BF AND #ScreenStatusOverworld_AllEnemiesKilled
ROM5:90C0 CMP #ScreenStatusOverworld_AllEnemiesKilled
ROM5:90C1 BNE found_entry
ROM5:90C2 LDA (var_0),Y ; Clear ScreenStatusOverworld_AllEnemiesKilled when this
  ; room is no longer in screen history.
ROM5:90C3 AND #$F8
ROM5:90C4 STA (var_0),Y
 
ROM5:90C5 ret:
ROM5:90C5 RTS
 
ROM5:90C6 found_entry: ; Load to check ScreenStatusOverworld_AllEnemiesKilled
ROM5:90C6 JSR get_screen_status
ROM5:90C7 AND #ScreenStatusOverworld_AllEnemiesKilled
ROM5:90C8 BEQ ret
ROM5:90C9 CMP #ScreenStatusOverworld_AllEnemiesKilled
ROM5:90CA BEQ no_spawn
ROM5:90CB STA var_4
ROM5:90CC LDA var_3
ROM5:90CD SEC
ROM5:90CE SBC var_4
ROM5:90CF BPL loc_150EC
 
ROM5:90D0 no_spawn:
ROM5:90D0 LDA #0
ROM5:90D1 STA var_2
 
ROM5:90EC loc_150EC:
ROM5:90EC STA var_3
ROM5:90ED RTS
 
Subroutine update_overworld_screen_kill_count
ROM5:90EF update_overworld_screen_kill_count:
ROM5:90EF JSR get_screen_status ; Out Y = map location
  ; Out A = screen status for the current screen
  ; Out var_0 = pointer to screen status for this dungeon
  ; Bits 0x0F (dungeons): direction mask for bombed/opened doors
  ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM5:90F0 AND #7 ; Mask off the number of killed enemies
ROM5:90F1 STA var_2 ; Store the number of killed enemies
ROM5:90F2 LDA (var_0),Y ; var_0 still points to the screen status from the above
  ; call to get_map_info.
ROM5:90F3 AND #$F8 ; Mask off everything but the stored kill counter.
ROM5:90F4 STA (var_0),Y ; Store the masked value. This sets the kill count to 0
  ; until we replace it below.
ROM5:90F5 LDA object_type ; Load the number of enemies killed on the current screen.
  ; This doesn't include enemies killed on previous visits
  ; to the screen.
ROM5:90F6 CMP total_enemies_spawned_in_room
ROM5:90F7 BCS loc_1510D ; Branch if enemies killed > enemies number spawned
ROM5:90F8 AND #7
ROM5:90F9 CLC
ROM5:90FA ADC var_2 ; Add enemies killed + previous enemies killed
ROM5:90FB CMP #7
ROM5:90FC BCC loc_1510F ; If < 7, skip assigning 7. If >= 7, clamp to 7.
 
ROM5:910D loc_1510D: ; We either killed all enemies or we killed more than 7.
ROM5:910D LDA #7 ; Clamp to 7.
 
ROM5:910F loc_1510F: ; OR the rest of the screen status (0xF8) back into the
ROM5:910F ORA (0),Y ; value we'll assign below.
ROM5:9110 STA (0),Y ; Update the low 3 bits of the screen status, which is
  ; the number of enemies killed on that screen or 0x7 if
  ; all enemies were killed.
ROM5:9111 RTS
 
Subroutine task0_InDungeonCellar
ROM5:9114 task0_InDungeonCellar:
ROM5:9114 LDA task_state
ROM5:9115 JSR call_jump_table
 
ROM5:9116   .WORD task0_InOverworldCellar_0 ; This is the first task0 task of InOverworldCellar, ExitingOverworldCellar, InDungeonCellar and ExitingCellar.
ROM5:9118   .WORD task0_InDungeonCellar_1
ROM5:911A   .WORD task0_InDungeonCellar_2
ROM5:911C   .WORD task0_InDungeonCellar_3
ROM5:911E   .WORD task0_InOverworldCellar_4
ROM5:9120   .WORD task0_InDungeonCellar_5
ROM5:9122   .WORD task0_InDungeonCellar_6
ROM5:9124   .WORD task0_InDungeonCellar_2
ROM5:9126   .WORD task0_InDungeonCellar_8
ROM5:9128   .WORD task0_InDungeonCellar_9
 
ROM5:912A   .BYTE $A0
ROM5:912B   .BYTE 0
ROM5:912C   .BYTE $F0
ROM5:912D   .BYTE 2
ROM5:912E   .BYTE $A0
ROM5:912F   .BYTE 1
ROM5:9130   .BYTE $84
ROM5:9131   .BYTE $C
ROM5:9132   .BYTE $BC
ROM5:9133   .BYTE $4F
ROM5:9134   .BYTE 3
ROM5:9135   .BYTE $C8
ROM5:9136   .BYTE $85
ROM5:9137   .BYTE $D
ROM5:9138   .BYTE $84
ROM5:9139   .BYTE $E
ROM5:913A   .BYTE $86
ROM5:913B   .BYTE 8
ROM5:913C   .BYTE $A9
ROM5:913D   .BYTE $40
ROM5:913E   .BYTE $8D
ROM5:913F   .BYTE $43
ROM5:9140   .BYTE 3
ROM5:9141   .BYTE $A9
ROM5:9142   .BYTE $44
ROM5:9143   .BYTE $4C
ROM5:9144   .BYTE 4
ROM5:9145   .BYTE $78
 
Subroutine lock_movement_to_dungeon_door
; Adjust the player's walking_directions when standing in ; a dungeon door. If we're in a left/right door, pressing left ; moves left (even if up or down are also pressed), right ; moves right, and pressing up or down alone keeps moving in ; the direction we're already facing.
ROM5:9149 lock_movement_to_dungeon_door:
ROM5:9149 LDA in_dungeon_door ; Skip if we're not standing in a dungeon door.
ROM5:914A BEQ ret
ROM5:914B LDY walking_directions ; Skip if the player isn't holding any directions.
  ; This is a bitmask that contains the directions the player is pressing.
ROM5:914C BEQ ret
ROM5:914D LDA object_direction
ROM5:914E AND walking_directions ; A = object_direction & walking_directions
 
  ; This gives us the direction the player is facing, if he's
  ; holding the controller in that direction. For example, if
  ; the player is facing right, and holding up-right, this gives
  ; right. If the player is facing right and holding left, this
  ; gives 0.
ROM5:914F BNE not_walking ; Branch if the facing direction and controller direction
  ; overlap. We'll store the overlapped direction as the
  ; walking direction: if the player is holding up-right while
  ; facing right in a dungeon door, he'll keep moving right and
  ; the up press will be ignored.
ROM5:9150 LDA object_direction ; We're changing direction while in a dungeon door.
ROM5:9151 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM5:9152 AND walking_directions ; Do the same, comparing the opposite direction to the
  ; controller input. If the player is facing right, and
  ; holding up-left, this gives left.
ROM5:9153 BNE not_walking ; Branch if the opposite of the facing direction overlaps
  ; the controller direction.
ROM5:9154 LDA object_direction ; Otherwise, store the current facing direction as the
  ; walking direction. This way, pressing up or down while
  ; in a left/right door continues moving you in the direction
  ; you're facing, instead of stopping.
 
ROM5:9155 not_walking:
ROM5:9155 STA walking_directions
 
ROM5:9156 ret:
ROM5:9156 RTS
 
ROM5:9157   .BYTE $A9
ROM5:9158   .BYTE $F8
ROM5:9159   .BYTE $8D
ROM5:915A   .BYTE $40
ROM5:915B   .BYTE 2
ROM5:915C   .BYTE $8D
ROM5:915D   .BYTE $44
ROM5:915E   .BYTE 2
ROM5:915F   .BYTE $60
ROM5:9172 door_x_center: .BYTE $78
ROM5:9173   .BYTE $78
ROM5:9174   .BYTE $8D
ROM5:9175   .BYTE $8D
ROM5:9176 door_y_top: .BYTE $3D
ROM5:9177   .BYTE $BD
ROM5:9178   .BYTE 0
ROM5:9179   .BYTE $CF
ROM5:917A door_y_bottom: .BYTE $5E
ROM5:917B   .BYTE $DE
ROM5:917C   .BYTE $21
ROM5:917D   .BYTE $F1
ROM5:917E door_y_top_while_inside: .BYTE $3D
ROM5:917F   .BYTE $BF
ROM5:9180   .BYTE 0
ROM5:9181   .BYTE $D2
ROM5:9182 door_y_bottom_while_inside: .BYTE $5C
ROM5:9183   .BYTE $DE
ROM5:9184   .BYTE $1F
ROM5:9185   .BYTE $F1
 
Subroutine check_door_entry
; Check entering dungeon doors. This handles locking movement ; to doors, and triggering the bomb door and push screen ; transitions.
ROM5:9186 check_door_entry:
ROM5:9186 LDA in_dungeon_door ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
ROM5:9187 BNE currently_in_dungeon_door
 
ROM5:9188 facing_inside_door:
ROM5:9188 LDA object_direction
ROM5:9189 JSR get_movement_position ; A is a movement direction. Get Link's position in var_0 and var_1. If A is horizontal, swap X and Y.
ROM5:918A LDY #3 ; Loop over each door
 
ROM5:918B door_loop1: ; Link's X position (if moving vertically)
ROM5:918B LDA var_0
ROM5:918C CMP door_x_center,Y ; Check if we're lined up horizontally with the door
ROM5:918D BNE check_next_door1
ROM5:918E LDA var_1 ; Link's Y position (if moving vertically)
ROM5:918F CMP door_y_top,Y ; Check if we're between top < position < bottom
ROM5:9190 BCC check_next_door1
ROM5:9191 CMP door_y_bottom,Y
ROM5:9192 BCC inside_door
 
ROM5:9193 check_next_door1:
ROM5:9193 DEY
ROM5:9194 BPL door_loop1
 
ROM5:9195 not_inside_door: ; We're not inside any door. Clear in_dungeon_door, so we don't lock movement to a door.
ROM5:9195 LDA #0
ROM5:9196 STA in_dungeon_door ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
ROM5:9197 RTS
 
ROM5:9198 currently_in_dungeon_door: ; Push A (in_dungeon_door)
ROM5:9198 PHA
ROM5:9199 JSR get_movement_position ; A is a movement direction. Get Link's position in var_0 and var_1. If A is horizontal, swap X and Y.
ROM5:919A PLA
ROM5:919B JSR get_opposite_direction_and_index ; Get the door index that we're inside.
ROM5:919C LDA var_1 ; Link's Y position (if moving vertically)
ROM5:919D CMP door_y_top,Y ; Check if we're still inside that door.
ROM5:919E BCC no_longer_inside_door
ROM5:919F CMP door_y_bottom,Y
ROM5:91A0 BCS no_longer_inside_door
ROM5:91A1 LDA in_dungeon_door ; Check if we're facing in the direction of the door we're locked to.
ROM5:91A2 CMP object_direction
ROM5:91A3 BEQ facing_inside_door ; Branch to the basic test if we're facing in the door we're locked to.
 
ROM5:91A4 no_longer_inside_door: ; We're facing out of the door we entered. Check against an alternate
ROM5:91A4 LDY #3 ; list of door sizes. This seems to give a bit of hysteresis to door entry,
  ; so turning around in a door will keep you stuck on the door a little longer.
 
ROM5:91A5 door_loop2: ; Link's X position (if moving vertically)
ROM5:91A5 LDA var_0
ROM5:91A6 CMP door_x_center,Y ; Check if we're lined up horizontally with the door
ROM5:91A7 BNE check_next_door2
ROM5:91A8 LDA var_1 ; Link's Y position (if moving vertically)
ROM5:91A9 CMP door_y_top_while_inside,Y ; Check if we're between top < position < bottom
ROM5:91AA BCC check_next_door2
ROM5:91AB CMP door_y_bottom_while_inside,Y
ROM5:91AC BCC inside_door
 
ROM5:91AD check_next_door2:
ROM5:91AD DEY
ROM5:91AE BPL door_loop2
ROM5:91AF BMI not_inside_door ; We're not inside any door.
 
ROM5:91B0 inside_door: ; Save the door index we're inside.
ROM5:91B0 STY var_14
ROM5:91B1 LDA walking_directions
ROM5:91B2 AND #$F
ROM5:91B3 STA var_2 ; Set to walking_directions
ROM5:91B4 STA var_12 ; Set to walking_directions
ROM5:91B5 CMP walking_bits_2,Y
ROM5:91B6 BNE locret_15215
ROM5:91B7 JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:91B8 STA var_13 ; Set to dungeon door type
ROM5:91B9 JSR check_door ; On entry, var_2 and var_12 are Link's walking_directions, and var_13 is the
  ; current dungeon room's door type.
 
  ; On return, var_14 is set to 0xFF if this door is unpassable.
ROM5:91BA LDY var_14
ROM5:91BB BMI locret_15215 ; Stop if we can't pass through this door.
ROM5:91BC LDA walking_bits_2,Y ; Lock movement into dungeon doors
ROM5:91BD STA object_direction
ROM5:91BE STA var_15
ROM5:91BF STA in_dungeon_door ; Set to our movement direction when inside dungeon doors
ROM5:91C0 LDA var_13 ; Reload the door type.
ROM5:91C1 AND #7
ROM5:91C2 CMP #DungeonDoor_Push ; These doors force entry as soon as they're walked into,
  ; instead of acting like a floor.
ROM5:91C3 BEQ start_door_transition_thunk
ROM5:91C4 CMP #DungeonDoor_PushSilent
ROM5:91C5 BEQ start_door_transition_thunk
ROM5:91C6 CMP #DungeonDoor_BombWall
ROM5:91C7 BEQ start_door_transition_thunk
 
ROM5:9215 locret_15215:
ROM5:9215 RTS
 
ROM5:9216 start_door_transition_thunk:
ROM5:9216 JMP start_GameMode_PrepareScroll
 
Subroutine get_movement_position
; A is a movement direction. Get Link's position in var_0 and var_1. If A is horizontal, swap X and Y.
ROM5:9219 get_movement_position:
ROM5:9219 LDX object_x
ROM5:921A LDY object_y ; We're walking vertically. var_0 = object X, var_1 = object Y
ROM5:921B AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM5:921C BEQ vertical
ROM5:921D LDY object_x ; We're walking horizontally. Swap X and Y.
ROM5:921E LDX object_y
 
ROM5:921F vertical:
ROM5:921F STX var_0
ROM5:9220 STY var_1
ROM5:9221 RTS
 
Subroutine check_door
; On entry, var_2 and var_12 are Link's walking_directions, and var_13 is the ; current dungeon room's door type. ; ; On return, var_14 is set to 0xFF if this door is unpassable.
ROM5:922A check_door:
ROM5:922A AND #7
ROM5:922B JSR call_jump_table
 
ROM5:922C   .WORD handle_door_Door ; DungeonDoor_Door
ROM5:922E   .WORD handle_door_Wall ; DungeonDoor_Wall
ROM5:9230   .WORD handle_door_Push ; DungeonDoor_Push
ROM5:9232   .WORD handle_door_Push ; DungeonDoor_PushSilent
ROM5:9234   .WORD handle_door_Bomb ; DungeonDoor_BombWall
ROM5:9236   .WORD handle_door_LockedDoor ; DungeonDoor_LockedDoor
ROM5:9238   .WORD handle_door_LockedDoor ; DungeonDoor_LockedDoor2
ROM5:923A   .WORD handle_door_ShutterDoor ; DungeonDoor_ShutterDoor
 
Subroutine handle_door_Wall
ROM5:923F handle_door_Wall:
ROM5:923F LDY #$FF
ROM5:9240 STY var_14
 
ROM5:9243 handle_door_Door:
ROM5:9243 RTS
 
Subroutine handle_door_Push
ROM5:9244 handle_door_Push:
ROM5:9244 LDA enemy_action_timers
ROM5:9245 BEQ start_pushing
ROM5:9246 CMP #1
ROM5:9247 BNE keep_pushing
ROM5:9248 RTS
 
ROM5:9249 start_pushing: ; Push a push door for 24 frames to pass
ROM5:9249 LDA #24
ROM5:924A STA enemy_action_timers
 
ROM5:924B keep_pushing:
ROM5:924B JMP handle_door_Wall
 
ROM5:9254 handle_door_Bomb:
ROM5:9254 LDA var_12
ROM5:9255 AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:9256 BEQ handle_door_Wall
ROM5:9257 RTS
 
Subroutine handle_door_ShutterDoor
ROM5:925B handle_door_ShutterDoor:
ROM5:925B LDA byte_54 ; Treat shutter doors as walls if this is already set.
ROM5:925C BNE handle_door_Wall
ROM5:925D LDA var_12 ; var_12 is Link's facing direction.
ROM5:925E AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:925F BEQ handle_door_Wall ; If Link's direction mask is 0 in unlocked_door_directions,
  ; this door isn't open. Treat this as a wall.
ROM5:9260 AND shutter_doors_entered ; A mask of shutter doors on the current screen that Link has walked into since he entered the screen.
ROM5:9261 BEQ add_to_shutter_doors_entered
ROM5:9262 BNE allow_entering_door_if_enemy_action_timer_expired ; Always branch
 
ROM5:9263 add_to_shutter_doors_entered: ; Add this direction mask to shutter_doors_entered.
ROM5:9263 LDA shutter_doors_entered
  ; It's not clear what this does. It seems to just delay allowing
  ; walking into a shutter door for one frame the first time you walk
  ; into it.
ROM5:9264 ORA var_12
ROM5:9265 STA shutter_doors_entered ; A mask of shutter doors on the current screen that Link has walked into since he entered the screen.
ROM5:9266 RTS
 
ROM5:9275 handle_door_LockedDoor: ; var_12 is Link's walking_directions.
ROM5:9275 LDA var_12
ROM5:9276 AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:9277 BNE ret
ROM5:9278 LDA byte_54 ; Allow entering locked doors without using a key if this
  ; is set. What does this do? This isn't related to the magical
  ; key.
ROM5:9279 BNE allow_entering_door_if_enemy_action_timer_expired
ROM5:927A LDA have_magic_key ; Skip checking keys if we have the magic key.
ROM5:927B BNE has_magic_key
ROM5:927C LDA num_keys ; Check if we have a key to use.
ROM5:927D BEQ no_keys
ROM5:927E DEC num_keys ; Use a key
 
ROM5:927F has_magic_key: ; Set A to Link's walking direction.
ROM5:927F LDA var_12
ROM5:9280 JSR start_opening_key_or_bomb_door
ROM5:9281 LDA #32 ; Delay opening the door by 32 frames. Until then,
  ; treat this like a wall and return it as unpassable.
ROM5:9282 STA enemy_action_timers
 
ROM5:9283 no_keys:
ROM5:9283 JMP handle_door_Wall
 
ROM5:9284 allow_entering_door_if_enemy_action_timer_expired:
ROM5:9284 LDA enemy_action_timers
ROM5:9285 BNE no_keys
 
ROM5:9286 ret:
ROM5:9286 RTS
 
Subroutine sub_1529D
; This is only called in dungeons.
ROM5:929D sub_1529D:
ROM5:929D LDY #5
ROM5:929E LDA map_location
 
ROM5:929F loop:
ROM5:929F CMP screen_history_0,Y
ROM5:92A0 BEQ screen_in_history
ROM5:92A1 DEY
ROM5:92A2 BPL loop
ROM5:92A3 JSR get_screen_status ; Load to check ScreenStatusDungeon_AllEnemiesKilled.
ROM5:92A4 AND #ScreenStatusDungeon_AllEnemiesKilled
ROM5:92A5 CMP #ScreenStatusDungeon_AllEnemiesKilled
ROM5:92A6 BNE screen_in_history
ROM5:92A7 LDA var_2 ; Enemy code for this room
ROM5:92A8 CMP #ObjectType_DodongoBoss
ROM5:92A9 BCC loc_152C4
ROM5:92AA CMP #ObjectType_RedLanmola
ROM5:92AB BEQ loc_152C4
ROM5:92AC CMP #ObjectType_BlueLanmola
ROM5:92AD BEQ loc_152C4
ROM5:92AE CMP #ObjectType_WallTrap_Vert
ROM5:92AF BCC spawn_zero_enemies
 
ROM5:92C4 loc_152C4: ; A < ObjectType_DodongoBoss, A >= ObjectType_WallTrap_Horiz
ROM5:92C4 LDA (var_0),Y ; or a Lanmola
ROM5:92C5 AND #$3F
ROM5:92C6 STA (var_0),Y
ROM5:92C7 LDA #0
ROM5:92C8 STA number_of_enemies_killed_in_dungeon_room,Y ; Set to 0
ROM5:92C9 RTS
 
ROM5:92CA screen_in_history:
ROM5:92CA LDY map_location
ROM5:92CB LDA var_3 ; Load the number of enemy spawned in this room
ROM5:92CC SEC
ROM5:92CD SBC number_of_enemies_killed_in_dungeon_room,Y ; Subtract the number previously killed
ROM5:92CE BPL ret ; Branch if spawned - killed > 0
 
ROM5:92CF spawn_zero_enemies:
ROM5:92CF LDA #0
ROM5:92D0 STA var_2 ; Set to 0
 
ROM5:92D1 ret: ; Store the number of enemies remaining in this room
ROM5:92D1 STA var_3 ; (number to spawn minus the number previously killed)
ROM5:92D2 RTS
 
Subroutine update_dungeon_screen_kill_count
ROM5:92E1 update_dungeon_screen_kill_count:
ROM5:92E1 JSR get_screen_status ; Load to clear and update ScreenStatusDungeon_AllEnemiesKilled.
ROM5:92E2 AND #$3F ; Clear the kill counter for this room, leaving the other
  ; bits. We'll update the counter below.
ROM5:92E3 STA (var_0),Y
ROM5:92E4 LDA total_enemies_spawned_in_room
ROM5:92E5 BEQ store_all_enemies_killed ; branch if no enemies spawned
ROM5:92E6 LDA object_type
ROM5:92E7 BEQ update_counted_kills ; branch if no enemies killed
ROM5:92E8 LDY first_object_type ; The first object type on the screen at screen load time. This is only set in dungeons.
ROM5:92E9 CPY #ObjectType_DodongoBoss
ROM5:92EA BCC update_counted_kills ; A < ObjectType_DodongoBoss
ROM5:92EB CPY #ObjectType_RedLanmola
ROM5:92EC BEQ update_counted_kills ; A = number of enemies killed, compare to total_enemies_spawned_in_room
ROM5:92ED CPY #ObjectType_BlueLanmola
ROM5:92EE BEQ update_counted_kills ; A = number of enemies killed, compare to total_enemies_spawned_in_room
ROM5:92EF CPY #ObjectType_WallTrap_Vert
ROM5:92F0 BCC store_all_enemies_killed ; A < ObjectType_WallTrap_Vert
 
  ; Y < ObjectType_DodongoBoss || Lanmola || >= ObjectType_WallTrap_Vert
 
ROM5:92F1 update_counted_kills: ; A = number of enemies killed, compare to total_enemies_spawned_in_room
ROM5:92F1 CMP total_enemies_spawned_in_room
ROM5:92F2 BCS store_all_enemies_killed ; Branch if number killed >= number spawned
ROM5:92F3 LDY map_location
ROM5:92F4 CLC
ROM5:92F5 ADC number_of_enemies_killed_in_dungeon_room,Y ; Add the previous kill counter to the number killed this screen.
 
  ; number_of_enemies_killed_in_dungeon_room tracks the total
  ; enemies killed on the screen. The screen status that we
  ; store below only stores two bits and clamps at 2, and is
  ; set to 3 (0xC0) when all enemies have been killed.
ROM5:92F6 STA number_of_enemies_killed_in_dungeon_room,Y
ROM5:92F7 CMP #3
ROM5:92F8 BCC less_than_3 ; A < 3
ROM5:92F9 LDA #2 ; Clamp to 2. 3 means "all enemies killed" (ScreenStatusDungeon_AllEnemiesKilled)
 
ROM5:92FA less_than_3:
ROM5:92FA CLC
ROM5:92FB ROR A ; Shift the result into the top 2 bits (first shift is into carry)
ROM5:92FC ROR A
ROM5:92FD ROR A
ROM5:92FE JMP store ; Store A as the number of enemies killed in this room.
 
ROM5:92FF store_all_enemies_killed:
ROM5:92FF LDY map_location
ROM5:9300 LDA #$F
ROM5:9301 STA number_of_enemies_killed_in_dungeon_room,Y
ROM5:9302 LDA #ScreenStatusDungeon_AllEnemiesKilled
 
ROM5:9303 store: ; Store A as the number of enemies killed in this room.
ROM5:9303 ORA (var_0),Y
ROM5:9304 STA (var_0),Y
ROM5:9305 RTS
 
ROM5:932E boss_roar_sounds: .BYTE 0
ROM5:932F   .BYTE Sound0_BossRoar1
ROM5:9330   .BYTE Sound0_BossRoar2
ROM5:9331   .BYTE Sound0_BossRoar3
 
Subroutine check_boss_roar
ROM5:9332 check_boss_roar:
ROM5:9332 JSR get_screen_status ; Load to check ScreenStatusDungeon_AllEnemiesKilled.
ROM5:9333 LDY ppu_data_for_current_dungeon.boss_loc
ROM5:9334 LDA (var_0),Y
ROM5:9335 AND #ScreenStatusDungeon_AllEnemiesKilled
ROM5:9336 CMP #ScreenStatusDungeon_AllEnemiesKilled
ROM5:9337 BEQ no_boss_roar
ROM5:9338 LDY map_location
ROM5:9339 LDA dungeon_screen_data_4,Y ; Check if this room plays a boss sound.
ROM5:933A AND #ScreenData_Dungeon_4_PlayBossSound1|ScreenData_Dungeon_4_PlayBossSound2
ROM5:933B ASL A ; Shift boss roar bits to 0x3
ROM5:933C ROL A
ROM5:933D ROL A
ROM5:933E ROL A
ROM5:933F TAX ; Boss roar is now 0-3
ROM5:9340 LDA boss_roar_sounds,X
ROM5:9341 BEQ no_boss_roar ; Jump if no boss roar
ROM5:9342 ORA #$80 ; Play Sound0_BossRoar*
ROM5:9343 STA play_sound_0 ; Set to a nonzero value to play a one-off sound effect (this can also start the boss roar loop)
ROM5:9344 RTS
 
ROM5:9345 no_boss_roar: ; Set play_sound |= 0x80 to stop boss roar
ROM5:9345 LDA #Sound2_StopBossRoar
ROM5:9346 JMP add_play_sound_2 ; Play a sound on play_sound_2. A is the mask of the sound to play.
 
ROM5:9347 Skipped empty chunk
Subroutine copy_door_or_bomb_sprite_data
ROM5:9400 copy_door_or_bomb_sprite_data:
ROM5:9400 LDY var_9
ROM5:9401 LDA byte_165E3,Y
ROM5:9402 CLC
ROM5:9403 ADC var_7
ROM5:9404 TAY
ROM5:9405 LDA byte_165D5,Y
ROM5:9406 TAY
ROM5:9407 LDA (var_2),Y ; Copy the sprite value
ROM5:9408 STA ppu_command_buffer,X
ROM5:9409 INX
ROM5:940A INC var_7
ROM5:940B DEC var_4
ROM5:940C RTS
 
ROM5:940D
ROM5:9BA8 cellar_ppu_data_0: .BYTE 0
ROM5:9BA9   .BYTE 0
ROM5:9BAA   .BYTE $95
ROM5:9BAB   .BYTE $95
ROM5:9BAC   .BYTE $95
ROM5:9BAD   .BYTE $95
ROM5:9BAE   .BYTE $95
ROM5:9BAF   .BYTE $C2
ROM5:9BB0   .BYTE $C2
ROM5:9BB1   .BYTE $95
ROM5:9BB2   .BYTE $95
ROM5:9BB3   .BYTE $95
ROM5:9BB4   .BYTE $95
ROM5:9BB5   .BYTE $95
ROM5:9BB6   .BYTE 0
ROM5:9BB7   .BYTE 0
ROM5:9BB8 cellar_ppu_data_1:
ROM5:9F9C byte_15F9C: .BYTE $18
ROM5:9F9D byte_15F9D: .BYTE $94
ROM5:9F9E byte_15F9E: .BYTE $D8
ROM5:9F9F byte_15F9F: .BYTE $9B
ROM5:9FA0
ROM5:A3B4 cellar_ppu_data_2: .BYTE 4
ROM5:A3B5   .BYTE 4
ROM5:A3B6   .BYTE 0
ROM5:A3B7   .BYTE 1
ROM5:A3B8   .BYTE 0
ROM5:A3B9   .BYTE 0
ROM5:A3BA   .BYTE 0
ROM5:A3BB   .BYTE 0
ROM5:A3BC   .BYTE 0
ROM5:A3BD   .BYTE 0
ROM5:A3BE   .BYTE 0
ROM5:A3BF   .BYTE 0
ROM5:A3C0   .BYTE 1
ROM5:A3C1   .BYTE 0
ROM5:A3C2   .BYTE 4
ROM5:A3C3   .BYTE 4
ROM5:A3C4 cellar_ppu_data_3: .BYTE 4
ROM5:A3C5   .BYTE 4
ROM5:A3C6   .BYTE 0
ROM5:A3C7   .BYTE 1
ROM5:A3C8   .BYTE 0
ROM5:A3C9   .BYTE 0
ROM5:A3CA   .BYTE 0
ROM5:A3CB   .BYTE 3
ROM5:A3CC   .BYTE 3
ROM5:A3CD   .BYTE 3
ROM5:A3CE   .BYTE 3
ROM5:A3CF   .BYTE 2
ROM5:A3D0   .BYTE 3
ROM5:A3D1   .BYTE 3
ROM5:A3D2   .BYTE 4
ROM5:A3D3   .BYTE 4
ROM5:A3D4   .BYTE $82
ROM5:A3D5   .BYTE $43
ROM5:A3D6   .BYTE $43
ROM5:A3D7   .BYTE $43
ROM5:A3D8   .BYTE 2
ROM5:A3D9   .BYTE $C
ROM5:A3DA   .BYTE $43
ROM5:A3DB   .BYTE $80
ROM5:A3DC   .BYTE $41
ROM5:A3DD   .BYTE $41
ROM5:A3DE   .BYTE $41
ROM5:A3DF   .BYTE $41
ROM5:A3E0   .BYTE $43
ROM5:A3E1   .BYTE $82
ROM5:A3E2   .BYTE $43
ROM5:A3E3   .BYTE $42
ROM5:A3E4   .BYTE $C
ROM5:A3E5   .BYTE 1
ROM5:A3E6   .BYTE $41
ROM5:A3E7   .BYTE $43
ROM5:A3E8   .BYTE $82
ROM5:A3E9   .BYTE $43
ROM5:A3EA   .BYTE $42
ROM5:A3EB   .BYTE $C
ROM5:A3EC   .BYTE 3
ROM5:A3ED   .BYTE 2
ROM5:A3EE   .BYTE $C
ROM5:A3EF   .BYTE $43
ROM5:A3F0   .BYTE $82
ROM5:A3F1   .BYTE $43
ROM5:A3F2   .BYTE $43
ROM5:A3F3   .BYTE $43
ROM5:A3F4   .BYTE $43
ROM5:A3F5   .BYTE $43
 
Subroutine get_dungeon_door_type
; Set A to the door type we're facing. ; ; In var_2: a bitmask for the directions the caller wants.
ROM5:A3F6 get_dungeon_door_type:
ROM5:A3F6 LDA #1
ROM5:A3F7 STA var_1 ; Set to 1
ROM5:A3F8 LDA #3
ROM5:A3F9 STA var_3 ; Set to 3 to test each direction.
 
ROM5:A3FA loop:
ROM5:A3FA LDY map_location
ROM5:A3FB LDA dungeon_screen_data_0,Y ; Table 0 has the top/bottom dungeon door type flags.
ROM5:A3FC LDY var_3
ROM5:A3FD CPY #2
ROM5:A3FE BCC skip1 ; Branch if Y = 0 or 1 to test top or bottom.
ROM5:A3FF LDY map_location
ROM5:A400 LDA dungeon_screen_data_1,Y ; Table 1 has the left/right dungeon door type flags.
 
ROM5:A401 skip1: ; Store the dungeon door type flag we're testing.
ROM5:A401 STA var_0
ROM5:A402 LDA var_3 ; Load the direction we're testing.
ROM5:A403 AND #1
ROM5:A404 BNE not_top_or_left
ROM5:A405 LSR var_0 ; We're testing the top or left wall. Shift right by 3
  ; to shift 0b11100000 to 0b00011100.
ROM5:A406 LSR var_0
ROM5:A407 LSR var_0
 
ROM5:A408 not_top_or_left: ; Shift right by 2 to shift 0b00011100 to 0b00000111.
ROM5:A408 LSR var_0
ROM5:A409 LSR var_0
ROM5:A40A LDA var_2 ; var_1 is the bit for the direction we're testing.
  ; var_2 is the bitmask for the directions the caller wants,
  ; using bits from walking_bits_2.
ROM5:A40B BIT var_1
ROM5:A40C BNE ret ; If var_1 & var_2, return.
ROM5:A40D ASL var_1 ; var_1 <<= 1
ROM5:A40E DEC var_3 ; var_3--
ROM5:A40F BPL loop
ROM5:A410 LDA #8
ROM5:A411 RTS
 
ROM5:A412 ret:
ROM5:A412 LDA var_0
ROM5:A413 AND #7
ROM5:A414 RTS
 
Subroutine sub_16434
ROM5:A434 sub_16434:
ROM5:A434 LDA #$13
ROM5:A435 STA var_6
ROM5:A436 LDX #$19
ROM5:A437 BNE loc_16484
 
ROM5:A43C loc_1643C:
ROM5:A43C JSR decrement_16bit_var4_by_1
ROM5:A43D JMP loc_1648E
 
ROM5:A442 loc_16442: ; var_0 = 0x9FA0
ROM5:A442 LDA #$A0
ROM5:A443 STA var_0
ROM5:A444 LDA #$9F
ROM5:A445 STA var_1
ROM5:A446 LDA #$47 ; var_2 = 0x6547
ROM5:A447 STA var_2
ROM5:A448 LDA #$65
ROM5:A449 STA var_3
ROM5:A44A LDA #$5A ; var_4 = 0x655A
ROM5:A44B STA var_4
ROM5:A44C LDA #$65
ROM5:A44D STA var_5
ROM5:A44E LDA #$A
ROM5:A44F STA var_6 ; var_6 = 0
ROM5:A450 LDY #0
 
ROM5:A460 loc_16460:
ROM5:A460 LDA (var_0),Y
ROM5:A461 BEQ sub_16434
ROM5:A462 STA (var_2),Y
ROM5:A463 STA (var_4),Y
ROM5:A464 CMP #$DE
ROM5:A465 BEQ loc_16474
ROM5:A466 CMP #$E2
ROM5:A467 BCS loc_16474
ROM5:A468 ADC #1
ROM5:A469 STA (var_4),Y
 
ROM5:A474 loc_16474:
ROM5:A474 LDA #1
ROM5:A475 LDX #1
ROM5:A476 DEC 6 ; Dungeon 3
ROM5:A477 BNE loc_16484
ROM5:A478 LDA #$A
ROM5:A479 STA var_6
ROM5:A47A LDA #$D
ROM5:A47B LDX #$1F
 
ROM5:A484 loc_16484: ; 16-bit var2 += A
ROM5:A484 JSR increment_16bit_var2_by_A
ROM5:A485 TXA
ROM5:A486 DEX
ROM5:A487 BEQ loc_1643C
ROM5:A488 JSR increment_16bit_var4_by_A ; 16-bit var4 += A
 
ROM5:A48E loc_1648E: ; 16-bit var0++
ROM5:A48E JSR increment_16bit_var0_by_1
ROM5:A48F CMP #$EE
ROM5:A490 BNE loc_16460
ROM5:A491 LDA #$30 ; var_2 = 0x6530
ROM5:A492 STA var_2
ROM5:A493 LDA #$65
ROM5:A494 STA var_3
ROM5:A495 LDA #$EF ; var_4 = 0x67EF
ROM5:A496 STA var_4
ROM5:A497 LDA #$67
ROM5:A498 STA var_5
 
ROM5:A4A5 loc_164A5:
ROM5:A4A5 LDA (var_2),Y
ROM5:A4A6 STA (var_4),Y
ROM5:A4A7 CMP #$DD
ROM5:A4A8 BEQ loc_164CF
ROM5:A4A9 CMP #$E0
ROM5:A4AA BCS loc_164BE
ROM5:A4AB CMP #$DC
ROM5:A4AC BCS loc_164B9
ROM5:A4AD ADC #1
ROM5:A4AE STA (4),Y
 
ROM5:A4B9 loc_164B9:
ROM5:A4B9 CLC
ROM5:A4BA ADC #1
 
ROM5:A4BC loc_164BC:
ROM5:A4BC STA (var_4),Y
 
ROM5:A4BE loc_164BE:
ROM5:A4BE JSR decrement_16bit_var4_by_1
ROM5:A4BF JSR increment_16bit_var2_by_1 ; 16-bit var2++
ROM5:A4C0 CMP #$90
ROM5:A4C1 BNE loc_164A5
ROM5:A4C2 LDA var_3
ROM5:A4C3 CMP #$66
ROM5:A4C4 BNE loc_164A5
ROM5:A4C5 RTS
 
ROM5:A4CF loc_164CF:
ROM5:A4CF LDA #$DC
ROM5:A4D0 BNE loc_164BC ; Always branch
 
ROM5:A4D3 byte_164D3: .BYTE 1
ROM5:A4D4   .BYTE 2
ROM5:A4D5   .BYTE 4
ROM5:A4D6   .BYTE 8
ROM5:A4D7 door_sprite_ptr_low: .BYTE $EE ; 9FEE
ROM5:A4D8   .BYTE $2A ; A02A
ROM5:A4D9   .BYTE $66 ; A066
ROM5:A4DA   .BYTE $A2 ; A0A2
ROM5:A4DB door_sprite_ptr_high: .BYTE $9F
ROM5:A4DC   .BYTE $A0
ROM5:A4DD   .BYTE $A0
ROM5:A4DE   .BYTE $A0
ROM5:A4DF byte_164DF: .BYTE $A1 ; 67A1
ROM5:A4E0   .BYTE $4F ; 654F
ROM5:A4E1   .BYTE $76 ; 6676
ROM5:A4E2   .BYTE $65 ; 6665
ROM5:A4E3 byte_164E3: .BYTE $67
ROM5:A4E4   .BYTE $65
ROM5:A4E5   .BYTE $66
ROM5:A4E6   .BYTE $66
ROM5:A4E7 byte_164E7: .BYTE $14
ROM5:A4E8   .BYTE 1
ROM5:A4E9   .BYTE 1
ROM5:A4EA byte_164EA: .BYTE 2
ROM5:A4EB   .BYTE 2
ROM5:A4EC   .BYTE $2C
ROM5:A4ED   .BYTE $2C
ROM5:A4EE byte_164EE: .BYTE 3
ROM5:A4EF   .BYTE 3
ROM5:A4F0   .BYTE 2
ROM5:A4F1   .BYTE 2
ROM5:A4F2 byte_164F2: .BYTE 1
ROM5:A4F3   .BYTE 1
ROM5:A4F4   .BYTE 2
ROM5:A4F5   .BYTE 2
 
Subroutine sub_164F6
ROM5:A4F6 sub_164F6:
ROM5:A4F6 LDX #3
 
ROM5:A4F7 loop1:
ROM5:A4F7 LDA #1
ROM5:A4F8 STA var_6
 
ROM5:A4F9 loop2:
ROM5:A4F9 TXA
ROM5:A4FA PHA
ROM5:A4FB STA var_11
ROM5:A4FC LDA byte_164D3,X
ROM5:A4FD STA var_2
ROM5:A4FE JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:A4FF CMP #DungeonDoor_LockedDoor
ROM5:A500 BCS loc_16528 ; Branch if locked door or shutter door
ROM5:A501 CMP #DungeonDoor_BombWall
ROM5:A502 BNE loc_16518
ROM5:A503 LDA #8 ; Bomb wall
ROM5:A504 BNE loc_16528 ; Always branch
 
ROM5:A505 loop3:
ROM5:A505 LDA #9
ROM5:A506 BNE loc_16547
 
ROM5:A518 loc_16518:
ROM5:A518 PHA
ROM5:A519 LDA var_2
ROM5:A51A EOR #$FF
ROM5:A51B AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:A51C STA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:A51D PLA
ROM5:A51E CMP #1
ROM5:A51F BCS loc_16528
ROM5:A520 LDA #4
 
ROM5:A528 loc_16528:
ROM5:A528 PHA
ROM5:A529 LDA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:A52A AND var_2
ROM5:A52B TAX
ROM5:A52C PLA
ROM5:A52D CPX var_2
ROM5:A52E BNE loc_16547
ROM5:A52F TAY
ROM5:A530 PLA
ROM5:A531 PHA
ROM5:A532 TAX
ROM5:A533 TYA
ROM5:A534 CMP #7
ROM5:A535 BEQ loc_16545
ROM5:A536 PHA
ROM5:A537 JSR screen_status_bit_set_X ; Add (1 << A) to the current screen's status.
ROM5:A538 PLA
ROM5:A539 CMP #8
ROM5:A53A BEQ loop3
 
ROM5:A545 loc_16545:
ROM5:A545 LDA #4
 
ROM5:A547 loc_16547:
ROM5:A547 LDX var_6
ROM5:A548 BEQ loc_16555
ROM5:A549 LDX var_11
ROM5:A54A PHA
ROM5:A54B JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:A54C JSR update_currently_open_doors ; Shift 0x01 into currently_open_doors if there's an open
  ; door or bomb wall in the direction contained in X
  ; (a direction index) is open, otherwise shift in 0x00.
 
  ; In X: direction bit
ROM5:A54D PLA
 
ROM5:A555 loc_16555:
ROM5:A555 CMP #4
ROM5:A556 BCC loc_165A5
ROM5:A557 SEC
ROM5:A558 SBC #3
ROM5:A559 TAY
ROM5:A55A CPY #3
ROM5:A55B BCC loc_16562
ROM5:A55C DEY
 
ROM5:A562 loc_16562:
ROM5:A562 PLA
ROM5:A563 PHA
ROM5:A564 JSR get_dungeon_door_sprite_ptr ; In A: direction index for which side door we want
  ; In Y: which door sprite type we want
  ; Out X: in A
  ; Out var_2: the memory pointer to the sprite
  ; Out var_0: unknown (RAM pointers related to scrolling
  ; doors onscreen)
ROM5:A565 LDA var_6
ROM5:A566 BNE loc_16576
ROM5:A567 LDA byte_164EA,X
ROM5:A568 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A569 LDA #6
ROM5:A56A JSR increment_16bit_var2_by_A ; 16-bit var2 += A
 
ROM5:A576 loc_16576:
ROM5:A576 LDY #0
ROM5:A577 LDA byte_164EE,X
ROM5:A578 STA var_5
 
ROM5:A579 loop4:
ROM5:A579 PLA
ROM5:A57A PHA
ROM5:A57B TAX
ROM5:A57C LDA byte_164F2,X
ROM5:A57D TAX
 
ROM5:A57E loop5:
ROM5:A57E LDA (var_2),Y
ROM5:A57F STA (var_0),Y
ROM5:A580 JSR increment_16bit_var2_by_1 ; 16-bit var2++
ROM5:A581 LDA byte_164E7,X
ROM5:A582 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A583 CPX #0
ROM5:A584 BNE loc_1659E
ROM5:A585 PLA
ROM5:A586 PHA
ROM5:A587 CMP #2
ROM5:A588 BCS loc_1659E
ROM5:A589 JSR increment_16bit_var0_by_1 ; 16-bit var0++
 
ROM5:A59E loc_1659E:
ROM5:A59E DEX
ROM5:A59F BPL loop5
ROM5:A5A0 DEC var_5
ROM5:A5A1 BNE loop4
 
ROM5:A5A5 loc_165A5:
ROM5:A5A5 PLA
ROM5:A5A6 TAX
ROM5:A5A7 DEC var_6
ROM5:A5A8 BMI loc_165AE
ROM5:A5A9 JMP loop2
 
ROM5:A5AE loc_165AE:
ROM5:A5AE DEX
ROM5:A5AF BMI locret_165D4
ROM5:A5B0 JMP loop1
 
Subroutine get_dungeon_door_sprite_ptr
; In A: direction index for which side door we want ; In Y: which door sprite type we want ; Out X: in A ; Out var_2: the memory pointer to the sprite ; Out var_0: unknown (RAM pointers related to scrolling ; doors onscreen)
ROM5:A5B4 get_dungeon_door_sprite_ptr:
ROM5:A5B4 TAX
ROM5:A5B5 LDA door_sprite_ptr_low,X
ROM5:A5B6 STA var_2
ROM5:A5B7 LDA door_sprite_ptr_high,X
ROM5:A5B8 STA var_3
ROM5:A5B9 LDA byte_164DF,X
ROM5:A5BA STA var_0
ROM5:A5BB LDA byte_164E3,X
ROM5:A5BC STA var_1
 
ROM5:A5BD loop: ; var2 += Y*0x0C
ROM5:A5BD DEY
ROM5:A5BE BEQ locret_165D4
ROM5:A5BF LDA #$C
ROM5:A5C0 JSR increment_16bit_var2_by_A ; 16-bit var2 += A
ROM5:A5C1 JMP loop
 
ROM5:A5D4 locret_165D4:
ROM5:A5D4 RTS
 
ROM5:A5D5 byte_165D5: .BYTE 1
ROM5:A5D6   .BYTE 3
ROM5:A5D7   .BYTE 6
ROM5:A5D8   .BYTE 8
ROM5:A5D9   .BYTE 3
ROM5:A5DA   .BYTE 5
ROM5:A5DB   .BYTE 8
ROM5:A5DC   .BYTE $A
ROM5:A5DD   .BYTE 3
ROM5:A5DE   .BYTE 6
ROM5:A5DF   .BYTE 4
ROM5:A5E0   .BYTE 7
ROM5:A5E1   .BYTE 5
ROM5:A5E2   .BYTE 8
ROM5:A5E3 byte_165E3: .BYTE 0
ROM5:A5E4   .BYTE 4
ROM5:A5E5   .BYTE 8
ROM5:A5E6   .BYTE $A
  ; The PPU nametable addresses of dungeon doors in the background
ROM5:A5E7 ppu_background_door_ptr_high: .BYTE $22 ; 225C
ROM5:A5E8   .BYTE $22 ; 2242
ROM5:A5E9   .BYTE $23 ; 234F
ROM5:A5EA   .BYTE $21 ; 214F
ROM5:A5EB ppu_background_door_ptr_low: .BYTE $5C
ROM5:A5EC   .BYTE $42
ROM5:A5ED   .BYTE $4F
ROM5:A5EE   .BYTE $4F
ROM5:A5EF adjacent_room_offset: .BYTE 1
ROM5:A5F0   .BYTE $FF
ROM5:A5F1   .BYTE $10
ROM5:A5F2   .BYTE $F0
 
Subroutine dungeon_only_update_door_background
; This isn't fully traced, but seems to handle updating the ; background to display opened/closed doors and bomb holes ; (not bomb explosions, which are sprites).
ROM5:A5F3 dungeon_only_update_door_background:
ROM5:A5F3 LDA game_mode
ROM5:A5F4 CMP #GameMode_PickedUpTriforce ; Return if in GameMode_PickedUpTriforce.
ROM5:A5F5 BEQ locret_165D4
ROM5:A5F6 LDA bombed_door_timer ; If this timer is running, don't display the bombed hole yet.
ROM5:A5F7 BNE locret_165D4
ROM5:A5F8 LDA byte_54
ROM5:A5F9 BEQ locret_165D4
ROM5:A5FA AND #7
ROM5:A5FB LDY #1
ROM5:A5FC STY var_2 ; Set to 1.
ROM5:A5FD BIT var_2
ROM5:A5FE BEQ loc_1660C
ROM5:A5FF LSR A ; If A & 1, A >>= 1
 
ROM5:A60C loc_1660C:
ROM5:A60C CMP #2
ROM5:A60D BNE skip_set_enemy_action_timer
ROM5:A60E LDY #48
ROM5:A60F STY enemy_action_timers ; Set to 48.
 
ROM5:A610 skip_set_enemy_action_timer:
ROM5:A610 AND #3
ROM5:A611 SEC
ROM5:A612 SBC #1
ROM5:A613 AND #2
ROM5:A614 STA var_8 ; This is used by update_door_or_bomb_wall_background.
ROM5:A615 LDA byte_54
ROM5:A616 CMP #5
ROM5:A617 BCS loc_16631
ROM5:A618 LDA bombing_or_unlocking_door_direction
ROM5:A619 STA var_2 ; Set var_2 to the bombed door direction. This is used
  ; by get_dungeon_door_type.
ROM5:A61A JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:A61B CMP #DungeonDoor_ShutterDoor
ROM5:A61C BEQ loc_16631 ; Branch if this is a shutter door.
ROM5:A61D JMP loc_16682
 
ROM5:A631 loc_16631: ; Out X: ppu_command_buffer_bytes_used
ROM5:A631 JSR setup_door_or_bomb_wall_background_update ; Out var_0, var_1: low/high byte of PPU address
  ; Out var_2, var_3: low/high byte of pointer to sprite
  ; Out var_5, var_6: number of bytes to update
 
ROM5:A632 loop:
ROM5:A632 LDA var_6
ROM5:A633 STA var_4 ; Set var_4 = var_6. This is used by copy_door_or_bomb_sprite_data below.
ROM5:A634 LDA var_0
ROM5:A635 STA ppu_command_buffer,X ; PPU pointer low byte
ROM5:A636 INX
ROM5:A637 LDA var_1
ROM5:A638 STA ppu_command_buffer,X ; PPU pointer high byte
ROM5:A639 INX
ROM5:A63A LDA var_6
ROM5:A63B STA ppu_command_buffer,X ; Number of bytes to send to the PPU
ROM5:A63C INX
 
ROM5:A63D loop2:
ROM5:A63D JSR copy_door_or_bomb_sprite_data
ROM5:A63E BNE loop2
ROM5:A63F LDA #$20
ROM5:A640 ORA var_1
ROM5:A641 STA var_1
ROM5:A642 DEC var_5
ROM5:A643 BNE loop
ROM5:A644 LDA #$FF ; Store the 0xFF terminator.
ROM5:A645 STA ppu_command_buffer,X
ROM5:A646 TXA ; Update ppu_command_buffer_bytes_used with the command
  ; we appended.
ROM5:A647 STA ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM5:A648 INC byte_54
ROM5:A649 LDA byte_54
ROM5:A64A AND #3
ROM5:A64B BEQ loc_1666F
ROM5:A64C LDA #8 ; (byte_54 & 3) != 0
ROM5:A64D STA bombed_door_timer ; Set to 8. This is the delay before the hole appears in the wall.
ROM5:A64E RTS
 
ROM5:A66F loc_1666F:
ROM5:A66F LDA byte_54
ROM5:A670 CMP #4
ROM5:A671 BNE loc_16689
ROM5:A672 LDX var_9
ROM5:A673 JSR screen_status_clear_bit_X ; Remove (1 << A) to the current screen's status.
ROM5:A674 LDA bombing_or_unlocking_door_direction
ROM5:A675 EOR #$F
ROM5:A676 AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
 
ROM5:A677 continue: ; The loc_16689 code path comes back here.
ROM5:A677 STA unlocked_door_directions
 
ROM5:A682 loc_16682:
ROM5:A682 LDA #0
ROM5:A683 STA byte_54 ; Set to 0
ROM5:A684 JMP sub_164F6
 
ROM5:A689 loc_16689:
ROM5:A689 LDA bombing_or_unlocking_door_direction
ROM5:A68A STA var_2 ; Set to bombed_door_direction
ROM5:A68B JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:A68C CMP #DungeonDoor_ShutterDoor ; Skip marking doors open for shutter doors.
ROM5:A68D BEQ skip_open_adjacent_door
ROM5:A68E LDX var_9
ROM5:A68F JSR screen_status_bit_set_X ; Add (1 << A) to the current screen's status.
ROM5:A690 TYA
ROM5:A691 CLC
ROM5:A692 ADC adjacent_room_offset,X ; Get the adjacent room.
ROM5:A693 TAY
ROM5:A694 TXA ; Flip bit 1 on the direction we're opening/bombing to get the
  ; opposite direction. If we're bombing down on a room or opening
  ; the bottom door, also open the corresponding top door on the room
  ; below.
ROM5:A695 EOR #1
ROM5:A696 TAX
ROM5:A697 LDA (var_0),Y
ROM5:A698 ORA powers_of_two,X
ROM5:A699 STA (var_0),Y
 
ROM5:A69A skip_open_adjacent_door:
ROM5:A69A LDA bombing_or_unlocking_door_direction
ROM5:A69B ORA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:A69C JMP continue
 
Subroutine setup_door_or_bomb_wall_background_update
; Out X: ppu_command_buffer_bytes_used ; Out var_0, var_1: low/high byte of PPU address ; Out var_2, var_3: low/high byte of pointer to sprite ; Out var_5, var_6: number of bytes to update
ROM5:A6B1 setup_door_or_bomb_wall_background_update:
ROM5:A6B1 LDA bombing_or_unlocking_door_direction ; Set var_2 to the bombed door direction. This is used
  ; by get_dungeon_door_type.
ROM5:A6B2 STA var_2
ROM5:A6B3 JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:A6B4 CMP #DungeonDoor_LockedDoor ; Don't play the door opening sound for doors < DungeonDoor_LockedDoor.
ROM5:A6B5 BCC no_door_sound
ROM5:A6B6 PHA ; Save the door type.
ROM5:A6B7 LDA #Sound0_Door
ROM5:A6B8 JSR add_mask_to_play_sound_0 ; play_sound_0 |= A
ROM5:A6B9 PLA ; Restore the door type.
 
ROM5:A6BA no_door_sound:
ROM5:A6BA CMP #DungeonDoor_BombWall
ROM5:A6BB BNE not_bomb_wall
ROM5:A6BC LDA #8 ; This is a bomb wall. Set A = 8, so it'll be set to 5 after
  ; subtracting 3 below.
 
ROM5:A6BD not_bomb_wall:
ROM5:A6BD CMP #DungeonDoor_Wall
ROM5:A6BE BNE not_wall ; (This can also compare against A = 8 above, which will
  ; always branch.)
ROM5:A6BF LDA #4 ; This is a regular wall. Set A = 4, so it'll be set to 1 after
  ; subtracting 3 below.
 
  ; Otherwise, A is the door type.
 
ROM5:A6C0 not_wall:
ROM5:A6C0 SEC
ROM5:A6C1 SBC #3 ; A -= 3
ROM5:A6C2 TAY ; Y = A
ROM5:A6C3 LDA var_8 ; This was set by our caller.
ROM5:A6C4 BEQ var_8_is_0
ROM5:A6C5 CPY #5
ROM5:A6C6 BEQ y_is_0
ROM5:A6C7 LDY #1
 
ROM5:A6C8 var_8_is_0:
ROM5:A6C8 CPY #3
ROM5:A6C9 BCC y_is_0
ROM5:A6CA DEY
 
ROM5:A6CB y_is_0:
ROM5:A6CB LDA #3
ROM5:A6CC SEC
ROM5:A6CD SBC var_3
ROM5:A6CE JSR get_dungeon_door_sprite_ptr ; A = 0: direction index for door (0 = right)
 
  ; Y = 1: open door
  ; Y = 2: locked door
  ; Y = 3: shutter door
  ; Y = 4: wall
  ; Y = 5: bomb hole
ROM5:A6CF LDA ppu_background_door_ptr_high,X ; Set var_0/var_1 to the PPU address of the door tile we're updating in the background.
ROM5:A6D0 STA var_0
ROM5:A6D1 LDA ppu_background_door_ptr_low,X
ROM5:A6D2 STA var_1
ROM5:A6D3 STX var_9 ; Store the direction index.
ROM5:A6D4 LDX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM5:A6D5 LDA #0
ROM5:A6D6 STA var_7 ; Set to 0
ROM5:A6D7 LDA #2
ROM5:A6D8 STA var_6 ; Set to 2
ROM5:A6D9 STA var_5 ; Set to 2
ROM5:A6DA RTS
 
ROM5:A704 byte_16704: .BYTE $D6
ROM5:A705 byte_16705: .BYTE $A2
ROM5:A706   .BYTE $E6
ROM5:A707   .BYTE $A2
ROM5:A708   .BYTE 4
ROM5:A709   .BYTE $A3
ROM5:A70A   .BYTE $15
ROM5:A70B   .BYTE $A3
ROM5:A70C   .BYTE $26
ROM5:A70D   .BYTE $A3
ROM5:A70E   .BYTE $3D
ROM5:A70F   .BYTE $A3
ROM5:A710   .BYTE $54
ROM5:A711   .BYTE $A3
ROM5:A712   .BYTE $65
ROM5:A713   .BYTE $A3
ROM5:A714   .BYTE $77
ROM5:A715   .BYTE $A3
ROM5:A716   .BYTE $91
ROM5:A717   .BYTE $A3
ROM5:A718 byte_16718: .BYTE $B0
ROM5:A719   .BYTE $74
ROM5:A71A   .BYTE $94
ROM5:A71B   .BYTE $B4
ROM5:A71C   .BYTE $70
ROM5:A71D   .BYTE $68
ROM5:A71E   .BYTE $F4
ROM5:A71F   .BYTE $24
 
Function chunk for sub_168C4
ROM5:A720 loc_16720: ; Set A to the screen code of the current location when in a dungeon.
ROM5:A720 JSR dungeon_get_screen_code
ROM5:A721 PHA
ROM5:A722 LDA #$DE
ROM5:A723 STA var_2
ROM5:A724 LDA #$A0
ROM5:A725 STA var_3
ROM5:A726 PLA
ROM5:A727 ASL A
ROM5:A728 ASL A
ROM5:A729 STA var_0
ROM5:A72A JSR increment_16bit_var2_by_A ; 16-bit var2 += A
ROM5:A72B LDA var_0
ROM5:A72C JSR increment_16bit_var2_by_A ; 16-bit var2 += A
ROM5:A72D LDA var_0
ROM5:A72E JSR increment_16bit_var2_by_A ; 16-bit var2 += A
ROM5:A72F LDA #$8C
ROM5:A730 STA var_0
ROM5:A731 LDA #$65
ROM5:A732 STA var_1
ROM5:A733 LDY #0
ROM5:A734 STY var_6
 
ROM5:A74A loc_1674A:
ROM5:A74A LDY var_6
ROM5:A74B LDA (var_2),Y
ROM5:A74C AND #$F0
ROM5:A74D LSR A
ROM5:A74E LSR A
ROM5:A74F LSR A
ROM5:A750 TAX
ROM5:A751 LDA byte_16704,X
ROM5:A752 STA var_4
ROM5:A753 LDA byte_16705,X
ROM5:A754 STA var_5
ROM5:A755 LDA (var_2),Y
ROM5:A756 AND #$F
ROM5:A757 TAX
ROM5:A758 LDY #0
 
ROM5:A765 loc_16765:
ROM5:A765 LDA (var_4),Y
ROM5:A766 BPL loc_1676C
ROM5:A767 DEX
ROM5:A768 BMI loc_16770
 
ROM5:A76C loc_1676C:
ROM5:A76C INY
ROM5:A76D JMP loc_16765
 
ROM5:A770 loc_16770:
ROM5:A770 TYA
ROM5:A771 JSR increment_16bit_var4_by_A ; 16-bit var4 += A
ROM5:A772 LDA #0
ROM5:A773 STA var_7 ; Set to 0
ROM5:A774 STA var_8
 
ROM5:A77A loc_1677A:
ROM5:A77A LDY #0
ROM5:A77B LDA (var_4),Y
ROM5:A77C AND #7
ROM5:A77D TAX
ROM5:A77E LDA byte_16718,X
ROM5:A77F LDY #0
ROM5:A780 JSR sub_167C1
ROM5:A781 LDA #2
ROM5:A782 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A783 LDY #0
ROM5:A784 LDA (var_4),Y
ROM5:A785 AND #$70
ROM5:A786 LSR A
ROM5:A787 LSR A
ROM5:A788 LSR A
ROM5:A789 LSR A
ROM5:A78A CMP var_8
ROM5:A78B BEQ loc_167A1
ROM5:A78C INC var_8
ROM5:A78D JMP loc_167A8
 
ROM5:A7A1 loc_167A1:
ROM5:A7A1 LDA #0
ROM5:A7A2 STA var_8
ROM5:A7A3 JSR increment_16bit_var4_by_1 ; 16-bit var4++
 
ROM5:A7A8 loc_167A8:
ROM5:A7A8 INC var_7
ROM5:A7A9 LDA var_7
ROM5:A7AA CMP #7
ROM5:A7AB BCC loc_1677A
ROM5:A7AC LDA #$1E
ROM5:A7AD JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A7AE INC var_6
ROM5:A7AF LDA var_6
ROM5:A7B0 CMP #$C
ROM5:A7B1 BCS locret_167C0
ROM5:A7B2 JMP loc_1674A
 
ROM5:A7C0 locret_167C0:
ROM5:A7C0 RTS
 
Subroutine sub_167C1
ROM5:A7C1 sub_167C1:
ROM5:A7C1 CMP #$70
ROM5:A7C2 BCC loc_167E0
ROM5:A7C3 CMP #$F3
ROM5:A7C4 BCS loc_167E0
ROM5:A7C5 TAX
ROM5:A7C6 STA (0),Y
ROM5:A7C7 INY
ROM5:A7C8 INX
ROM5:A7C9 TXA
ROM5:A7CA STA (0),Y
ROM5:A7CB TYA
ROM5:A7CC CLC
ROM5:A7CD ADC #$15
ROM5:A7CE TAY
ROM5:A7CF INX
ROM5:A7D0 TXA
ROM5:A7D1 STA (0),Y
ROM5:A7D2 INX
ROM5:A7D3 TXA
 
ROM5:A7DC loc_167DC:
ROM5:A7DC INY
ROM5:A7DD STA (0),Y
ROM5:A7DE RTS
 
ROM5:A7E0 loc_167E0:
ROM5:A7E0 STA (0),Y
ROM5:A7E1 INY
ROM5:A7E2 STA (0),Y
ROM5:A7E3 PHA
ROM5:A7E4 TYA
ROM5:A7E5 CLC
ROM5:A7E6 ADC #$15
ROM5:A7E7 TAY
ROM5:A7E8 PLA
ROM5:A7E9 STA (0),Y
 
ROM5:A7EE loc_167EE:
ROM5:A7EE JMP loc_167DC
 
Subroutine sub_167F1
ROM5:A7F1 sub_167F1:
ROM5:A7F1 LDA #0
ROM5:A7F2 STA byte_B7 ; Set to 0
ROM5:A7F3 STA byte_A3 ; Set to 0
ROM5:A7F4 JSR dungeon_get_screen_code ; Set A to the screen code of the current location when in a dungeon.
ROM5:A7F5 CMP #$21
ROM5:A7F6 BNE not_screen_0x21 ; Loop from 8-34 incrementing by 4s
ROM5:A7F7 LDA #$40
ROM5:A7F8 STA object_x_11 ; Set to 0x40
ROM5:A7F9 ASL A
ROM5:A7FA STA object_y_11 ; Set to 0x80
ROM5:A7FB JMP set_object_B_to_push_block
 
ROM5:A7FC not_screen_0x21: ; Loop from 8-34 incrementing by 4s
ROM5:A7FC LDX #8
ROM5:A7FD LDY #$A
 
ROM5:A80C loc_1680C:
ROM5:A80C LDA room_tile_ptrs,X
ROM5:A80D STA var_0
ROM5:A80E LDA room_tile_ptrs+1,X
ROM5:A80F STA var_1
ROM5:A810 LDA (var_0),Y
ROM5:A811 CMP #$B0
ROM5:A812 BEQ loc_16824
 
ROM5:A81C loc_1681C: ; X += 4
ROM5:A81C INX
ROM5:A81D INX
ROM5:A81E INX
ROM5:A81F INX
ROM5:A820 CPX #$34
ROM5:A821 BNE loc_1680C
 
ROM5:A824 loc_16824:
ROM5:A824 TXA
ROM5:A825 ASL A
ROM5:A826 ASL A
ROM5:A827 STA object_x_11
ROM5:A828 LDA #$90
ROM5:A829 STA object_y_11
 
ROM5:A82A set_object_B_to_push_block: ; An overworld push block.
ROM5:A82A LDA #ObjectType_DungeonSecret_Push_Block
ROM5:A82B STA object_type_B ; Set to ObjectType_DungeonSecret_Push_Block.
ROM5:A82C RTS
 
Subroutine task0_PickedUpTriforce
ROM5:A833 task0_PickedUpTriforce:
ROM5:A833 LDA #Music_PickedUpTriforcePiece
ROM5:A834 STA play_music ; Play Music_PickedUpTriforcePiece
ROM5:A835 LDA #$20
ROM5:A836 STA object_x_12
ROM5:A837 LDA #1
ROM5:A838 STA link_melee_x
ROM5:A839 LDA #$30
ROM5:A83A STA enemy_action_timers
ROM5:A83B LDA #$24
 
ROM5:A846 loc_16846:
ROM5:A846 STA var_10
ROM5:A847 JSR clear_room_tiles_to_var_10 ; Clear the current room's tile data (0x6530-0x67EF) to var_10.
ROM5:A848 INC active_game_mode_task ; Set to 1
 
ROM5:A84D loc_1684D: ; Clear the sprites created by update_object_sprite.
ROM5:A84D JSR clear_some_oam_sprites
ROM5:A84E LDA #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
ROM5:A84F STA picking_up_item ; If Link is holding an item above his head, this is the InventoryItem being held up.
ROM5:A850 JMP update_hold_up_item_1
 
Function chunk for task1_PickedUpTriforce
ROM5:A851 task1_PickedUpTriforce_main: ; Clear the sprites created by update_object_sprite.
ROM5:A851 JSR clear_some_oam_sprites
ROM5:A852 JSR update_hold_up_item_2
ROM5:A853 LDA task_state
ROM5:A854 JSR call_jump_table
 
ROM5:A855   .WORD task1_PickedUpTriforce_0
ROM5:A857   .WORD task1_PickedUpTriforce_1
ROM5:A859   .WORD task1_PickedUpTriforce_2
ROM5:A85B   .WORD task1_PickedUpTriforce_3
ROM5:A85D   .WORD task1_PickedUpTriforce_4
 
Subroutine task1_PickedUpTriforce_0
ROM5:A86D task1_PickedUpTriforce_0:
ROM5:A86D LDA enemy_action_timers
ROM5:A86E BNE locret_16887
ROM5:A86F LDA #$30
 
ROM5:A873 loc_16873:
ROM5:A873 STA enemy_action_timers
ROM5:A874 BNE loc_1688C
 
ROM5:A877 task1_PickedUpTriforce_1: ; This sends ppu_data_for_current_dungeon.
ROM5:A877 LDY #PPUCommandIndices_DungeonPPUData
ROM5:A878 LDA enemy_action_timers
ROM5:A879 BEQ loc_16888
ROM5:A87A AND #7
ROM5:A87B CMP #4
ROM5:A87C BCC loc_16885 ; Set to PPUCommandIndices_PickedUpTriforce_1 or PPUCommandIndices_PickedUpTriforce_2
ROM5:A87D LDY #PPUCommandIndices_PickedUpTriforce
 
ROM5:A885 loc_16885: ; Set to PPUCommandIndices_PickedUpTriforce_1 or PPUCommandIndices_PickedUpTriforce_2
ROM5:A885 STY current_ppu_command_index
 
ROM5:A887 locret_16887:
ROM5:A887 RTS
 
ROM5:A888 loc_16888:
ROM5:A888 LDA #2
ROM5:A889 STA health_refill ; 0x01 = potion refill, 0x02 = triforce refill, 0x40 = fairy refill
 
ROM5:A88C loc_1688C:
ROM5:A88C INC task_state
ROM5:A88D RTS
 
Subroutine task1_PickedUpTriforce_2
ROM5:A88F task1_PickedUpTriforce_2:
ROM5:A88F JSR update_fairy_refill_rupees_and_hud ; Update fairy/triforce health refill, rupee gain/loss and parts of the HUD.
  ; This is called during the Triforce fanfare (probably for health refill).
  ; It's also called from update_start_menu.
ROM5:A890 LDA health_refill ; 0x01 = potion refill, 0x02 = triforce refill, 0x40 = fairy refill
ROM5:A891 BEQ loc_168A4
ROM5:A892 RTS
 
ROM5:A897 task1_PickedUpTriforce_3:
ROM5:A897 LDA enemy_action_timers
ROM5:A898 BNE locret_168AA
ROM5:A899 JSR update_curtain ; This is related to curtains opening and closing.
ROM5:A89A LDA object_x_12
ROM5:A89B CMP #$11
ROM5:A89C BCS locret_168AA
 
ROM5:A8A4 loc_168A4:
ROM5:A8A4 LDA #$80
ROM5:A8A5 STA enemy_action_timers
ROM5:A8A6 INC task_state
 
ROM5:A8AA locret_168AA:
ROM5:A8AA RTS
 
Subroutine task1_PickedUpTriforce_4
ROM5:A8AB task1_PickedUpTriforce_4:
ROM5:A8AB LDA enemy_action_timers
ROM5:A8AC BNE locret_168AA
ROM5:A8AD JSR clear_oam ; Clear the OAM buffer.
ROM5:A8AE LDA current_ppuctrl
ROM5:A8AF AND #$FB ; Clear PPUMaskBits_SpritesOnLeft8PX.
ROM5:A8B0 STA current_ppuctrl
ROM5:A8B1 STA PPUCTRL
ROM5:A8B2 JMP exit_dungeon_after_triforce_fanfare
 
Function chunk for sub_168C4
ROM5:A8B3 in_overworld:
ROM5:A8B3 JSR sub_169F4
ROM5:A8B4 JMP sub_16B73 ; This is only called on the overworld.
 
Subroutine sub_168C4
ROM5:A8C4 sub_168C4:
 
ROM5:A8C4 JSR sub_16B30
ROM5:A8C5 LDA dungeon_idx
ROM5:A8C6 BEQ in_overworld ; Branch if on the overworld.
ROM5:A8C7 LDA #$F6
ROM5:A8C8 STA var_10 ; Set to 0xF6.
ROM5:A8C9 JSR clear_room_tiles_to_var_10 ; Clear the current room's tile data (0x6530-0x67EF) to var_10.
ROM5:A8CA JSR add_screen_status_to_unlocked_door_directions ; Add the direction bits set in unlocked_door_directions to screen_status, eg. ScreenStatus_WallOpened_*.
ROM5:A8CB JSR loc_16442
ROM5:A8CC JSR sub_164F6
ROM5:A8CD JMP loc_16720
 
Subroutine copy_background_column_to_ppu
; This copies a column of background tiles to the PPU. ; This is used for curtains opening and horizontal scrolling.
ROM5:A8DE copy_background_column_to_ppu:
ROM5:A8DE LDA #$1A ; var_0 = SRAM 0x651A
ROM5:A8DF STA var_0
ROM5:A8E0 LDA #$65
ROM5:A8E1 STA var_1
ROM5:A8E2 LDX byte_E8
ROM5:A8E3 DEX
ROM5:A8E4 TXA
ROM5:A8E5 LDY ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM5:A8E6 STA ppu_command_buffer_01,Y
ROM5:A8E7 LDA #$21
ROM5:A8E8 STA ppu_command_buffer,Y
 
ROM5:A8E9 loop1:
ROM5:A8E9 LDA #$16
ROM5:A8EA JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A8EB DEX
ROM5:A8EC BPL loop1
ROM5:A8ED LDA #$96
ROM5:A8EE STA ppu_command_buffer_02,Y
ROM5:A8EF TXA
ROM5:A8F0 STA ppu_command_buffer_19,Y
ROM5:A8F1 TYA
ROM5:A8F2 TAX
ROM5:A8F3 LDY #0
ROM5:A8F4 STY var_6
 
ROM5:A8F5 loop2:
ROM5:A8F5 LDA (var_0),Y
ROM5:A8F6 STA ppu_command_buffer_03,X
ROM5:A8F7 JSR increment_16bit_var0_by_1 ; 16-bit var0++
ROM5:A8F8 INX
ROM5:A8F9 INC var_6
ROM5:A8FA LDA var_6
ROM5:A8FB CMP #$16
ROM5:A8FC BCC loop2 ; Loop while A < 0x16
ROM5:A8FD INX
ROM5:A8FE INX
ROM5:A8FF INX
ROM5:A900 STX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM5:A901 RTS
 
Subroutine sub_16924
ROM5:A924 sub_16924:
ROM5:A924 LDA #$65
ROM5:A925 STA var_1
ROM5:A926 LDA byte_E9
ROM5:A927 TAX
ROM5:A928 CLC
ROM5:A929 ADC #$30
ROM5:A92A STA var_0
ROM5:A92B BCC loc_16934
ROM5:A92C INC var_1
 
ROM5:A934 loc_16934:
ROM5:A934 LDA #$20
ROM5:A935 STA ppu_command_buffer
ROM5:A936 LDA #$E0
ROM5:A937 STA ppu_command_buffer_01
 
ROM5:A938 loop1:
ROM5:A938 LDA ppu_command_buffer_01
ROM5:A939 CLC
ROM5:A93A ADC #$20
ROM5:A93B STA ppu_command_buffer_01
ROM5:A93C BCC loc_1694C
ROM5:A93D INC ppu_command_buffer
 
ROM5:A94C loc_1694C:
ROM5:A94C DEX
ROM5:A94D BPL loop1
ROM5:A94E LDA #$20
ROM5:A94F STA ppu_command_buffer_02
ROM5:A950 STX byte_325
ROM5:A951 LDX #0
ROM5:A952 LDY #0
 
ROM5:A953 loop2:
ROM5:A953 LDA (var_0),Y
ROM5:A954 STA ppu_command_buffer_03,X
ROM5:A955 LDA #$16
ROM5:A956 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:A957 INX
ROM5:A958 CPX #$20
ROM5:A959 BCC loop2
ROM5:A95A LDA #$23
ROM5:A95B STA ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM5:A95C RTS
 
ROM5:A970 overworld_object_types: .BYTE ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM5:A971   .BYTE ObjectType_OverworldSecret_Bomb ; An overworld bomb spot.
ROM5:A972   .BYTE ObjectType_OverworldSecret_Candle ; An overworld candle spot.
ROM5:A973   .BYTE ObjectType_OverworldSecret_Push_Tomb ; An overworld push block (tomb sprite).
ROM5:A974   .BYTE ObjectType_OverworldSecret_Push_Armos ; An overworld push block (Armos sprite).
ROM5:A975   .BYTE ObjectType_OverworldSecret_Bomb_2 ; An overworld bomb spot. I'm not sure how this differs from ObjectType_OverworldSecret_Bomb.
ROM5:A976 byte_16976: .BYTE $C8
ROM5:A977   .BYTE $D8
ROM5:A978   .BYTE $C4
ROM5:A979   .BYTE $BC
ROM5:A97A   .BYTE $C0
ROM5:A97B   .BYTE $C0
ROM5:A97C byte_1697C: .BYTE $24
ROM5:A97D   .BYTE $6F
ROM5:A97E   .BYTE $F3
ROM5:A97F   .BYTE $FA
ROM5:A980   .BYTE $98
ROM5:A981   .BYTE $90
ROM5:A982   .BYTE $8F
ROM5:A983   .BYTE $95
ROM5:A984   .BYTE $8E
ROM5:A985   .BYTE $90
ROM5:A986   .BYTE $74
ROM5:A987   .BYTE $76
ROM5:A988   .BYTE $F3
ROM5:A989   .BYTE $24
ROM5:A98A   .BYTE $26
ROM5:A98B   .BYTE $89
ROM5:A98C   .BYTE 3
ROM5:A98D   .BYTE 4
ROM5:A98E   .BYTE $70
ROM5:A98F   .BYTE $C8
ROM5:A990   .BYTE $BC
ROM5:A991   .BYTE $8D
ROM5:A992   .BYTE $8F
ROM5:A993   .BYTE $93
ROM5:A994   .BYTE $95
ROM5:A995   .BYTE $C4
ROM5:A996   .BYTE $CE
ROM5:A997   .BYTE $D8
ROM5:A998   .BYTE $B0
ROM5:A999   .BYTE $B4
ROM5:A99A   .BYTE $AA
ROM5:A99B   .BYTE $AC
ROM5:A99C   .BYTE $B8
ROM5:A99D   .BYTE $9C
ROM5:A99E   .BYTE $A6
ROM5:A99F   .BYTE $9A
ROM5:A9A0   .BYTE $A2
ROM5:A9A1   .BYTE $A0
ROM5:A9A2   .BYTE $E5
ROM5:A9A3   .BYTE $E6
ROM5:A9A4   .BYTE $E7
ROM5:A9A5   .BYTE $E8
ROM5:A9A6   .BYTE $E9
ROM5:A9A7   .BYTE $EA
ROM5:A9A8   .BYTE $C0
ROM5:A9A9   .BYTE $E0
ROM5:A9AA   .BYTE $78
ROM5:A9AB   .BYTE $7A
ROM5:A9AC   .BYTE $7E
ROM5:A9AD   .BYTE $80
ROM5:A9AE   .BYTE $CC
ROM5:A9AF   .BYTE $D0
ROM5:A9B0   .BYTE $D4
ROM5:A9B1   .BYTE $DC
ROM5:A9B2   .BYTE $89
ROM5:A9B3   .BYTE $84
ROM5:A9B4 byte_169B4: .BYTE $24
ROM5:A9B5   .BYTE $24
ROM5:A9B6   .BYTE $24
ROM5:A9B7   .BYTE $24
ROM5:A9B8   .BYTE $6F
ROM5:A9B9   .BYTE $6F
ROM5:A9BA   .BYTE $6F
ROM5:A9BB   .BYTE $6F
ROM5:A9BC   .BYTE $F3
ROM5:A9BD   .BYTE $F3
ROM5:A9BE   .BYTE $F3
ROM5:A9BF   .BYTE $F3
ROM5:A9C0   .BYTE $FA
ROM5:A9C1   .BYTE $FA
ROM5:A9C2   .BYTE $FA
ROM5:A9C3   .BYTE $FA
ROM5:A9C4   .BYTE $98
ROM5:A9C5   .BYTE $95
ROM5:A9C6   .BYTE $26
ROM5:A9C7   .BYTE $26
ROM5:A9C8   .BYTE $90
ROM5:A9C9   .BYTE $95
ROM5:A9CA   .BYTE $90
ROM5:A9CB   .BYTE $95
ROM5:A9CC   .BYTE $8F
ROM5:A9CD   .BYTE $90
ROM5:A9CE   .BYTE $8F
ROM5:A9CF   .BYTE $90
ROM5:A9D0   .BYTE $95
ROM5:A9D1   .BYTE $96
ROM5:A9D2   .BYTE $95
ROM5:A9D3   .BYTE $96
ROM5:A9D4   .BYTE $8E
ROM5:A9D5   .BYTE $93
ROM5:A9D6   .BYTE $90
ROM5:A9D7   .BYTE $95
ROM5:A9D8   .BYTE $90
ROM5:A9D9   .BYTE $95
ROM5:A9DA   .BYTE $92
ROM5:A9DB   .BYTE $97
ROM5:A9DC   .BYTE $74
ROM5:A9DD   .BYTE $74
ROM5:A9DE   .BYTE $75
ROM5:A9DF   .BYTE $75
ROM5:A9E0   .BYTE $76
ROM5:A9E1   .BYTE $77
ROM5:A9E2   .BYTE $76
ROM5:A9E3   .BYTE $77
ROM5:A9E4   .BYTE $F3
ROM5:A9E5   .BYTE $24
ROM5:A9E6   .BYTE $F3
ROM5:A9E7   .BYTE $24
ROM5:A9E8   .BYTE $24
ROM5:A9E9   .BYTE $24
ROM5:A9EA   .BYTE $24
ROM5:A9EB   .BYTE $24
ROM5:A9EC   .BYTE $26
ROM5:A9ED   .BYTE $26
ROM5:A9EE   .BYTE $26
ROM5:A9EF   .BYTE $26
ROM5:A9F0   .BYTE $89
ROM5:A9F1   .BYTE $88
ROM5:A9F2   .BYTE $8B
ROM5:A9F3   .BYTE $88
 
Subroutine sub_169F4
ROM5:A9F4 sub_169F4:
ROM5:A9F4 LDA byte_15F9C ; 0x18
ROM5:A9F5 STA var_2
ROM5:A9F6 LDA byte_15F9D ; 0x94
ROM5:A9F7 STA var_3
ROM5:A9F8 LDA #0
ROM5:A9F9 STA var_6
ROM5:A9FA LDX map_location
ROM5:A9FB LDA dungeon_screen_data_3,X
ROM5:A9FC ASL A
ROM5:A9FD ASL A
ROM5:A9FE ROL var_6
ROM5:A9FF ASL A
ROM5:AA00 ROL var_6
ROM5:AA01 ASL A
ROM5:AA02 ROL var_6
ROM5:AA03 ADC var_2
ROM5:AA04 STA var_2
ROM5:AA05 LDA var_6
ROM5:AA06 ADC var_3
ROM5:AA07 STA var_3
 
ROM5:AA1B loc_16A1B:
ROM5:AA1B LDA ppu_data_for_current_dungeon.screen_status_ptr
ROM5:AA1C STA var_8
ROM5:AA1D LDA ppu_data_for_current_dungeon.screen_status_ptr+1
ROM5:AA1E STA var_9
ROM5:AA1F JSR set_var0_to_current_tile_data ; Set 16-bit var0 to room_tiles_x_00 (0x6530), which is
  ; the memory block holding the current room's tile data.
ROM5:AA20 LDA #0
ROM5:AA21 STA var_12 ; set to 0
ROM5:AA22 STA var_6
 
ROM5:AA2E loc_16A2E:
ROM5:AA2E LDY var_6
ROM5:AA2F LDA (var_2),Y
ROM5:AA30 AND #$F0
ROM5:AA31 LSR A
ROM5:AA32 LSR A
ROM5:AA33 LSR A
ROM5:AA34 TAX
ROM5:AA35 LDA byte_26827,X
ROM5:AA36 STA var_4
ROM5:AA37 LDA byte_26828,X
ROM5:AA38 STA var_5
ROM5:AA39 LDA (var_2),Y
ROM5:AA3A AND #$F
ROM5:AA3B TAX
ROM5:AA3C LDY #$FF
 
ROM5:AA49 loc_16A49:
ROM5:AA49 INY
ROM5:AA4A LDA (var_4),Y
ROM5:AA4B BPL loc_16A49
ROM5:AA4C DEX
ROM5:AA4D BPL loc_16A49
ROM5:AA4E TYA
ROM5:AA4F JSR increment_16bit_var4_by_A ; 16-bit var4 += A
ROM5:AA50 LDA #0
ROM5:AA51 STA var_7
 
ROM5:AA59 loc_16A59:
ROM5:AA59 LDY #0
ROM5:AA5A LDA (var_4),Y
ROM5:AA5B AND #$3F
ROM5:AA5C STA var_13
ROM5:AA5D TAX
ROM5:AA5E LDA byte_1697C,X
ROM5:AA5F PHA
ROM5:AA60 LDY map_location
ROM5:AA61 LDA (var_8),Y
ROM5:AA62 AND #$80
ROM5:AA63 BEQ loc_16A88
ROM5:AA64 PLA
ROM5:AA65 CMP #$E7
ROM5:AA66 BEQ loc_16A7B
ROM5:AA67 CMP #$E6
ROM5:AA68 BEQ loc_16A83
ROM5:AA69 CMP #$EA
ROM5:AA6A BNE loc_16A87
 
ROM5:AA7B loc_16A7B:
ROM5:AA7B LDA #$10
ROM5:AA7C STA var_13
ROM5:AA7D LDA #$70
ROM5:AA7E BNE loc_16A87
 
ROM5:AA83 loc_16A83:
ROM5:AA83 LDA #$C
ROM5:AA84 STA var_13
 
ROM5:AA87 loc_16A87:
ROM5:AA87 PHA
 
ROM5:AA88 loc_16A88:
ROM5:AA88 PLA
ROM5:AA89 JSR sub_16ABF
ROM5:AA8A LDY #0
ROM5:AA8B JSR sub_16AF1
ROM5:AA8C LDA #2
ROM5:AA8D JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:AA8E LDY #0
ROM5:AA8F LDA (var_4),Y
ROM5:AA90 AND #$40
ROM5:AA91 BEQ loc_16AA4
ROM5:AA92 EOR var_12
ROM5:AA93 STA var_12
ROM5:AA94 BNE loc_16AA7
 
ROM5:AAA4 loc_16AA4: ; 16-bit var4++
ROM5:AAA4 JSR increment_16bit_var4_by_1
 
ROM5:AAA7 loc_16AA7:
ROM5:AAA7 INC var_7
ROM5:AAA8 LDA var_7
ROM5:AAA9 CMP #$B
ROM5:AAAA BNE loc_16A59
ROM5:AAAB LDA #$16
ROM5:AAAC JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:AAAD INC var_6
ROM5:AAAE LDA var_6
ROM5:AAAF CMP #$10
ROM5:AAB0 BCS locret_16AF0
ROM5:AAB1 JMP loc_16A2E
 
Subroutine sub_16ABF
ROM5:AABF sub_16ABF:
ROM5:AABF LDX #$EA
ROM5:AAC0 STX var_10
ROM5:AAC1 LDX #5
 
ROM5:AAC5 loc_16AC5:
ROM5:AAC5 CMP var_10
ROM5:AAC6 BEQ loc_16AD0
ROM5:AAC7 DEC var_10
ROM5:AAC8 DEX
ROM5:AAC9 BPL loc_16AC5
ROM5:AACA BMI locret_16AF0
 
ROM5:AAD0 loc_16AD0:
ROM5:AAD0 LDA byte_16976,X
ROM5:AAD1 PHA
ROM5:AAD2 LDA overworld_object_types,X
ROM5:AAD3 STA overworld_room_object_type
ROM5:AAD4 LDA var_6
ROM5:AAD5 ASL A
ROM5:AAD6 ASL A
ROM5:AAD7 ASL A
ROM5:AAD8 ASL A
ROM5:AAD9 STA overworld_room_object_x
ROM5:AADA LDA var_7
ROM5:AADB ASL A
ROM5:AADC ASL A
ROM5:AADD ASL A
ROM5:AADE ASL A
ROM5:AADF CLC
ROM5:AAE0 ADC #ObjectType_Flame_Unkillable
ROM5:AAE1 STA overworld_room_object_y
ROM5:AAE2 PLA
 
ROM5:AAF0 locret_16AF0:
ROM5:AAF0 RTS
 
Subroutine sub_16AF1
ROM5:AAF1 sub_16AF1:
ROM5:AAF1 LDX var_13
ROM5:AAF2 CPX #$10
ROM5:AAF3 BCC less_than_0x10 ; X < 0x10
ROM5:AAF4 TAX
ROM5:AAF5 STA (var_0),Y
ROM5:AAF6 INY
ROM5:AAF7 INX
ROM5:AAF8 TXA
ROM5:AAF9 STA (var_0),Y
ROM5:AAFA TYA
ROM5:AAFB CLC
ROM5:AAFC ADC #$15
ROM5:AAFD TAY
ROM5:AAFE INX
ROM5:AAFF TXA
ROM5:AB00 STA (var_0),Y
ROM5:AB01 INX
ROM5:AB02 TXA
 
ROM5:AB0A loc_16B0A:
ROM5:AB0A INY
ROM5:AB0B STA (var_0),Y
ROM5:AB0C RTS
 
ROM5:AB0D less_than_0x10:
ROM5:AB0D TXA
ROM5:AB0E ASL A ; A <<= 2
ROM5:AB0F ASL A
ROM5:AB10 TAX
ROM5:AB11 LDA byte_169B4,X
ROM5:AB12 STA (var_0),Y
ROM5:AB13 INY
ROM5:AB14 INX
ROM5:AB15 LDA byte_169B4,X
ROM5:AB16 STA (var_0),Y
ROM5:AB17 TYA
ROM5:AB18 CLC
ROM5:AB19 ADC #$15
ROM5:AB1A TAY
ROM5:AB1B INX
ROM5:AB1C LDA byte_169B4,X
ROM5:AB1D STA (0),Y
ROM5:AB1E INX
ROM5:AB1F LDA byte_169B4,X
ROM5:AB20 JMP loc_16B0A
 
Subroutine sub_16B30
ROM5:AB30 sub_16B30:
ROM5:AB30 LDA byte_15F9E ; D8
ROM5:AB31 LDX byte_15F9F ; 9B
ROM5:AB32 LDY dungeon_idx
ROM5:AB33 BEQ in_overworld
ROM5:AB34 LDA #$D4
ROM5:AB35 LDX #$A3
 
ROM5:AB36 in_overworld:
ROM5:AB36 STA byte_26827
ROM5:AB37 STX byte_26828
ROM5:AB38 RTS
 
ROM5:AB45 cellar_ppu_data: .WORD cellar_ppu_data_0
ROM5:AB47   .WORD cellar_ppu_data_1
ROM5:AB49   .WORD cellar_ppu_data_2
ROM5:AB4B   .WORD cellar_ppu_data_3
 
Subroutine task0_InOverworldCellar_3
ROM5:AB4D task0_InOverworldCellar_3:
ROM5:AB4D LDX #0 ; Use cellar_ppu_data_0
 
ROM5:AB4F cellar_increase_task_state_and_copy_ppu_data:
ROM5:AB4F LDA cellar_ppu_data,X
ROM5:AB50 STA var_2
ROM5:AB51 LDA cellar_ppu_data+1,X
ROM5:AB52 STA var_3
ROM5:AB53 INC task_state
ROM5:AB54 JMP loc_16A1B
 
Subroutine task0_ExitingOverworldCellar_3
ROM5:AB5E task0_ExitingOverworldCellar_3:
ROM5:AB5E LDX #2 ; Use cellar_ppu_data_2
ROM5:AB5F BNE cellar_increase_task_state_and_copy_ppu_data ; Always branch
 
Subroutine task0_InDungeonCellar_3
ROM5:AB62 task0_InDungeonCellar_3:
ROM5:AB62 LDA #0
ROM5:AB63 STA byte_E9
ROM5:AB64 LDX #4 ; Use cellar_ppu_data_2
ROM5:AB65 JSR dungeon_get_screen_code ; Set A to the screen code of the current location when in a dungeon.
ROM5:AB66 AND #1
ROM5:AB67 BEQ cellar_increase_task_state_and_copy_ppu_data
ROM5:AB68 LDX #6 ; Use cellar_ppu_data_3
ROM5:AB69 BNE cellar_increase_task_state_and_copy_ppu_data ; Always branch
 
Subroutine sub_16B73
; This is only called on the overworld.
ROM5:AB73 sub_16B73:
ROM5:AB73 JSR get_screen_status ; Load to check ScreenStatus_OverworldSecretOpened and ScreenStatus_Visited
ROM5:AB74 ASL A
ROM5:AB75 BCS ret ; Branch if ScreenStatus_OverworldSecretOpened is set.
ROM5:AB76 LDA (var_0),Y
ROM5:AB77 AND #ScreenStatusDungeon_Visited
ROM5:AB78 BEQ ret ; Branch if ScreenStatus_Visited isn't set.
ROM5:AB79 JSR set_var0_to_current_tile_data ; Set 16-bit var0 to room_tiles_x_00 (0x6530), which is
  ; the memory block holding the current room's tile data.
ROM5:AB7A JSR dungeon_get_item_position ; Get this room's item position: A = X position, Y = Y position
ROM5:AB7B LSR A ; X = floor item X position / 4
ROM5:AB7C LSR A
ROM5:AB7D TAX
ROM5:AB7E LDA room_tile_ptrs,X ; Set var_0 to the tile pointers for the item's column.
ROM5:AB7F STA var_0
ROM5:AB80 LDA room_tile_ptrs+1,X
ROM5:AB81 STA var_1
ROM5:AB82 TYA ; Y = floor item (Y position - 64) / 8
ROM5:AB83 SEC
ROM5:AB84 SBC #64
ROM5:AB85 LSR A
ROM5:AB86 LSR A
ROM5:AB87 LSR A
ROM5:AB88 TAY ; Y = A
ROM5:AB89 LDA (var_0),Y ; Get the tile type for the floor item.
ROM5:AB8A CMP #$C4
ROM5:AB8B BEQ loc_16BBC
ROM5:AB8C CMP #$BC
ROM5:AB8D BEQ ret
ROM5:AB8E CMP #$D8
ROM5:AB8F BNE loc_16BBC
ROM5:AB90 LDA overworld_room_object_type
ROM5:AB91 CMP #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM5:AB92 BEQ loc_16BBC
ROM5:AB93 LDA #0
ROM5:AB94 STA overworld_room_object_type ; Set to 0.
ROM5:AB95 LDA #$C
ROM5:AB96 STA var_13
 
ROM5:ABB8 loc_16BB8:
ROM5:ABB8 JSR sub_16AF1
 
ROM5:ABB9 ret:
ROM5:ABB9 RTS
 
ROM5:ABBC loc_16BBC:
ROM5:ABBC LDA #$10
ROM5:ABBD STA var_13 ; Set to 0x10.
ROM5:ABBE LDA #$70
ROM5:ABBF BNE loc_16BB8 ; Always branch
 
Subroutine sub_16BC4
ROM5:ABC4 sub_16BC4:
ROM5:ABC4 TXA
ROM5:ABC5 PHA
ROM5:ABC6 LDA object_x,X
ROM5:ABC7 AND #$F0
ROM5:ABC8 LSR A
ROM5:ABC9 LSR A
ROM5:ABCA TAX
ROM5:ABCB LDA room_tile_ptrs,X
ROM5:ABCC STA var_0
ROM5:ABCD LDA room_tile_ptrs+1,X
ROM5:ABCE STA var_1
ROM5:ABCF PLA
ROM5:ABD0 PHA
ROM5:ABD1 TAX
ROM5:ABD2 LDA object_y,X
ROM5:ABD3 AND #$F0
ROM5:ABD4 SEC
ROM5:ABD5 SBC #$40
ROM5:ABD6 LSR A
ROM5:ABD7 LSR A
ROM5:ABD8 LSR A
ROM5:ABD9 JSR increment_16bit_var0_by_A ; 16-bit var0 += A
ROM5:ABDA LDY #0
ROM5:ABDB LDX #$10
ROM5:ABDC LDA var_5
ROM5:ABDD CMP #$27
ROM5:ABDE BCC loc_16BF5
ROM5:ABDF CMP #$F3
ROM5:ABE0 BCC loc_16BFF
 
ROM5:ABF5 loc_16BF5:
ROM5:ABF5 LDX #$E
 
ROM5:ABF6 loop:
ROM5:ABF6 CMP byte_1697C,X
ROM5:ABF7 BEQ loc_16BFF
ROM5:ABF8 DEX
ROM5:ABF9 BNE loop
 
ROM5:ABFF loc_16BFF:
ROM5:ABFF STX var_13
ROM5:AC00 JSR sub_16AF1
ROM5:AC01 PLA
ROM5:AC02 TAX
ROM5:AC03 RTS
 
Subroutine set_var0_to_current_tile_data
; Set 16-bit var0 to room_tiles_x_00 (0x6530), which is ; the memory block holding the current room's tile data.
ROM5:AC07 set_var0_to_current_tile_data:
ROM5:AC07 LDA #$30
ROM5:AC08 STA var_0
ROM5:AC09 LDA #$65
ROM5:AC0A STA var_1
ROM5:AC0B RTS
 
Subroutine task0_InOverworldCellar_4
ROM5:AC10 task0_InOverworldCellar_4:
ROM5:AC10 JSR sub_16C16
ROM5:AC11 BCS task0_FinishedEnteringDoor_4_increase_task_state
ROM5:AC12 RTS
 
Subroutine sub_16C16
ROM5:AC16 sub_16C16:
ROM5:AC16 JSR sub_16924
ROM5:AC17 INC byte_E9
ROM5:AC18 LDA byte_E9
ROM5:AC19 CMP #$16
ROM5:AC1A RTS
 
Subroutine task0_ExitingCellar_4
ROM5:AC20 task0_ExitingCellar_4:
ROM5:AC20 JSR sub_168C4
ROM5:AC21 LDA #0
ROM5:AC22 STA byte_E9
 
ROM5:AC27 task0_FinishedEnteringDoor_4_increase_task_state:
ROM5:AC27 INC task_state
ROM5:AC28 RTS
 
ROM5:AC29 Skipped empty chunk
Function chunk for task1_Normal
Subroutine task0_CurtainsOpening_2
ROM5:B000 task0_CurtainsOpening_2:
ROM5:B000 LDA map_location
ROM5:B001 JSR sub_143D7
ROM5:B002 LDA #PPUCommandIndices_DungeonPPUData ; This sends ppu_data_for_current_dungeon.
ROM5:B003 BNE CurtainsOpening_5_set_current_ppu_command_index_and_advance_task_state
 
ROM5:B009 task0_CurtainsOpening_3:
ROM5:B009 LDA #$D0
ROM5:B00A LDY #$17
 
ROM5:B00D loc_1700D:
ROM5:B00D JMP sub_14501
 
Subroutine task0_CurtainsOpening_4
ROM5:B010 task0_CurtainsOpening_4:
ROM5:B010 LDA #$E8
ROM5:B011 LDY #$2F
ROM5:B012 BNE loc_1700D
 
ROM5:B016 task0_CurtainsOpening_5:
ROM5:B016 LDA #PPUCommandIndices_CurtainsOpening_5
 
ROM5:B018 CurtainsOpening_5_set_current_ppu_command_index_and_advance_task_state:
ROM5:B018 STA current_ppu_command_index
 
ROM5:B01A CurtainsOpening_5_advance_task_state:
ROM5:B01A INC task_state
ROM5:B01B RTS
 
Subroutine task0_CurtainsOpening_6
ROM5:B01D task0_CurtainsOpening_6:
ROM5:B01D LDA dungeon_idx
ROM5:B01E BEQ loc_17026
ROM5:B01F JSR check_has_map_in_current_dungeon ; Set not equal if we have the map for this dungeon.
ROM5:B020 BEQ CurtainsOpening_5_advance_task_state
 
ROM5:B026 loc_17026:
ROM5:B026 LDA #PPUCommandIndices_Unknown_44
ROM5:B027 BNE CurtainsOpening_5_set_current_ppu_command_index_and_advance_task_state
 
ROM5:B02A task0_CurtainsOpening_7:
ROM5:B02A LDA ppu_data_for_current_dungeon.displayed_level_number
ROM5:B02B BEQ CurtainsOpening_5_advance_task_state
ROM5:B02C STA unk_26825
ROM5:B02D LDA #PPUCommandIndices_CurtainsOpening_7 ; PPUCommandIndices_Unknown_Copied_Data_2
ROM5:B02E BNE CurtainsOpening_5_set_current_ppu_command_index_and_advance_task_state
 
ROM5:B036 task0_CurtainsOpening_8:
ROM5:B036 JSR sub_168C4
ROM5:B037 LDY #$10
ROM5:B038 STY object_x_12
ROM5:B039 INY
ROM5:B03A STY link_melee_x
ROM5:B03B LDA #0
ROM5:B03C STA curtains_currently_opening
ROM5:B03D LDA #8
ROM5:B03E STA object_direction
ROM5:B03F LDA #$78
 
ROM5:B04A loc_1704A:
ROM5:B04A STA object_x
ROM5:B04B LDA ppu_data_for_current_dungeon.start_y_pos
ROM5:B04C STA object_y
ROM5:B04D JMP start_task1 ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
 
ROM5:B054 screen_bounds: .BYTE $11 ; Overworld screen min X
ROM5:B055   .BYTE $E0 ; Overworld screen max X
ROM5:B056   .BYTE $4E ; Overworld screen min Y
ROM5:B057   .BYTE $CD ; Overworld screen max Y
ROM5:B058   .BYTE $89 ; Overworld (unknown, related to walking_collision_flags)
ROM5:B059   .BYTE $21 ; Dungeon screen min X. Dungeons have a smaller bounding box than the overworld.
ROM5:B05A   .BYTE $D0 ; Dungeon screen max X
ROM5:B05B   .BYTE $5E ; Dungeon screen min Y
ROM5:B05C   .BYTE $BD ; Dungeon screen max X
ROM5:B05D   .BYTE $78 ; Dungeon (unknown)
 
Subroutine setup_screen_bounds
ROM5:B05E setup_screen_bounds:
ROM5:B05E LDY #5 ; Y = 5 for dungeons
ROM5:B05F LDA dungeon_idx
ROM5:B060 BNE in_dungeon
ROM5:B061 LDY #0
ROM5:B062 STY in_dungeon_door ; Set to 0
 
ROM5:B063 in_dungeon: ; Y = 0 for overworld
ROM5:B063 LDX #0
 
ROM5:B064 loop:
ROM5:B064 LDA screen_bounds,Y
ROM5:B065 STA screen_min_x,X ; This is copied from ROM5:B054 byte_17054 on the overworld, and ROM5:B059 in dungeons. See ROM5:B05E setup_byte_346.
ROM5:B066 INY
ROM5:B067 INX
ROM5:B068 CPX #5
ROM5:B069 BNE loop
ROM5:B06A RTS
 
ROM5:B077 byte_17077: .BYTE $28
ROM5:B078   .BYTE $D8
ROM5:B079   .BYTE 0
 
Subroutine task0_PreparingScroll
ROM5:B07A task0_PreparingScroll:
ROM5:B07A JSR deactivate_clock_and_walk_state
ROM5:B07B JSR update_minimap_and_link_sprite
ROM5:B07C LDA dungeon_idx
ROM5:B07D BEQ in_overworld
ROM5:B07E JSR setup_dungeon_only_sprites
 
ROM5:B07F in_overworld: ; Like update_link_sprite_and_check_ladder, but do nothing if
ROM5:B07F JSR update_link_sprite_and_check_ladder_if_overworld ; we're in a dungeon.
ROM5:B080 JSR update_screen_kill_count
ROM5:B081 LDA dungeon_idx
ROM5:B082 BEQ is_overworld
ROM5:B083 JSR sub_170C3
ROM5:B084 PHA
ROM5:B085 AND #7
ROM5:B086 CMP #2
ROM5:B087 BNE loc_170A0
ROM5:B088 LDA #Sound1_Secret
ROM5:B089 STA play_sound_1 ; Play Sound1_Secret
 
ROM5:B0A0 loc_170A0:
ROM5:B0A0 PLA
ROM5:B0A1 AND #7
ROM5:B0A2 CMP #2
ROM5:B0A3 BCC is_overworld
ROM5:B0A4 CMP #5
ROM5:B0A5 BCC loc_170AD
 
ROM5:B0A6 is_overworld:
ROM5:B0A6 LDY #2
 
ROM5:B0AD loc_170AD:
ROM5:B0AD LDA byte_17077,Y
ROM5:B0AE STA object_tile_offset_whole
ROM5:B0AF JSR task0_Normal_3
 
ROM5:B0B6 clear_ladder_and_player_projectiles:
ROM5:B0B6 LDA #0
ROM5:B0B7 STA ladder_object_id ; Set to 0
ROM5:B0B8 LDY #5
 
ROM5:B0B9 loop: ; Clear all player projectile states
ROM5:B0B9 STA sword_state,Y
ROM5:B0BA DEY
ROM5:B0BB BPL loop
ROM5:B0BC RTS
 
Subroutine sub_170C3
ROM5:B0C3 sub_170C3:
ROM5:B0C3 LDY #0
ROM5:B0C4 LDA object_direction
ROM5:B0C5 AND #5
ROM5:B0C6 BEQ loc_170CC
ROM5:B0C7 INY
 
ROM5:B0CC loc_170CC:
ROM5:B0CC STY var_15
ROM5:B0CD LDA object_direction
ROM5:B0CE LDY game_mode
ROM5:B0CF CPY #GameMode_PrepareScroll
ROM5:B0D0 BEQ loc_170D9
ROM5:B0D1 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
 
ROM5:B0D9 loc_170D9:
ROM5:B0D9 STA var_2
ROM5:B0DA JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:B0DB LDY var_15
ROM5:B0DC RTS
 
Subroutine task1_JustDied_store_ppu_command_ending_at_Y
ROM5:B0E1 task1_JustDied_store_ppu_command_ending_at_Y:
ROM5:B0E1 STX ppu_command_buffer
ROM5:B0E2 STA ppu_command_buffer_01
ROM5:B0E3 LDX #$18
ROM5:B0E4 STX ppu_command_buffer_02 ; Set to 0x18.
ROM5:B0E5 LDA #$FF
ROM5:B0E6 STA ppu_command_buffer_03,X ; Set to 0xFF (the new PPU command terminator).
 
ROM5:B0E7 loop:
ROM5:B0E7 LDA temp_ppu_command_buffer,Y
ROM5:B0E8 STA ppu_command_buffer_02,X
ROM5:B0E9 DEY
ROM5:B0EA DEX
ROM5:B0EB BNE loop
ROM5:B0EC RTS
 
Subroutine task0_ExitingCellar
ROM5:B0FC task0_ExitingCellar:
ROM5:B0FC LDA task_state
ROM5:B0FD JSR call_jump_table
 
ROM5:B0FE   .WORD task0_InOverworldCellar_0 ; This is the first task0 task of InOverworldCellar, ExitingOverworldCellar, InDungeonCellar and ExitingCellar.
ROM5:B100   .WORD task0_ExitingCellar_1
ROM5:B102   .WORD task0_ExitingCellar_2
ROM5:B104   .WORD task0_InDungeonCellar_2
ROM5:B106   .WORD task0_ExitingCellar_4
ROM5:B108   .WORD task0_InOverworldCellar_4
ROM5:B10A   .WORD task0_ExitingCellar_6
ROM5:B10C   .WORD task0_InOverworldCellar_6
ROM5:B10E   .WORD task0_ExitingCellar_8
ROM5:B110   .WORD task0_InDungeonCellar_2
ROM5:B112   .WORD set_game_mode_finish_scroll
 
Subroutine task0_InOverworldCellar_0
; This is the first task0 task of InOverworldCellar, ExitingOverworldCellar, InDungeonCellar and ExitingCellar.
ROM5:B117 task0_InOverworldCellar_0:
ROM5:B117 LDA #0
ROM5:B118 STA byte_E9 ; Set to 0
ROM5:B119 STA unlocked_door_directions ; Set to 0
ROM5:B11A LDA dungeon_idx
ROM5:B11B BNE in_dungeon ; Branch if in a dungeon.
ROM5:B11C JSR in_dungeon ; Otherwise, still run the in_dungeon code, but return
  ; back here.
ROM5:B11D JMP set_oam_sprite_0_after_hud ; This puts a bomb sprite in the HUD overlapping the bomb
  ; in the background. This is used to trigger a sprite zero
  ; hit after the PPU finishes drawing the HUD and before it
  ; starts drawing the play field. OnNMI waits for this in
  ; wait_for_sprite_0_hit to allow changing PPU flags to
  ; scroll the play field during transitions without scrolling
  ; the HUD.
 
  ; https://wiki.nesdev.com/w/index.php/PPU_OAM#Sprite_zero_hits
 
ROM5:B11E in_dungeon:
ROM5:B11E INC task_state
ROM5:B11F JMP update_minimap_and_link_sprite
 
Subroutine task0_InDungeonCellar_5
ROM5:B12C task0_InDungeonCellar_5:
ROM5:B12C LDA #PPUCommandIndices_Cellar
 
ROM5:B12E set_current_ppu_command_index_and_advance_task_state: ; Set to PPUCommandIndices_Cellar, PPUCommandIndices_JustDied_3 or PPUCommandIndices_JustDied_4 or PPUCommandIndices_JustDied_5
ROM5:B12E STA current_ppu_command_index
 
ROM5:B130 increment_task_state_and_return:
ROM5:B130 INC task_state
ROM5:B131 RTS
 
Subroutine task0_InDungeonCellar_1
ROM5:B133 task0_InDungeonCellar_1:
ROM5:B133 LDA #0
 
ROM5:B135 loc_17135:
ROM5:B135 LDY dungeon_idx
ROM5:B136 BEQ increment_task_state_and_return ; Branch if we're in the overworld.
ROM5:B137 JSR set_next_palette_cycle_and_advance_task_state
 
ROM5:B13C task0_InDungeonCellar_2:
ROM5:B13C LDY dungeon_idx
ROM5:B13D BEQ increment_task_state_and_return ; Branch if we're in the overworld.
ROM5:B13E JMP task1_JustDied_8
 
Subroutine task0_InDungeonCellar_6
ROM5:B143 task0_InDungeonCellar_6:
ROM5:B143 LDA #$A0
ROM5:B144 BNE loc_17135 ; Always branch.
 
Subroutine task0_ExitingCellar_2
ROM5:B147 task0_ExitingCellar_2:
ROM5:B147 LDA #$20
ROM5:B148 BNE loc_17135 ; Always branch.
 
Subroutine task0_ExitingCellar_8
ROM5:B14B task0_ExitingCellar_8:
ROM5:B14B LDA #$80
ROM5:B14C BNE loc_17135 ; Always branch.
 
Subroutine task0_InOverworldCellar_1
ROM5:B14F task0_InOverworldCellar_1:
ROM5:B14F LDA #$3E
ROM5:B150 BNE set_current_ppu_command_index_and_advance_task_state ; Always branch.
 
Subroutine task0_ExitingCellar_1
ROM5:B153 task0_ExitingCellar_1:
ROM5:B153 LDA dungeon_idx
ROM5:B154 BNE increment_task_state_and_return ; Branch if in a dungeon.
ROM5:B155 JMP loc_1EA2B
 
Subroutine set_game_mode_finish_scroll
ROM5:B15A set_game_mode_finish_scroll:
ROM5:B15A JSR clear_ladder_and_player_projectiles
ROM5:B15B LDA #0
ROM5:B15C STA task_state
ROM5:B15D LDA #GameMode_FinishScroll
ROM5:B15E STA game_mode ; set GameMode_FinishScroll
ROM5:B15F RTS
 
ROM5:B166 task0_ExitingCellar_6:
ROM5:B166 LDA map_location
ROM5:B167 JMP loc_1716D
 
Subroutine task0_InOverworldCellar_5
ROM5:B16B task0_InOverworldCellar_5:
ROM5:B16B LDA #$44 ; Map location
 
ROM5:B16D loc_1716D:
ROM5:B16D JSR sub_143D7
ROM5:B16E JMP task0_CurtainsOpening_3
 
Subroutine task0_InOverworldCellar_6
ROM5:B173 task0_InOverworldCellar_6:
ROM5:B173 JSR task0_CurtainsOpening_4
ROM5:B174 JMP loc_1717B
 
ROM5:B175   .BYTE $E6
ROM5:B176   .BYTE $13
 
ROM5:B17B loc_1717B:
ROM5:B17B LDA #0
ROM5:B17C STA do_ppu_work_after_sprite0_next_frame ; Set to 0
ROM5:B17D RTS
 
Subroutine task0_InOverworldCellar_8
ROM5:B180 task0_InOverworldCellar_8:
ROM5:B180 LDA object_tile_offset_whole
ROM5:B181 BEQ loc_17194
ROM5:B182 LDA object_direction
ROM5:B183 STA walking_directions
ROM5:B184 STA var_15
ROM5:B185 LDX #0
ROM5:B186 JSR process_movement
ROM5:B187 JMP update_link_sprite_and_door_clipping ; Update Link's sprite and dungeon door clipping.
 
ROM5:B194 loc_17194:
ROM5:B194 JMP task0_Normal_3
 
ROM5:B197 byte_17197: .BYTE $30
ROM5:B198   .BYTE $C0
 
Subroutine task0_InDungeonCellar_8
ROM5:B199 task0_InDungeonCellar_8:
ROM5:B199 LDA task_state
ROM5:B19A PHA
ROM5:B19B JSR task0_FinishingTransition_state_0
ROM5:B19C JSR clear_ladder_and_player_projectiles
ROM5:B19D PLA
ROM5:B19E STA task_state
ROM5:B19F LDY map_location
ROM5:B1A0 LDX #0
ROM5:B1A1 LDA map_location_in_dungeon_cellar
ROM5:B1A2 CMP dungeon_screen_data_0,Y ; This is copied from dungeon_screen_attr_1Q_1, etc.
ROM5:B1A3 BEQ loc_171B2
ROM5:B1A4 INX
 
ROM5:B1B2 loc_171B2:
ROM5:B1B2 LDA byte_17197,X
ROM5:B1B3 STA object_x
ROM5:B1B4 LDA #$41
ROM5:B1B5 STA object_y
 
Subroutine sub_171BB
ROM5:B1BB sub_171BB:
ROM5:B1BB LDA #4
ROM5:B1BC STA object_direction
ROM5:B1BD LDA #$E4
ROM5:B1BE STA object_tile_offset_whole
ROM5:B1BF LDA #0
ROM5:B1C0 STA active_game_mode_task ; Set to 0
ROM5:B1C1 STA in_dungeon_door ; Set to 0
ROM5:B1C2 INC task_state
ROM5:B1C3 RTS
 
Subroutine task0_InDungeonCellar_9
ROM5:B1CD task0_InDungeonCellar_9:
ROM5:B1CD LDA object_direction
ROM5:B1CE STA walking_directions
ROM5:B1CF JSR update_link_movement
ROM5:B1D0 LDA object_y
ROM5:B1D1 CMP #$5D
ROM5:B1D2 BNE locret_171E5
ROM5:B1D3 LDA #0
ROM5:B1D4 STA walk_state_and_weapon_state
ROM5:B1D5 LDA #1
ROM5:B1D6 STA is_in_cellar ; Set to 1
ROM5:B1D7 STA active_game_mode_task ; Set to 1
 
ROM5:B1E5 locret_171E5:
ROM5:B1E5 RTS
 
Subroutine handle_potion_fairy_refill
ROM5:B1E6 handle_potion_fairy_refill:
ROM5:B1E6 LDA health_refill ; 0x01 = potion refill, 0x02 = triforce refill, 0x40 = fairy refill
ROM5:B1E7 BEQ potion_refill_not_active ; Do nothing if not set
ROM5:B1E8 LDA #Sound3_GainRupee
ROM5:B1E9 STA play_sound_3 ; Play Sound3_GainRupee
ROM5:B1EA LDA partial_heart ; Half heart if < 0x80, and a timer for potion refills
ROM5:B1EB CMP #$F8
ROM5:B1EC BCS heart_fill_wrapped ; Branch if partial_heart >= 0xF8
ROM5:B1ED CLC
ROM5:B1EE ADC #6
ROM5:B1EF STA partial_heart ; partial_heart += 6
ROM5:B1F0 RTS
 
ROM5:B1F1 heart_fill_wrapped: ; Potion refill has filled a whole heart.
ROM5:B1F1 LDA #0
ROM5:B1F2 STA partial_heart ; Reset back to 0 after wrap
ROM5:B1F3 JSR is_health_full ; Set Z if hearts are full, otherwise clear Z.
ROM5:B1F4 BNE filled_heart ; We've filled a whole heart. Transfer it to health.
ROM5:B1F5 DEC partial_heart ; Set to 0xFF
ROM5:B1F6 LDA #0
ROM5:B1F7 STA sword_disabled_by_bubble ; Finished with health refill, set to 0
ROM5:B1F8 STA health_refill ; Finished with health refill, set to 0
ROM5:B1F9 STA paused ; Finished with health refill, unpause
 
ROM5:B1FA potion_refill_not_active:
ROM5:B1FA RTS
 
ROM5:B1FB filled_heart: ; We've filled a whole heart. Transfer it to health.
ROM5:B1FB INC hearts
ROM5:B1FC RTS
 
ROM5:B218 start_menu_ppu_command_indices_dungeon: .BYTE 0 ; This stuff is related to running PPU commands to set up the start menu.
ROM5:B219   .BYTE 0
ROM5:B21A   .BYTE 0
ROM5:B21B   .BYTE PPUCommandIndices_Unknown_30
ROM5:B21C   .BYTE PPUCommandIndices_Unknown_32
ROM5:B21D   .BYTE PPUCommandIndices_Unknown_34
ROM5:B21E   .BYTE PPUCommandIndices_Unknown_38
ROM5:B21F   .BYTE PPUCommandIndices_Unknown_3a
ROM5:B220   .BYTE PPUCommandIndices_Unknown_3C
ROM5:B221   .BYTE 0
ROM5:B222   .BYTE 0
ROM5:B223   .BYTE 0
ROM5:B224   .BYTE PPUCommandIndices_Unknown_40
ROM5:B225 start_menu_ppu_command_indices_overworld: .BYTE 0
ROM5:B226   .BYTE 0
ROM5:B227   .BYTE 0
ROM5:B228   .BYTE PPUCommandIndices_Unknown_30
ROM5:B229   .BYTE PPUCommandIndices_Unknown_32
ROM5:B22A   .BYTE PPUCommandIndices_Unknown_34
ROM5:B22B   .BYTE PPUCommandIndices_Unknown_38
ROM5:B22C   .BYTE PPUCommandIndices_Unknown_3a
ROM5:B22D   .BYTE PPUCommandIndices_Unknown_3C
ROM5:B22E   .BYTE 0
ROM5:B22F   .BYTE 0
ROM5:B230   .BYTE 0
ROM5:B231   .BYTE 0
ROM5:B232   .BYTE 0
ROM5:B233   .BYTE 0
ROM5:B234   .BYTE PPUCommandIndices_Unknown_50
ROM5:B235   .BYTE PPUCommandIndices_Unknown_Copied_Data_3
ROM5:B236   .BYTE PPUCommandIndices_Unknown_Copied_Data_4
ROM5:B237   .BYTE PPUCommandIndices_Unknown_Copied_Data_5
ROM5:B238   .BYTE PPUCommandIndices_Unknown_Copied_Data_6
ROM5:B239   .BYTE PPUCommandIndices_Unknown_5A
 
Subroutine send_start_menu_ppu_commands
ROM5:B23A send_start_menu_ppu_commands:
ROM5:B23A LDA start_menu_scroll_progress
ROM5:B23B BMI ret
ROM5:B23C LSR A
ROM5:B23D TAY
ROM5:B23E BCS loc_1725B ; Branch if 0x01 was set.
ROM5:B23F CMP #$D
ROM5:B240 BCS loc_1724C ; Branch if >= 0xD.
ROM5:B241 LDA start_menu_ppu_command_indices_dungeon,Y ; This stuff is related to running PPU commands to set up the start menu.
 
ROM5:B249 loc_17249:
ROM5:B249 JMP decrement_start_menu_scroll_progress_store_command_idx_and_return
 
ROM5:B24C loc_1724C:
ROM5:B24C CMP #$15
ROM5:B24D BNE not_0x15
ROM5:B24E LDA #PPUCommandIndices_Unknown_42
ROM5:B24F JMP loc_17249
 
ROM5:B250 not_0x15: ; This sends PPU commands to draw the big map in the start menu.
ROM5:B250 JSR send_start_menu_map_ppu_commands
 
ROM5:B251 decrement_byte_5E_and_return:
ROM5:B251 DEC start_menu_scroll_progress
 
ROM5:B252 ret:
ROM5:B252 RTS
 
ROM5:B25B loc_1725B:
ROM5:B25B LDA #$28
ROM5:B25C STA ppu_command_buffer
ROM5:B25D LDA #$C0
 
ROM5:B25E loop:
ROM5:B25E CLC
ROM5:B25F ADC #$20
ROM5:B260 BCC no_increment
ROM5:B261 INC ppu_command_buffer
 
ROM5:B262 no_increment:
ROM5:B262 DEY
ROM5:B263 BPL loop
ROM5:B264 STA ppu_command_buffer_01
ROM5:B265 LDA #$60
ROM5:B266 STA ppu_command_buffer_02
ROM5:B267 LDA #$24
ROM5:B268 STA ppu_command_buffer_03
ROM5:B269 LDA #$FF
ROM5:B26A STA ppu_command_buffer_04
ROM5:B26B JMP decrement_byte_5E_and_return
 
ROM5:B282 show_menu_6_7_overworld_sub:
ROM5:B282 LDA start_menu_scroll_progress
ROM5:B283 BMI locret_17295
ROM5:B284 LSR A
ROM5:B285 TAY
ROM5:B286 BCS loc_1725B
ROM5:B287 CMP #$15
ROM5:B288 BCS decrement_start_menu_scroll_progress_and_return_2
ROM5:B289 LDA start_menu_ppu_command_indices_overworld,Y
 
ROM5:B28A decrement_start_menu_scroll_progress_store_command_idx_and_return:
ROM5:B28A STA current_ppu_command_index
 
ROM5:B28B decrement_start_menu_scroll_progress_and_return_2:
ROM5:B28B DEC start_menu_scroll_progress
 
ROM5:B295 locret_17295:
ROM5:B295 RTS
 
ROM5:B296 direction_axes: .BYTE ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:B297   .BYTE ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:B298   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM5:B299   .BYTE ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
 
Subroutine update_walking_direction
; Check for item use and sword swords (A and B presses) ; Update Link's walking direction. ; If we're not on a tile, update Link's walking speed.
ROM5:B29A update_walking_direction:
 
ROM5:B29A LDA walk_state_and_weapon_state ; Don't allow using items if any walk_state is set
ROM5:B29B BNE no_item_use
ROM5:B29C JSR prevent_item_and_sword_when_near_screen_edge ; If Link is close to the edge of the screen and facing in that
  ; direction, prevent using items or the sword.
 
  ; The threshold for preventing items and the sword is different,
  ; and the sword threshold is different in the overworld and in
  ; dungeon.
ROM5:B29D LDA bubble_sword_timer ; Check if our sword is disabled by a regular bubble
ROM5:B29E ORA sword_disabled_by_bubble ; Check if our sword is permanently disabled by a red bubble
ROM5:B29F BNE no_sword_swing ; Skip checking the sword if it's been disabled by a bubble.
ROM5:B2A0 LDA controller_1_pressed ; Load to check if we're attacking
ROM5:B2A1 AND #ControllerBits_A
ROM5:B2A2 BEQ no_sword_swing
ROM5:B2A3 JSR link_swing_sword ; Call if A was pressed to swing the sword.
 
ROM5:B2A4 no_sword_swing: ; Load to check if we're using an item.
ROM5:B2A4 LDA controller_1_pressed
ROM5:B2A5 AND #ControllerBits_B
ROM5:B2A6 BEQ no_item_use
ROM5:B2A7 JSR use_item ; Call if B was pressed to use an item.
 
ROM5:B2A8 no_item_use:
ROM5:B2A8 LDX #0
ROM5:B2A9 LDA object_knockback ; Don't do anything else if we're in knockback.
ROM5:B2AA BNE ret
ROM5:B2AB LDA dungeon_idx ; Skip checking dungeon door movement when on the overworld.
ROM5:B2AC BEQ is_overworld
ROM5:B2AD JSR lock_movement_to_dungeon_door ; Adjust the player's walking_directions when standing in
  ; a dungeon door. If we're in a left/right door, pressing left
  ; moves left (even if up or down are also pressed), right
  ; moves right, and pressing up or down alone keeps moving in
  ; the direction we're already facing.
 
ROM5:B2AE is_overworld:
ROM5:B2AE LDA object_tile_offset_whole
ROM5:B2AF BEQ on_tile
ROM5:B2B0 JMP not_on_tile
 
ROM5:B2B1 on_tile: ; Set to 0
ROM5:B2B1 STA var_11
ROM5:B2B2 STA var_12 ; Set to 0
ROM5:B2B3 STA number_of_extra_directions_pressed ; Set to 0
ROM5:B2B4 LDY #3
 
ROM5:B2B5 loop_each_walking_direction: ; Loop over each direction and check the direction the player is walking
ROM5:B2B5 LDA walking_directions
ROM5:B2B6 AND walking_bits_2,Y
ROM5:B2B7 BEQ not_walking_this_direction ; Branch if walking_directions doesn't include this direction.
ROM5:B2B8 STA var_15 ; Store this walking direction. set_walking_collision_flags_2 uses this.
ROM5:B2B9 TYA ; Push Y (loop index)
ROM5:B2BA PHA
ROM5:B2BB INC var_11
ROM5:B2BC JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM5:B2BD CMP screen_first_solid_tile_id ; Compare walking_collision_flags with screen_first_solid_tile_id.
ROM5:B2BE BCS solid_tile ; Branch if walking_collision_flags >= screen_first_solid_tile_id (tile is solid)
ROM5:B2BF LDA var_15 ; This direction isn't blocked by a solid tile.
  ; Set var_13 to this walking direction.
ROM5:B2C0 STA var_13
ROM5:B2C1 INC var_12 ; var_12++. This counts the number of held walking directions
  ; that aren't blocked.
 
ROM5:B2C2 solid_tile: ; Restore the loop variable.
ROM5:B2C2 PLA
ROM5:B2C3 TAY
 
ROM5:B2C4 not_walking_this_direction:
ROM5:B2C4 DEY
ROM5:B2C5 BPL loop_each_walking_direction
ROM5:B2C6 LDY var_11
ROM5:B2C7 BNE one_or_more_directions_pressed ; Branch if at least one direction is being held (whether it's obstructed or not).
 
ROM5:B2C8 ret:
ROM5:B2C8 RTS
 
ROM5:B2C9 one_or_more_directions_pressed:
ROM5:B2C9 LDA var_15
ROM5:B2CA CPY #1 ; Check if more than one direction is pressed.
ROM5:B2CB BEQ store_direction_lock
ROM5:B2CC LDA var_12
ROM5:B2CD BNE two_or_more_directions_pressed ; Branch if two or more directions are pressed that aren't
  ; blocked.
ROM5:B2CE JMP store_A_to_walking_directions
 
ROM5:B2CF two_or_more_directions_pressed: ; This handles figuring out which direction to walk if
ROM5:B2CF TAY ; two buttons are pressed.
 
  ; Y = A: bitmask of directions being held that aren't blocked
ROM5:B2D0 INC number_of_extra_directions_pressed ; More than one direction is pressed, so set this to 1.
ROM5:B2D1 LDX #0
ROM5:B2D2 LDA var_13
ROM5:B2D3 CPY #ControllerBits_Dpad_Right
ROM5:B2D4 BEQ store_direction_lock
ROM5:B2D5 LDY dungeon_idx
ROM5:B2D6 BEQ store_direction_lock ; Skip if in overworld
ROM5:B2D7 LDY object_x
ROM5:B2D8 CPY #32 ; Dungeon left wall
ROM5:B2D9 BEQ left_or_right_wall
ROM5:B2DA CPY #208 ; Dungeon right wall
ROM5:B2DB BNE not_left_or_right_wall
 
ROM5:B2DC left_or_right_wall:
ROM5:B2DC LDY object_y
ROM5:B2DD CPY #133 ; One half tile above the side doors (door is at 141, bottom half tile is 149)
ROM5:B2DE BNE flip_perpendicular_to_object_direction
ROM5:B2DF LDA object_direction ; We're against the side wall and half a tile above the door.
ROM5:B2E0 AND #ControllerBits_Dpad_Down
ROM5:B2E1 BEQ flip_perpendicular_to_object_direction ; Branch if down isn't pressed
 
ROM5:B2E2 loop:
ROM5:B2E2 LDA object_direction
ROM5:B2E3 BNE store_direction_lock ; Branch if object_direction != 0
 
ROM5:B2E4 not_left_or_right_wall:
ROM5:B2E4 LDA object_direction
ROM5:B2E5 LDX walking_direction_was_flipped
ROM5:B2E6 BEQ flip_perpendicular_to_object_direction ; Branch if dungeon_walk_direction_lock == 0
ROM5:B2E7 LDY dungeon_idx ; walking_direction_was_flipped is set, which means we took
  ; the flip_perpendicular_to_object_direction code path last
  ; time.
ROM5:B2E8 BEQ store_direction_lock ; Skip if in overworld
ROM5:B2E9 LDY object_x
ROM5:B2EA CPY #120 ; Centered on X
ROM5:B2EB BNE store_direction_lock ; Branch if not exactly centered on X
ROM5:B2EC LDY object_y
ROM5:B2ED CPY #93 ; Dungeon top wall
ROM5:B2EE BNE store_direction_lock
ROM5:B2EF AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM5:B2F0 BEQ loop ; Branch if object_direction is vertical.
  ; (It looks like that will always jump to store_direction_lock,
  ; since object_direction isn't 0.)
 
ROM5:B2F1 flip_perpendicular_to_object_direction:
ROM5:B2F1 LDA object_direction
ROM5:B2F2 INX ; X = 1
ROM5:B2F3 JSR get_opposite_direction_and_index ; If object_direction is left or right, Y = 2,3.
  ; If up or down, Y = 0,1.
ROM5:B2F4 LDA walking_directions
ROM5:B2F5 PHA ; Push walking_directions
ROM5:B2F6 AND direction_axes,Y ; If object_direction is up or down, A = walking_direction & (Up|Down).
  ; Otherwise, A = walking_direction & (Left|Right).
ROM5:B2F7 STA var_12
ROM5:B2F8 PLA ; Restore walking_directions
ROM5:B2F9 EOR var_12 ; A (walking_directions) ^= var_12
 
ROM5:B2FA store_direction_lock:
ROM5:B2FA STX walking_direction_was_flipped
ROM5:B2FB JSR store_A_to_object_direction_and_walking_directions
ROM5:B2FC LDX #0 ; Set X back to 0 (Link).
 
ROM5:B366 update_link_walking_speed: ; Normal walk speed
ROM5:B366 LDA #$60
ROM5:B367 STA var_0 ; Store Link's normal walking speed (0x60)
ROM5:B368 LDA dungeon_idx
ROM5:B369 BNE set_walk_speed_to_var_0
ROM5:B36A LDA tile_walking_onto ; Compare to 0x74 and 0x75
ROM5:B36B CMP #OverworldTiles_Ladder1
ROM5:B36C BEQ on_overworld_ladder
ROM5:B36D CMP #OverworldTiles_Ladder2
ROM5:B36E BNE set_walk_speed_to_var_0
 
ROM5:B36F on_overworld_ladder: ; Half movement speed on overworld ladders
ROM5:B36F LDA #$30
ROM5:B370 STA var_0 ; Store Link's ladder walking speed (0x30)
ROM5:B371 CMP object_walk_speed
ROM5:B372 BEQ set_walk_speed_to_var_0
ROM5:B373 LDA #0
ROM5:B374 STA object_tile_offset_fraction ; If object_walk_speed is changing, clear walk_accumulation to 0
 
ROM5:B375 set_walk_speed_to_var_0:
ROM5:B375 LDA var_0
ROM5:B376 STA object_walk_speed ; Save Link's walk speed
 
ROM5:B38C locret_1738C:
ROM5:B38C RTS
 
Function chunk for update_walking_direction
ROM5:B38D not_on_tile:
ROM5:B38D LDA walking_directions
ROM5:B38E BEQ locret_1738C ; Return if we're not walking.
ROM5:B38F JSR get_opposite_direction_and_index ; Get the first direction that the player is facing. If he's
  ; holding more than one direction, this picks one.
ROM5:B390 LDA walking_bits_2,Y
ROM5:B391 CMP object_direction
ROM5:B392 BEQ update_link_walking_speed ; Branch if the player is facing in the direction we chose.
ROM5:B393 ORA object_direction ; The player isn't moving in that direction.
 
  ; A = new walking direction | current walking direction
ROM5:B394 CMP #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM5:B395 BEQ vertical ; Check if the walking direction and the current direction
  ; are either both vertical or both horizontal.
ROM5:B396 CMP #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM5:B397 BNE no_movement
 
ROM5:B398 vertical: ; The walking direction and the current direction are either
ROM5:B398 LDA walking_bits_2,Y ; both vertical or both horizontal. Store the new movement
  ; direction as the object direction. This is always valid
  ; regardless of the tile offset, since changing direction on
  ; the same axis will never put us off-axis on multiple axes.
 
ROM5:B3A9 store_A_to_object_direction_and_walking_directions:
ROM5:B3A9 STA object_direction
 
ROM5:B3AB store_A_to_walking_directions:
ROM5:B3AB STA walking_directions
ROM5:B3AC RTS
 
ROM5:B3AD no_movement: ; We're not aligned to a tile, one or more directions are pressed, and the directions
ROM5:B3AD LDA number_of_extra_directions_pressed ; conflict with the tile axis we're moving on.
  ; Is more than one direction being pressed?
ROM5:B3AE BNE update_link_walking_speed ; Branch if more than one button is being pressed.
ROM5:B3AF LDA object_tile_offset_whole
ROM5:B3B0 JSR absolute_value ; A = abs(tile offset)
ROM5:B3B1 PHA ; Push abs(tile offset)
ROM5:B3B2 LDA object_direction
ROM5:B3B3 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM5:B3B4 STA var_1 ; Store the opposite of the facing direction.
ROM5:B3B5 PLA ; Restore abs(tile offset)
ROM5:B3B6 CMP #4
ROM5:B3B7 BCS ret2 ; Stop if abs(tile offset) >= 4.
ROM5:B3B8 LDA object_direction
ROM5:B3B9 AND #ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
ROM5:B3BA BEQ right_or_down ; Branch if right or down
ROM5:B3BB LDA object_tile_offset_whole
ROM5:B3BC BPL ret2 ; When we're facing left or up, stop if positive.
ROM5:B3BD BMI tile_offset_positive ; Always branch
 
ROM5:B3BE right_or_down:
ROM5:B3BE LDA object_tile_offset_whole
ROM5:B3BF BMI ret2 ; When we're facing right or down, stop if negative.
 
ROM5:B3C0 tile_offset_positive:
ROM5:B3C0 LDA var_1
ROM5:B3C1 STA object_direction ; var_1 is the opposite of the facing direction.
 
  ; Store this in object_direction, turning us around in
  ; the opposite direction.
ROM5:B3C2 LDA #8 ; A = 8 when the tile offset is negative.
ROM5:B3C3 LDY object_tile_offset_whole
ROM5:B3C4 BMI tile_offset_negative ; Branch if the tile offset is negative.
ROM5:B3C5 LDA #$F8 ; A = -8 when the tile offset is positive.
 
ROM5:B3C6 tile_offset_negative: ; Push A (-8 or +8).
ROM5:B3C6 PHA
ROM5:B3C7 TYA ; A = tile offset
ROM5:B3C8 JSR inverse ; var_1 = -tile_offset
ROM5:B3C9 STA var_1
ROM5:B3CA PLA ; Restore A (-8 or +8).
ROM5:B3CB SEC
ROM5:B3CC SBC var_1 ; object_tile_offset_whole = A - (-tile_offset)
ROM5:B3CD STA object_tile_offset_whole
 
ROM5:B3CE ret2:
ROM5:B3CE RTS
 
Subroutine check_if_stepped_onto_entrance
; Check if Link has stepped onto an entrance tile, like an ; overworld cave or dungeon entrance or a dungeon cellar ; entrance. If he has, update game_mode.
ROM5:B3F4 check_if_stepped_onto_entrance:
ROM5:B3F4 LDA is_in_cellar
ROM5:B3F5 ORA object_tile_offset_whole
ROM5:B3F6 BNE ret ; Stop if we're in a cellar, or not on a tile.
ROM5:B3F7 LDA dungeon_idx
ROM5:B3F8 BNE in_dungeon2
ROM5:B3F9 LDA map_location
ROM5:B3FA CMP #$22 ; Level 6 entrance
ROM5:B3FB BNE in_dungeon2
ROM5:B3FC LDA object_x ; In the overworld, require the X position be divisible by
  ; 8 (half tile).
ROM5:B3FD AND #7
ROM5:B3FE BNE ret
ROM5:B3FF BEQ tile_okay ; Skip the next block when on the overworld.
 
ROM5:B400 in_dungeon2: ; In dungeons, require the X position be divisible by
ROM5:B400 LDA object_x ; 16 (whole tile).
ROM5:B401 AND #$F
ROM5:B402 BNE ret
 
ROM5:B403 tile_okay:
ROM5:B403 LDA object_y
ROM5:B404 AND #$F
ROM5:B405 CMP #$D
ROM5:B406 BNE ret
ROM5:B407 JSR set_tile_walking_onto_1 ; Set tile_walking_onto for the current object.
ROM5:B408 LDA tile_walking_onto ; Check if 0x70 < walking_collision_flags <= 0x74
ROM5:B409 LDY dungeon_idx
ROM5:B40A BEQ overworld ; Branch if we're on the overworld.
ROM5:B40B CMP #$70
ROM5:B40C BCC ret
ROM5:B40D CMP #$74
ROM5:B40E BCS ret
ROM5:B40F JSR update_screen_kill_count
ROM5:B410 LDA map_location
ROM5:B411 STA map_location_in_dungeon_cellar ; Store the original map_location.
ROM5:B412 LDX #$FF
 
ROM5:B413 loop: ; Find the cellar index with this screen as an
ROM5:B413 INX ; exit. Cellars can have two exits.
ROM5:B414 LDA ppu_data_for_current_dungeon.stairs_loc,X
ROM5:B415 TAY
ROM5:B416 LDA map_location
ROM5:B417 CMP dungeon_screen_data_0,Y ; Check the left cellar exit screen number.
ROM5:B418 BEQ found_cellar
ROM5:B419 CMP dungeon_screen_data_1,Y ; Check the right cellar exit screen number.
ROM5:B41A BNE loop
 
ROM5:B41B found_cellar:
ROM5:B41B STY map_location
ROM5:B41C LDA #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
 
ROM5:B41D store_next_game_mode:
ROM5:B41D STA next_game_mode
ROM5:B41E CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM5:B41F BEQ in_cellar
ROM5:B420 JSR stop_sounds
ROM5:B421 STA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
ROM5:B422 STA recorder_lock_timer
 
ROM5:B423 in_cellar:
ROM5:B423 LDA #GameMode_EnteringDoor
ROM5:B424 STA game_mode ; set GameMode_EnteringStairs
ROM5:B425 JSR disable_greyscale
ROM5:B426 JMP clear_task_state
 
ROM5:B464 update_screen_kill_count:
ROM5:B464 LDA dungeon_idx
ROM5:B465 BNE in_dungeon
ROM5:B466 JMP update_overworld_screen_kill_count
 
ROM5:B467 in_dungeon:
ROM5:B467 JSR update_dungeon_screen_kill_count
 
ROM5:B468 ret:
ROM5:B468 RTS
 
ROM5:B469 overworld: ; Set to walking_collision_flags.
ROM5:B469 STA link_most_recent_overworld_tile_type
ROM5:B46A CMP #OverworldTiles_CaveOrDungeonEntrance
ROM5:B46B BEQ switch_to_overworld_cellar
ROM5:B46C CMP #$88
ROM5:B46D BEQ switch_to_overworld_cellar
ROM5:B46E CMP #$70
ROM5:B46F BCC ret ; room < 0x70
ROM5:B470 CMP #$74
ROM5:B471 BCS ret ; room >= 0x74
ROM5:B472 LDA #$70
ROM5:B473 STA tile_walking_onto ; Set to 0x70
 
ROM5:B474 switch_to_overworld_cellar:
ROM5:B474 JSR update_screen_kill_count
ROM5:B475 LDY map_location
ROM5:B476 LDA dungeon_screen_data_1,Y
ROM5:B477 AND #ScreenDataOverworld_1_CaveDestination
ROM5:B478 CMP #$40
ROM5:B479 BCC entering_dungeon ; If the door ID < 0x40, this is a dungeon entrance.
ROM5:B47A LDY #GameMode_InOverworldCellar ; We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal.
  ; The map location doesn't change.
ROM5:B47B CMP #OverworldCaveDestinations_TakeAnyRoad ; "Take any road" entrance goes to GameMode_ExitingOverworldCellar
  ; instead.
ROM5:B47C BNE not_take_any_road
ROM5:B47D INY ; next_game_mode is GameMode_ExitingOverworldCellar instead.
 
ROM5:B47E not_take_any_road:
ROM5:B47E TYA
ROM5:B47F JMP store_next_game_mode
 
ROM5:B480 entering_dungeon: ; We're entering a dungeon entrance. Shift 0x11111100 -> 0x00111111 to get the dungeon number.
ROM5:B480 LSR A
ROM5:B481 LSR A
ROM5:B482 STA dungeon_idx ; Store the dungeon number when entering a dungeon.
ROM5:B483 LDA map_location
ROM5:B484 STA overworld_return_pos ; Store the overworld position to return to when exiting the dungeon.
ROM5:B485 LDA #GameMode_LoadDungeon
ROM5:B486 BNE store_next_game_mode ; A = GameMode_DelayBeforeCurtainsOpening
 
Subroutine check_sram
ROM5:B4AC check_sram:
ROM5:B4AC LDA sram_check_byte
ROM5:B4AD CMP #$5A
ROM5:B4AE BNE wipe_sram
ROM5:B4AF LDA sram_check_byte2
ROM5:B4B0 CMP #$A5
ROM5:B4B1 BEQ loc_174E6
 
ROM5:B4B2 wipe_sram: ; Wipe SRAM if 0x6001 != 0x5A or 0x7FFF != 0xA5.
ROM5:B4B2 LDA #$FF
ROM5:B4B3 STA byte_2652A ; Store 0xFF
ROM5:B4B4 STA byte_2652B ; Store 0xFF
ROM5:B4B5 STA byte_2652C ; Store 0xFF
ROM5:B4B6 LDA #$65
ROM5:B4B7 STA var_1
ROM5:B4B8 LDA #$30
ROM5:B4B9 STA var_0
ROM5:B4BA LDY #0
 
ROM5:B4BB wipe_sram_loop: ; clear 0x6530 ... 0x65B0
ROM5:B4BB LDA #0
ROM5:B4BC STA (0),Y
ROM5:B4BD LDA var_0
ROM5:B4BE CLC
ROM5:B4BF ADC #1
ROM5:B4C0 STA var_0
ROM5:B4C1 LDA var_1
ROM5:B4C2 ADC #0
ROM5:B4C3 STA var_1
ROM5:B4C4 CMP #$80
ROM5:B4C5 BNE wipe_sram_loop ; clear 0x6530 ... 0x65B0
ROM5:B4C6 SEC
ROM5:B4C7 RTS
 
ROM5:B4E6 loc_174E6:
ROM5:B4E6 CLC
ROM5:B4E7 RTS
 
Subroutine init_memory
ROM5:B4E8 init_memory:
ROM5:B4E8 LDA #7
ROM5:B4E9 LDY #$FE
ROM5:B4EA JSR reset_room_state
ROM5:B4EB LDA #0
ROM5:B4EC STA ppu_unknown_task_returns_to_ROM4 ; Set to 0
ROM5:B4ED STA sprite_data_1_initialized ; Set to 0
ROM5:B4EE STA sprite_data_2_initialized ; Set to 0
ROM5:B4EF STA byte_F3 ; Set to 0
ROM5:B4F0 LDY #$EF
 
ROM5:B4F1 init_memory_loop:
ROM5:B4F1 STA var_0,Y
ROM5:B4F2 DEY
ROM5:B4F3 CPY #$FF
ROM5:B4F4 BNE init_memory_loop
ROM5:B4F5 LDA #$40
ROM5:B4F6 STA spawn_from_side_position ; Set to 0x40
ROM5:B4F7 STA prng_0 ; Set to 0x40
ROM5:B4F8 LDA #1
ROM5:B4F9 STA byte_636 ; Set to 1
ROM5:B4FA STA byte_637 ; Set to 1
ROM5:B4FB RTS
 
ROM5:B513 map_transition_offsets: .BYTE $F0
ROM5:B514   .BYTE $10
ROM5:B515   .BYTE $FF
ROM5:B516   .BYTE 1
 
Subroutine task0_Scrolling_1_subtask_no_transition
ROM5:B517 task0_Scrolling_1_subtask_no_transition:
ROM5:B517 LDA #0
ROM5:B518 STA transitioning_direction ; Set to 0.
ROM5:B519 RTS
 
Function chunk for task0_Scrolling_1_subtask_0
ROM5:B51A next_direction: ; Shift var_0 to the next direction.
ROM5:B51A ASL var_0
ROM5:B51B DEX ; Decrement the loop counter.
ROM5:B51C JMP loop
 
Subroutine task0_Scrolling_1_subtask_0
ROM5:B522 task0_Scrolling_1_subtask_0:
 
ROM5:B522 LDA #ControllerBits_Dpad_Right
ROM5:B523 STA var_0 ; Set to ControllerBits_Dpad_Right.
ROM5:B524 LDX #3 ; Set to 3.
 
ROM5:B525 loop: ; Set X to the first bit set in byte_E7.
ROM5:B525 LDA transitioning_direction
ROM5:B526 BIT var_0
ROM5:B527 BEQ next_direction ; Branch if (byte_E7 & var_0) == 0
ROM5:B528 JSR dungeon_get_screen_code ; Set A to the screen code of the current location when in a dungeon.
ROM5:B529 STA byte_4E4 ; Set to the current screen code. Where is this used?
ROM5:B52A LDA map_transition_offsets,X ; Add map_transition_offsets[X] + map_location to get the
  ; map_location we're transitioning to.
ROM5:B52B CLC
ROM5:B52C ADC map_location
ROM5:B52D STA map_location_transitioning_to ; Store the new map location that we're transitioning into.
ROM5:B52E LDA dungeon_idx
ROM5:B52F BNE in_dungeon
ROM5:B530 JSR check_lost_woods_code ; If we're in the lost woods or lost hills, check the direction
  ; code. If we're repeating the room, change map_location_transitioning_to.
 
ROM5:B531 in_dungeon:
ROM5:B531 LDA map_location_transitioning_to
ROM5:B532 BPL disable_greyscale
 
ROM5:B547 exit_dungeon_after_triforce_fanfare:
ROM5:B547 JSR clear_game_mode_task_and_state
ROM5:B548 STA transitioning_direction ; Set to 0
ROM5:B549 STA dungeon_idx
ROM5:B54A LDA #GameMode_LoadDungeon
ROM5:B54B STA game_mode
ROM5:B54C STA is_in_cellar ; Set to GameMode_LoadDungeon (2).
ROM5:B54D LDA #Sound3_Stop
ROM5:B54E STA play_sound_3
 
ROM5:B559 disable_greyscale: ; Load to clear greyscale
ROM5:B559 LDA current_ppumask
ROM5:B55A AND #PPUMaskBits_BackgroundOnLeft8PX|PPUMaskBits_SpritesOnLeft8PX|PPUMaskBits_ShowBackground|PPUMaskBits_ShowSprites|PPUMaskBits_EmphasizeRed|PPUMaskBits_EmphasizeGreen|PPUMaskBits_EmphasizeBlue
ROM5:B55B STA current_ppumask ; &= 0xFE
ROM5:B55C RTS
 
Subroutine sub_17560
ROM5:B560 sub_17560:
ROM5:B560 LDX #1
ROM5:B561 STX var_0
ROM5:B562 LDX #3
 
ROM5:B563 loop:
ROM5:B563 BIT var_0
ROM5:B564 BNE finish
ROM5:B565 ASL var_0
ROM5:B566 DEX
ROM5:B567 JMP loop
 
ROM5:B568 finish:
ROM5:B568 LDA map_transition_offsets,X
ROM5:B569 CLC
ROM5:B56A ADC map_location
ROM5:B56B RTS
 
ROM5:B577 minimap_data_bits: .BYTE $80
ROM5:B578   .BYTE $40
ROM5:B579   .BYTE $20
ROM5:B57A   .BYTE $10
ROM5:B57B   .BYTE 8
ROM5:B57C   .BYTE 4
ROM5:B57D   .BYTE 2
ROM5:B57E   .BYTE 1
 
Subroutine send_start_menu_map_ppu_commands
; This sends PPU commands to draw the big map in the start menu.
ROM5:B57F send_start_menu_map_ppu_commands:
ROM5:B57F LDY #$10
ROM5:B580 LDA start_menu_scroll_progress
ROM5:B581 LSR A
ROM5:B582 TAX
ROM5:B583 LDA #$FF
ROM5:B584 STA ppu_command_buffer_03,Y
ROM5:B585 LDA #$10
ROM5:B586 STA ppu_command_buffer_02
ROM5:B587 LDA #$28
ROM5:B588 STA ppu_command_buffer
ROM5:B589 LDA #$EC
 
ROM5:B58A loop:
ROM5:B58A CLC
ROM5:B58B ADC #$20
ROM5:B58C BCC loc_1759E
ROM5:B58D INC ppu_command_buffer
 
ROM5:B59E loc_1759E:
ROM5:B59E DEX
ROM5:B59F BPL loop
ROM5:B5A0 STA ppu_command_buffer_01
ROM5:B5A1 LDA start_menu_scroll_drawing_map_position ; The map location of the start menu map that's currently
  ; being drawn.
ROM5:B5A2 PHA
 
ROM5:B5A3 loop2:
ROM5:B5A3 JSR send_start_menu_map_ppu_commands_helper
ROM5:B5A4 DEC start_menu_scroll_drawing_map_position ; The map location of the start menu map that's currently
  ; being drawn.
ROM5:B5A5 DEY
ROM5:B5A6 BNE loop2
ROM5:B5A7 PLA
ROM5:B5A8 SEC
ROM5:B5A9 SBC #$10
ROM5:B5AA STA start_menu_scroll_drawing_map_position ; The map location of the start menu map that's currently
  ; being drawn.
ROM5:B5AB LDX ppu_data_for_current_dungeon.map_start_pos_x
 
ROM5:B5AC loop3:
ROM5:B5AC BEQ continue
ROM5:B5AD LDA byte_314
ROM5:B5AE PHA
ROM5:B5AF LDY #$E
 
ROM5:B5B0 loop4:
ROM5:B5B0 LDA ppu_command_buffer_03,Y
ROM5:B5B1 STA ppu_command_buffer_04,Y
ROM5:B5B2 DEY
ROM5:B5B3 BPL loop4
ROM5:B5B4 PLA
ROM5:B5B5 STA ppu_command_buffer_03
ROM5:B5B6 DEX
ROM5:B5B7 JMP loop3
 
ROM5:B5B8 continue:
ROM5:B5B8 LDA start_menu_scroll_progress
ROM5:B5B9 SEC
ROM5:B5BA SBC #$1A
ROM5:B5BB LSR A
ROM5:B5BC TAX
ROM5:B5BD LDY #$F
 
ROM5:B5BE loop5:
ROM5:B5BE LDA ppu_data_for_current_dungeon.minimap_data,Y
ROM5:B5BF AND minimap_data_bits,X
ROM5:B5C0 BNE minimap_screen_visible
ROM5:B5C1 LDA #$F5
ROM5:B5C2 STA ppu_command_buffer_03,Y
 
ROM5:B5C3 minimap_screen_visible:
ROM5:B5C3 DEY
ROM5:B5C4 BPL loop5
ROM5:B5C5 RTS
 
Subroutine check_has_compass_in_current_dungeon
; Set not equal if we have the compass for this dungeon.
ROM5:B5EB check_has_compass_in_current_dungeon:
ROM5:B5EB LDX #$10
ROM5:B5EC BNE skip ; Always branches
 
ROM5:B5EF check_has_map_in_current_dungeon: ; Set not equal if we have the map for this dungeon.
ROM5:B5EF LDX #$11
 
ROM5:B5F0 skip:
ROM5:B5F0 LDA dungeon_idx
ROM5:B5F1 BEQ on_overworld ; Skip if we're on the overworld.
ROM5:B5F2 SEC
ROM5:B5F3 SBC #1 ; A = dungeon_idx - 1
ROM5:B5F4 CMP #8
ROM5:B5F5 BCC not_in_death_mountain ; Check if we're in dungeon 9 (death mountain).
ROM5:B5F6 INX ; In dungeon 9, skip from have_compass_per_dungeon to have_compass_dungeon_9.
ROM5:B5F7 INX
 
ROM5:B5F8 not_in_death_mountain:
ROM5:B5F8 AND #7
ROM5:B5F9 TAY
ROM5:B5FA LDA sword_type,X ; sword_type+0x10 is have_compass_per_dungeon.
ROM5:B5FB AND powers_of_two,Y
 
ROM5:B5FC on_overworld:
ROM5:B5FC RTS
 
Subroutine send_start_menu_map_ppu_commands_helper
ROM5:B608 send_start_menu_map_ppu_commands_helper:
ROM5:B608 TYA
ROM5:B609 PHA ; Save Y
ROM5:B60A JSR get_screen_status ; Out Y = map location
  ; Out A = screen status for the current screen
  ; Out var_0 = pointer to screen status for this dungeon
  ; Bits 0x0F (dungeons): direction mask for bombed/opened doors
  ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM5:B60B LDA map_location
ROM5:B60C PHA ; Save map_location
ROM5:B60D LDA start_menu_scroll_drawing_map_position ; The map location of the start menu map that's currently
  ; being drawn.
ROM5:B60E STA map_location ; Set map_location to the map screen we're drawing, since the
  ; code we're calling expects to work on the current screen.
  ; This is restored below when we're done.
ROM5:B60F LDA #$13
ROM5:B610 STA currently_open_doors ; Set to 0x13.
ROM5:B611 LDY map_location
ROM5:B612 LDA (var_0),Y
ROM5:B613 AND #ScreenStatusDungeon_Visited
ROM5:B614 BEQ skip ; Branch if this room hasn't been visited.
ROM5:B615 LDA #8
ROM5:B616 STA var_2 ; Used by get_dungeon_door_type
ROM5:B617 LDX #3
 
ROM5:B618 loop: ; Set A to the door type we're facing.
ROM5:B618 JSR get_dungeon_door_type
  ; In var_2: a bitmask for the directions the caller wants.
ROM5:B619 JSR update_currently_open_doors ; Shift 0x01 into currently_open_doors if there's an open
  ; door or bomb wall in the direction contained in X
  ; (a direction index) is open, otherwise shift in 0x00.
 
  ; In X: direction bit
ROM5:B61A DEX
ROM5:B61B LSR var_2 ; Is var_2 used here except as a loop counter?
ROM5:B61C BNE loop
 
ROM5:B61D skip: ; Restore map_location
ROM5:B61D PLA
ROM5:B61E STA map_location
ROM5:B61F PLA ; Restore Y
ROM5:B620 TAY
ROM5:B621 LDA currently_open_doors ; Get the open door mask we created above, or 0x13 if
  ; this room hasn't been visited, which gives the tile for
  ; no room on the inventory screen map.
ROM5:B622 CLC
ROM5:B623 ADC #$E2 ; Offset from the direction mask (or 0x13) to a map tile.
ROM5:B624 STA ppu_command_buffer_02,Y
ROM5:B625 RTS
 
Subroutine update_currently_open_doors
; Shift 0x01 into currently_open_doors if there's an open ; door or bomb wall in the direction contained in X ; (a direction index) is open, otherwise shift in 0x00. ; ; In X: direction bit
ROM5:B641 update_currently_open_doors:
ROM5:B641 LDY #0 ; Y = 0
ROM5:B642 PHA ; Save A
ROM5:B643 CMP #DungeonDoor_BombWall
ROM5:B644 BCC door_wall_or_push ; Branch if Door, Wall, Push or PushSilent
ROM5:B645 TXA ; Otherwise, BombWall, LockedDoor, LockedDoor2 or ShutterDoor
ROM5:B646 PHA ; Save X
ROM5:B647 TYA
ROM5:B648 PHA ; Save Y
ROM5:B649 JSR get_screen_status ; Out Y = map location
  ; Out A = screen status for the current screen
  ; Out var_0 = pointer to screen status for this dungeon
  ; Bits 0x0F (dungeons): direction mask for bombed/opened doors
  ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM5:B64A CLC
ROM5:B64B AND powers_of_two,X
ROM5:B64C BEQ carry_clear ; Branch with carry clear if screen status bit X is zero
  ; (door is still locked).
ROM5:B64D SEC
 
ROM5:B64E carry_clear:
ROM5:B64E PLA
ROM5:B64F TAY ; Restore Y
ROM5:B650 PLA
ROM5:B651 TAX ; Restore X
 
ROM5:B652 shift_into_currently_open_doors: ; Carry is set if the door in this direction is open.
ROM5:B652 LDA currently_open_doors,Y
ROM5:B653 ROL A ; Rotate the carry we set or cleared into byte_33F.
  ; Y is always 0, so this indirection isn't used.
ROM5:B654 AND #$F
ROM5:B655 STA currently_open_doors,Y
ROM5:B656 PLA ; Restore A
ROM5:B657 RTS
 
ROM5:B658 door_wall_or_push:
ROM5:B658 CMP #DungeonDoor_Door
ROM5:B659 BEQ shift_into_currently_open_doors ; If DungeonDoor_Door, branch with carry set.
ROM5:B65A CLC
ROM5:B65B BCC shift_into_currently_open_doors ; Always branch (with carry clear)
 
Subroutine add_screen_status_to_unlocked_door_directions
; Add the direction bits set in unlocked_door_directions to screen_status, eg. ScreenStatus_WallOpened_*.
ROM5:B66C add_screen_status_to_unlocked_door_directions:
ROM5:B66C JSR get_screen_status ; Load to set direction bits from unlocked_door_directions.
ROM5:B66D LDX #3
 
ROM5:B66E loop:
ROM5:B66E LDA (var_0),Y
ROM5:B66F AND powers_of_two,X
ROM5:B670 BEQ skip
ROM5:B671 ORA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM5:B672 STA unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
 
ROM5:B673 skip:
ROM5:B673 DEX
ROM5:B674 BPL loop
ROM5:B675 RTS
 
ROM5:B676   .BYTE $A5
ROM5:B677   .BYTE $EB
ROM5:B678   .BYTE $48
ROM5:B679   .BYTE $29
ROM5:B67A   .BYTE $F
ROM5:B67B   .BYTE $A8
ROM5:B67C   .BYTE $68
ROM5:B67D   .BYTE $4A
ROM5:B67E   .BYTE $4A
ROM5:B67F   .BYTE $4A
ROM5:B680   .BYTE $4A
ROM5:B681   .BYTE $AA
ROM5:B682   .BYTE $60
 
Subroutine check_if_dark
ROM5:B68D check_if_dark:
ROM5:B68D LDA dungeon_idx
ROM5:B68E BEQ on_overworld
ROM5:B68F LDA dungeon_screen_data_4,Y
ROM5:B690 AND #ScreenData_Dungeon_4_Dark
 
ROM5:B691 on_overworld:
ROM5:B691 RTS
 
ROM5:B697 byte_17697: .BYTE $80
ROM5:B698   .BYTE $98
ROM5:B699   .BYTE $AC
ROM5:B69A   .BYTE $B4
ROM5:B69B   .BYTE $C8
ROM5:B69C   .BYTE $80
ROM5:B69D   .BYTE $98
ROM5:B69E   .BYTE $B0
ROM5:B69F   .BYTE $C8
ROM5:B6A0   .BYTE $80
ROM5:B6A1   .BYTE $94
ROM5:B6A2   .BYTE $A0
ROM5:B6A3   .BYTE $B0
ROM5:B6A4   .BYTE $C0
ROM5:B6A5   .BYTE $CC
ROM5:B6A6   .BYTE $B0
 
Subroutine show_menu_8_1
; This is related to drawing the inventory sprites on the start menu.
ROM5:B6A7 show_menu_8_1:
ROM5:B6A7 LDX #InventoryItem_MagicBoomerang
 
ROM5:B6A8 loop: ; Find the boomerang type we have.
ROM5:B6A8 LDA sword_type,X
ROM5:B6A9 BNE found_boomerang_type
ROM5:B6AA DEX
ROM5:B6AB CPX #$1C
ROM5:B6AC BNE loop
ROM5:B6AD BEQ no_boomerang ; Always branch
 
ROM5:B6AE found_boomerang_type:
ROM5:B6AE LDA #$36
ROM5:B6AF STA var_1
ROM5:B6B0 LDA #$80
ROM5:B6B1 STA var_0
ROM5:B6B2 TXA
ROM5:B6B3 TAY
ROM5:B6B4 JSR update_inventory_item_sprite
 
ROM5:B6B5 no_boomerang:
ROM5:B6B5 LDX #InventoryItem_Bomb
 
ROM5:B6C4 loc_176C4:
ROM5:B6C4 LDA sword_type,X
ROM5:B6C5 CPX #InventoryItem_Compass
ROM5:B6C6 BNE check_map
ROM5:B6C7 JSR check_has_compass_in_current_dungeon ; Set not equal if we have the compass for this dungeon.
ROM5:B6C8 LDX #InventoryItem_Compass
 
ROM5:B6C9 check_map:
ROM5:B6C9 CPX #InventoryItem_Map
ROM5:B6CA BNE loc_176D9
ROM5:B6CB JSR check_has_map_in_current_dungeon ; Set not equal if we have the map for this dungeon.
ROM5:B6CC LDX #InventoryItem_Map
 
ROM5:B6D9 loc_176D9:
ROM5:B6D9 CMP #InventoryItem_Sword
ROM5:B6DA BEQ loc_17717
ROM5:B6DB CPX #InventoryItem_Letter
ROM5:B6DC BNE loc_176E6
ROM5:B6DD LDA have_potion_type
ROM5:B6DE BNE loc_17717
 
ROM5:B6E6 loc_176E6:
ROM5:B6E6 TXA
ROM5:B6E7 PHA
ROM5:B6E8 TAY
ROM5:B6E9 LDA byte_17697,X
ROM5:B6EA STA var_0
ROM5:B6EB LDA #$36
ROM5:B6EC CPX #5
ROM5:B6ED BCC loc_17710
ROM5:B6EE LDA #$46
ROM5:B6EF CPX #$F
ROM5:B6F0 BEQ loc_17710
ROM5:B6F1 CPX #9
ROM5:B6F2 BCC loc_17710
ROM5:B6F3 LDA #$1E
ROM5:B6F4 CPX #$10
ROM5:B6F5 BCC loc_17710
ROM5:B6F6 LDA #$2C
ROM5:B6F7 STA var_0
ROM5:B6F8 LDA #$9E
ROM5:B6F9 CPX #$11
ROM5:B6FA BCC loc_17710
ROM5:B6FB LDA #$76
 
ROM5:B710 loc_17710:
ROM5:B710 STA var_1
ROM5:B711 JSR loc_1781C
ROM5:B712 PLA
ROM5:B713 TAX
 
ROM5:B717 loc_17717:
ROM5:B717 INX
ROM5:B718 CPX #$12
ROM5:B719 BCC loc_176C4
ROM5:B71A RTS
 
ROM5:B71D byte_1771D: .BYTE $80
ROM5:B71E   .BYTE $98
ROM5:B71F   .BYTE $B0
ROM5:B720   .BYTE $B0
ROM5:B721   .BYTE $C8
ROM5:B722   .BYTE $80
ROM5:B723   .BYTE $98
ROM5:B724   .BYTE $B0
ROM5:B725   .BYTE $C8
 
Subroutine show_menu_8_2
; This is related to drawing the inventory sprites on the start menu.
ROM5:B726 show_menu_8_2:
ROM5:B726 LDX current_item
ROM5:B727 BNE has_boomerang1 ; Branch if not 0 (boomerang)
ROM5:B728 LDX #InventoryItem_MagicBoomerang
 
ROM5:B729 boomerang_loop1: ; The player has the boomerang selected. See if he actually has
ROM5:B729 LDA sword_type,X ; inventory item 0x1E (magic boomerang) or 0x1D (boomerang).
  ; This is a special case because the inventory for the boomerang
  ; flags isn't in the same place as other inventory items.
ROM5:B72A BNE has_boomerang1 ; Branch if he has this item
ROM5:B72B DEX
ROM5:B72C CPX #$1C
ROM5:B72D BNE boomerang_loop1 ; If he doesn't have this boomerang, check the other one.
ROM5:B72E BEQ loc_17756 ; He doesn't have either.
 
ROM5:B72F has_boomerang1:
ROM5:B72F LDA sword_type,X
ROM5:B730 BEQ loc_17756 ; Branch if he doesn't have this item
ROM5:B731 CPX #InventoryItem_Letter ; Branch if not potion (sword_type + 0x0F is the potion inventory slot)
ROM5:B732 BNE not_letter
ROM5:B733 LDA have_potion_type
ROM5:B734 BNE loc_17756 ; Branch if he doesn't have any potion
ROM5:B735 LDA #1
 
ROM5:B736 not_letter:
ROM5:B736 STA var_4
ROM5:B737 LDA #$36
ROM5:B738 STA var_1
ROM5:B739 LDA #$40
ROM5:B73A STA var_0
ROM5:B73B JSR loc_1781C
 
ROM5:B756 loc_17756:
ROM5:B756 LDY current_item
ROM5:B757 CPY #InventoryItem_Letter
ROM5:B758 BNE loc_17767
ROM5:B759 LDY #InventoryItem_Potion
ROM5:B75A LDA sword_type,Y
ROM5:B75B BEQ loc_17767
ROM5:B75C STY current_item
 
ROM5:B767 loc_17767:
ROM5:B767 LDA byte_1771D,Y
ROM5:B768 STA sprite_oam_data_1F
ROM5:B769 CLC
ROM5:B76A ADC #8
ROM5:B76B STA sprite_oam_data_23
ROM5:B76C LDA #$36
ROM5:B76D CPY #5
ROM5:B76E BCC loc_1777B
ROM5:B76F LDA #$46
 
ROM5:B77B loc_1777B:
ROM5:B77B STA sprite_oam_data_1C
ROM5:B77C STA sprite_oam_data_20
ROM5:B77D LDA #$1E
ROM5:B77E STA sprite_oam_data_1D
ROM5:B77F STA sprite_oam_data_21
ROM5:B780 LDA frame_counter
ROM5:B781 AND #8
ROM5:B782 LSR A
ROM5:B783 LSR A
ROM5:B784 LSR A
ROM5:B785 ADC #1
ROM5:B786 STA sprite_oam_data_1E
ROM5:B787 ORA #$40
ROM5:B788 STA sprite_oam_data_22
ROM5:B789 LDA walking_directions
ROM5:B78A CMP byte_EF
ROM5:B78B BEQ locret_177F1
ROM5:B78C TAX
ROM5:B78D BEQ loc_177C8
ROM5:B78E CPX #4
ROM5:B78F BCS loc_177C8
ROM5:B790 LDX #Sound1_Rupee
ROM5:B791 STX play_sound_1 ; Set to a nonzero value to play a one-off sound effect
ROM5:B792 TAX
ROM5:B793 LDA current_item
ROM5:B794 PHA
ROM5:B795 TXA
ROM5:B796 JSR loc_177C8
ROM5:B797 PLA
ROM5:B798 CMP current_item
ROM5:B799 BEQ loc_177C4
ROM5:B79A LDY current_item
ROM5:B79B LDA sword_type,Y
ROM5:B79C BNE locret_177C7
 
ROM5:B7C4 loc_177C4: ; Set to a nonzero value to play a one-off sound effect
ROM5:B7C4 LSR play_sound_1
 
ROM5:B7C7 locret_177C7:
ROM5:B7C7 RTS
 
ROM5:B7C8 loc_177C8:
ROM5:B7C8 STA byte_EF
ROM5:B7C9 LDX #9
 
ROM5:B7CC loc_177CC:
ROM5:B7CC JSR show_menu_8_2_1
ROM5:B7CD CPY #InventoryItem_Sword
ROM5:B7CE BEQ loc_177F2
ROM5:B7CF CPY #InventoryItem_Bow
ROM5:B7D0 BEQ check_bow
ROM5:B7D1 LDA sword_type,Y
ROM5:B7D2 BNE loc_177E5
ROM5:B7D3 CPY #InventoryItem_Potion
ROM5:B7D4 BEQ check_potion
 
ROM5:B7D5 check_bow:
ROM5:B7D5 DEX
ROM5:B7D6 BPL loc_177CC
ROM5:B7D7 LDY #0
 
ROM5:B7E5 loc_177E5:
ROM5:B7E5 CPY #InventoryItem_Arrow
ROM5:B7E6 BNE select_item_in_Y
ROM5:B7E7 LDA have_bow
ROM5:B7E8 BEQ loc_177CC
 
ROM5:B7E9 select_item_in_Y:
ROM5:B7E9 STY current_item
 
ROM5:B7F1 locret_177F1:
ROM5:B7F1 RTS
 
ROM5:B7F2 loc_177F2: ; Check if we have the magic boomerang, and if we don't
ROM5:B7F2 LDY #InventoryItem_MagicBoomerang ; have that, check if we have the regular boomerang.
 
ROM5:B7F3 boomerang_loop:
ROM5:B7F3 LDA sword_type,Y
ROM5:B7F4 BNE has_boomerang
ROM5:B7F5 DEY
ROM5:B7F6 CPY #InventoryItem_5Rupee
ROM5:B7F7 BNE boomerang_loop
ROM5:B7F8 LDY #0 ; We don't have the boomerang. Check the bow next.
ROM5:B7F9 JMP check_bow
 
ROM5:B7FA has_boomerang:
ROM5:B7FA LDY #0
ROM5:B7FB JMP loc_177E5
 
ROM5:B7FC check_potion: ; The potion is selected. Check if we have the letter.
ROM5:B7FC LDY #InventoryItem_Letter
ROM5:B7FD LDA sword_type,Y
ROM5:B7FE BNE has_letter
ROM5:B7FF LDY #InventoryItem_Potion
ROM5:B800 BNE check_bow
 
ROM5:B801 has_letter: ; Check if we have either potion.
ROM5:B801 LDA have_potion_type
ROM5:B802 BEQ select_item_in_Y ; If we don't, select the letter.
ROM5:B803 LDY #InventoryItem_Potion ; If we do have the potion, select it.
ROM5:B804 BNE select_item_in_Y
 
ROM5:B81C loc_1781C:
ROM5:B81C TXA
ROM5:B81D TAY
ROM5:B81E JMP update_inventory_item_sprite
 
Subroutine show_menu_8_2_1
ROM5:B821 show_menu_8_2_1:
ROM5:B821 LDA byte_EF
ROM5:B822 AND #3
ROM5:B823 BEQ ret
ROM5:B824 INY
ROM5:B825 LSR A
ROM5:B826 BCS loc_1782D
ROM5:B827 DEY
ROM5:B828 DEY
 
ROM5:B82D loc_1782D:
ROM5:B82D CPY #$FF
ROM5:B82E BNE loc_17833
ROM5:B82F LDY #8
 
ROM5:B833 loc_17833:
ROM5:B833 CPY #9
ROM5:B834 BNE ret
ROM5:B835 LDY #0
 
ROM5:B836 ret:
ROM5:B836 RTS
 
Subroutine setup_room_items
ROM5:B83A setup_room_items:
ROM5:B83A LDA #0
ROM5:B83B STA current_room_floor_item_hidden ; Set to 0
ROM5:B83C LDA dungeon_idx
ROM5:B83D BEQ in_overworld ; This is a special case for the coast heart container in overworld location 0x5F.
ROM5:B83E JSR get_room_status_floor_item_picked_up
ROM5:B83F BNE hide_floor_item ; Branch if the floor item on this room has already been taken.
ROM5:B840 LDY map_location
ROM5:B841 LDA dungeon_screen_data_4,Y ; Load to check if this is the magical sword
ROM5:B842 AND #ScreenData_Dungeon_4_Item
ROM5:B843 CMP #FloorItem_MagicalSword
ROM5:B844 BNE not_magical_sword
ROM5:B845 DEC current_room_floor_item_hidden ; Set to 0xFF if this is the magical sword. (What's actually happening here? We're
  ; in the dungeon code path, and the magical sword doesn't appear in dungeons.)
 
ROM5:B846 not_magical_sword:
ROM5:B846 STA current_floor_item
ROM5:B847 LDA dungeon_screen_data_5,Y
ROM5:B848 AND #ScreenData_Dungeon_5_KillingEverythingOpensDoorAndSpawnsItem
ROM5:B849 CMP #ScreenData_Dungeon_5_GanonTriforceOpensDoors
ROM5:B84A BEQ hide_floor_item
ROM5:B84B CMP #ScreenData_Dungeon_5_KillingEverythingOpensDoorAndSpawnsItem
ROM5:B84C BNE skip_hide_floor_item
 
ROM5:B84D hide_floor_item: ; Set to 0xFF to hide the floor item.
ROM5:B84D DEC current_room_floor_item_hidden
 
ROM5:B84E skip_hide_floor_item:
ROM5:B84E LDA dungeon_screen_data_3,Y
ROM5:B84F AND #ScreenData_Dungeon_3_PushBlock
ROM5:B850 BEQ no_push_block
ROM5:B851 JSR sub_167F1
 
ROM5:B852 no_push_block: ; Get this room's item position: A = X position, Y = Y position
ROM5:B852 JSR dungeon_get_item_position
 
ROM5:B853 overworld_heart:
ROM5:B853 STA floor_item_x
ROM5:B854 STY floor_item_y
ROM5:B855 LDY map_location
ROM5:B856 LDA dungeon_screen_data_4,Y ; Check if the floor item is a triforce piece.
ROM5:B857 AND #ScreenData_Dungeon_4_Item
ROM5:B858 CMP #FloorItem_TriforcePiece
ROM5:B859 BNE ret
ROM5:B85A LDA floor_item_x ; This is a triforce piece. Move the item left 8 pixels, so it lies between the tiles instead of on one.
ROM5:B85B SEC
ROM5:B85C SBC #8
ROM5:B85D STA floor_item_x
 
ROM5:B85E ret:
ROM5:B85E RTS
 
ROM5:B85F in_overworld: ; This is a special case for the coast heart container in overworld location 0x5F.
ROM5:B85F LDA #FloorItem_HeartContainer
ROM5:B860 STA current_floor_item ; set to FloorItem_HeartContainer
ROM5:B861 LDA #$C0 ; X position of the heart container
ROM5:B862 LDY #$90 ; Y position of the heart container
ROM5:B863 LDX game_mode
ROM5:B864 CPX #GameMode_Normal
ROM5:B865 BNE not_normal_gameplay
ROM5:B866 LDX map_location
ROM5:B867 CPX #$5F
ROM5:B868 BEQ overworld_heart
 
ROM5:B869 not_normal_gameplay:
ROM5:B869 DEC current_room_floor_item_hidden
ROM5:B86A RTS
 
ROM5:B86B Skipped empty chunk
Subroutine rom5_OnReset
ROM5:BF50 rom5_OnReset:
ROM5:BF50 SEI
ROM5:BF51 CLD
ROM5:BF52 LDA #0
ROM5:BF53 STA $2000
ROM5:BF54 LDX #$FF
ROM5:BF55 TXS
 
ROM5:BF5A loc_17F5A:
ROM5:BF5A LDA PPUSTATUS
ROM5:BF5B AND #$80
ROM5:BF5C BEQ loc_17F5A
 
ROM5:BF61 loc_17F61:
ROM5:BF61 LDA PPUSTATUS
ROM5:BF62 AND #$80
ROM5:BF63 BEQ loc_17F61
ROM5:BF64 ORA #$FF
ROM5:BF65 STA update_start_menu
ROM5:BF66 STA byte_16000
ROM5:BF67 STA $C000
ROM5:BF68 STA $E000
ROM5:BF69 LDA #$F
ROM5:BF6A JSR rom5_set_mmc_control_register
ROM5:BF6B LDA #0
ROM5:BF6C STA byte_16000
ROM5:BF6D LSR A
ROM5:BF6E STA byte_16000
ROM5:BF6F LSR A
ROM5:BF70 STA byte_16000
ROM5:BF71 LSR A
ROM5:BF72 STA byte_16000
ROM5:BF73 LSR A
ROM5:BF74 STA byte_16000
ROM5:BF75 LDA #7
ROM5:BF76 JSR rom5_set_prg_bank
ROM5:BF77 JMP continue_setup
 
Subroutine rom5_set_mmc_control_register
ROM5:BF98 rom5_set_mmc_control_register:
ROM5:BF98 STA rom2_sprite_data_ptrs ; $8000
ROM5:BF99 LSR A
ROM5:BF9A STA rom2_sprite_data_ptrs
ROM5:BF9B LSR A
ROM5:BF9C STA rom2_sprite_data_ptrs
ROM5:BF9D LSR A
ROM5:BF9E STA rom2_sprite_data_ptrs
ROM5:BF9F LSR A
ROM5:BFA0 STA rom2_sprite_data_ptrs
ROM5:BFA1 RTS
 
Subroutine rom5_set_prg_bank
ROM5:BFAC rom5_set_prg_bank:
ROM5:BFAC STA $E000
ROM5:BFAD LSR A
ROM5:BFAE STA $E000
ROM5:BFAF LSR A
ROM5:BFB0 STA $E000
ROM5:BFB1 LSR A
ROM5:BFB2 STA $E000
ROM5:BFB3 LSR A
ROM5:BFB4 STA $E000
ROM5:BFB5 RTS
 
ROM5:BFB6 Skipped empty chunk
 
Segment: ROM6
ROM6:8000 dungeon_screen_attr_1Q: .WORD dungeon_screen_attr_overworld
ROM6:8002   .WORD dungeon_screen_attr_1Q_1
ROM6:8004   .WORD dungeon_screen_attr_1Q_1
ROM6:8006   .WORD dungeon_screen_attr_1Q_1
ROM6:8008   .WORD dungeon_screen_attr_1Q_1
ROM6:800A   .WORD dungeon_screen_attr_1Q_1
ROM6:800C   .WORD dungeon_screen_attr_1Q_1
ROM6:800E   .WORD dungeon_screen_attr_1Q_2
ROM6:8010   .WORD dungeon_screen_attr_1Q_2
ROM6:8012   .WORD dungeon_screen_attr_1Q_2
ROM6:8014 dungeon_data_pointers: .WORD dungeon_data_overworld
ROM6:8016   .WORD dungeon_data_1
ROM6:8018   .WORD dungeon_data_2
ROM6:801A   .WORD dungeon_data_3
ROM6:801C   .WORD dungeon_data_4
ROM6:801E   .WORD dungeon_data_5
ROM6:8020   .WORD dungeon_data_6
ROM6:8022   .WORD dungeon_data_7
ROM6:8024   .WORD dungeon_data_8
ROM6:8026   .WORD dungeon_data_9
ROM6:8028 some_ppu_palette_pointer: .WORD some_ppu_data_0 ; This is copied to copied_ppu_data (SRAM:67F0) by copy_some_ppu_data.
  ; PPU addr: 0x3F00 (palettes)
ROM6:802A dungeon_screen_attr_2Q: .WORD dungeon_screen_attr_overworld
ROM6:802C   .WORD dungeon_screen_attr_2Q_1
ROM6:802E   .WORD dungeon_screen_attr_2Q_1
ROM6:8030   .WORD dungeon_screen_attr_2Q_1
ROM6:8032   .WORD dungeon_screen_attr_2Q_1
ROM6:8034   .WORD dungeon_screen_attr_2Q_1
ROM6:8036   .WORD dungeon_screen_attr_2Q_1
ROM6:8038   .WORD dungeon_screen_attr_2Q_2
ROM6:803A   .WORD dungeon_screen_attr_2Q_2
ROM6:803C   .WORD dungeon_screen_attr_2Q_2
 
Subroutine setup_dungeon
ROM6:803E setup_dungeon:
ROM6:803E LDA task_state
ROM6:803F JSR call_jump_table
 
ROM6:8040   .WORD setup_dungeon_screen_attr
ROM6:8042   .WORD setup_dungeon_data
 
Subroutine setup_dungeon_screen_attr
ROM6:8047 setup_dungeon_screen_attr:
ROM6:8047 LDA dungeon_idx
ROM6:8048 ASL A
ROM6:8049 TAX
ROM6:804A LDY current_save_slot
ROM6:804B LDA quest_no,Y ; Check if this game is second quest
ROM6:804C BNE second_quest ; Load pointer to screen attributes for this dungeon, 2nd quest
ROM6:804D LDA dungeon_screen_attr_1Q,X ; Load pointer to screen attributes for this dungeon, 1st quest
ROM6:804E STA var_0
ROM6:804F INX
ROM6:8050 LDA dungeon_screen_attr_1Q,X
ROM6:8051 JMP not_second_quest ; High byte to screen attributes pointer
 
ROM6:8052 second_quest: ; Load pointer to screen attributes for this dungeon, 2nd quest
ROM6:8052 LDA dungeon_screen_attr_2Q,X
ROM6:8053 STA var_0
ROM6:8054 INX
ROM6:8055 LDA dungeon_screen_attr_2Q,X
 
ROM6:8056 not_second_quest: ; High byte to screen attributes pointer
ROM6:8056 STA var_1
ROM6:8057 JSR set_copy_to_0x687E ; Set var_2-5 to [0x687E,0x6B7D]
ROM6:8058 JSR copy_dungeon_data ; var_0-1 is a pointer to the screen attributes to load.
  ; var_2-3 is a pointer to where we should copy them.
  ; var_4-5 is a pointer to the last byte to copy, relative to var_2.
ROM6:8059 RTS
 
Subroutine setup_dungeon_data
ROM6:8070 setup_dungeon_data:
ROM6:8070 LDA dungeon_idx
ROM6:8071 ASL A
ROM6:8072 TAX
ROM6:8073 LDA dungeon_data_pointers,X
ROM6:8074 STA var_0
ROM6:8075 INX
ROM6:8076 LDA dungeon_data_pointers,X
ROM6:8077 STA var_1
ROM6:8078 JSR set_copy_to_0x6B7E ; Set var_2-5 to [0x6B7E,0x6C7D]
ROM6:8079 JSR copy_dungeon_data ; var_0-1 is a pointer to the screen attributes to load.
  ; var_2-3 is a pointer to where we should copy them.
  ; var_4-5 is a pointer to the last byte to copy, relative to var_2.
ROM6:807A LDA #0
ROM6:807B STA task_state
ROM6:807C INC active_game_mode_task ; If 0, we run task0 for the current game_mode. If 1, we run task1.
ROM6:807D RTS
 
Subroutine copy_some_ppu_data
ROM6:808C copy_some_ppu_data:
ROM6:808C LDX #0
ROM6:808D LDA some_ppu_palette_pointer,X ; Only one entry, X is always 0
ROM6:808E STA var_0
ROM6:808F INX
ROM6:8090 LDA some_ppu_palette_pointer,X ; X = 0
ROM6:8091 STA var_1
ROM6:8092 JSR set_copy_to_0x67F0 ; Set var_2-5 to [0x67F0,0x687D]
ROM6:8093 JSR copy_dungeon_data ; var_0-1 is a pointer to the screen attributes to load.
  ; var_2-3 is a pointer to where we should copy them.
  ; var_4-5 is a pointer to the last byte to copy, relative to var_2.
ROM6:8094 LDA #0
ROM6:8095 STA task_state
ROM6:8096 RTS
 
Subroutine set_copy_to_0x687E
; Set var_2-5 to [0x687E,0x6B7D]
ROM6:80A4 set_copy_to_0x687E:
ROM6:80A4 LDA #$7E
ROM6:80A5 STA var_2
ROM6:80A6 LDA #$68
ROM6:80A7 STA var_3
ROM6:80A8 LDA #$7D
ROM6:80A9 STA var_4
ROM6:80AA LDA #$6B
ROM6:80AB STA var_5
ROM6:80AC RTS
 
Subroutine set_copy_to_0x6B7E
; Set var_2-5 to [0x6B7E,0x6C7D]
ROM6:80B5 set_copy_to_0x6B7E:
ROM6:80B5 LDA #$7E
ROM6:80B6 STA var_2
ROM6:80B7 LDA #$6B
ROM6:80B8 STA var_3
ROM6:80B9 LDA #$7D
ROM6:80BA STA var_4
ROM6:80BB LDA #$6C
ROM6:80BC STA var_5
ROM6:80BD RTS
 
Subroutine set_copy_to_0x67F0
; Set var_2-5 to [0x67F0,0x687D]
ROM6:80C6 set_copy_to_0x67F0:
ROM6:80C6 LDA #$F0
ROM6:80C7 STA var_2
ROM6:80C8 LDA #$67
ROM6:80C9 STA var_3
ROM6:80CA LDA #$7D
ROM6:80CB STA var_4
ROM6:80CC LDA #$68
ROM6:80CD STA var_5
ROM6:80CE RTS
 
Subroutine copy_dungeon_data
; var_0-1 is a pointer to the screen attributes to load. ; var_2-3 is a pointer to where we should copy them. ; var_4-5 is a pointer to the last byte to copy, relative to var_2.
ROM6:80D7 copy_dungeon_data:
ROM6:80D7 LDY #0
 
ROM6:80D8 loop: ; Copy a byte.
ROM6:80D8 LDA (var_0),Y
ROM6:80D9 STA (var_2),Y
ROM6:80DA LDA var_2 ; See if we just copied var_4.
ROM6:80DB CMP var_4
ROM6:80DC BNE loc_180EC
ROM6:80DD LDA var_3
ROM6:80DE CMP var_5
ROM6:80DF BNE loc_180EC
ROM6:80E0 INC task_state ; We've finished copying.
ROM6:80E1 RTS
 
ROM6:80EC loc_180EC: ; 16-bit increment var_2.
ROM6:80EC LDA var_2
ROM6:80ED CLC
ROM6:80EE ADC #1
ROM6:80EF STA var_2
ROM6:80F0 LDA var_3
ROM6:80F1 ADC #0
ROM6:80F2 STA var_3
ROM6:80F3 LDA var_0 ; 16-bit increment var_0.
ROM6:80F4 CLC
ROM6:80F5 ADC #1
ROM6:80F6 STA var_0
ROM6:80F7 LDA var_1
ROM6:80F8 ADC #0
ROM6:80F9 STA var_1
ROM6:80FA JMP loop
 
Subroutine task1_LoadDungeon_main
; Make some changes to map data for 2nd quest.
ROM6:8109 task1_LoadDungeon_main:
ROM6:8109 LDY current_save_slot
ROM6:810A LDA quest_no,Y
ROM6:810B BEQ locret_1812C ; Branch if 1st quest
ROM6:810C LDA dungeon_idx
ROM6:810D BEQ loc_1812D ; Branch if overworld
ROM6:810E TAX ; X = dungeon
ROM6:810F ASL A
ROM6:8110 TAY ; Y = dungeon*2
ROM6:8111 LDA second_quest_patch_data,Y
ROM6:8112 STA var_0
ROM6:8113 LDA second_quest_patch_data+1,Y
ROM6:8114 STA var_1
ROM6:8115 LDY second_quest_patch_data_size+1,X
 
ROM6:8116 patch_map_data_for_second_quest:
ROM6:8116 LDA (0),Y
ROM6:8117 STA ppu_data_for_current_dungeon.stair_or_item_pos,Y
ROM6:8118 DEY
ROM6:8119 BPL patch_map_data_for_second_quest
 
ROM6:812C locret_1812C:
ROM6:812C RTS
 
ROM6:812D loc_1812D:
ROM6:812D LDY #7
 
ROM6:812E loop:
ROM6:812E LDX second_quest_overworld_patch_offsets,Y
ROM6:812F LDA second_quest_overworld_patch_data,Y
ROM6:8130 STA dungeon_screen_data_1,X
ROM6:8131 DEY
ROM6:8132 BPL loop
ROM6:8133 LDA #$7B
ROM6:8134 STA dungeon_screen_data_3+$B
ROM6:8135 LDA #$7B
ROM6:8136 STA dungeon_screen_data_3+$3C
ROM6:8137 LDA #$5A
ROM6:8138 STA dungeon_screen_data_3+$74
ROM6:8139 LDA #$72
ROM6:813A STA dungeon_screen_data_0+$3C ; This is copied from dungeon_screen_attr_1Q_1, etc.
ROM6:813B LDA #$72
ROM6:813C STA dungeon_screen_data_0+$74 ; This is copied from dungeon_screen_attr_1Q_1, etc.
ROM6:813D LDA #1
ROM6:813E STA dungeon_screen_data_5+$3C
ROM6:813F LDA #0
ROM6:8140 STA dungeon_screen_data_5+$74
ROM6:8141 RTS
 
ROM6:815F second_quest_overworld_patch_offsets: .BYTE $E
ROM6:8160   .BYTE $F
ROM6:8161   .BYTE $22
ROM6:8162   .BYTE $34
ROM6:8163   .BYTE $3C
ROM6:8164   .BYTE $45
ROM6:8165   .BYTE $74
ROM6:8166   .BYTE $8B
ROM6:8167 second_quest_overworld_patch_data: .BYTE $7B
ROM6:8168   .BYTE $83
ROM6:8169   .BYTE $84
ROM6:816A   .BYTE $F
ROM6:816B   .BYTE $B
ROM6:816C   .BYTE $12
ROM6:816D   .BYTE $7A
ROM6:816E   .BYTE $2F
ROM6:816F second_quest_patch_data_1:
ROM6:81A8 second_quest_patch_data_2:
ROM6:81DF second_quest_patch_data_3:
ROM6:821C second_quest_patch_data_4:
ROM6:8255 second_quest_patch_data_5:
ROM6:8298 second_quest_patch_data_6:
ROM6:82D8 second_quest_patch_data_7:
ROM6:8317 second_quest_patch_data_8:
ROM6:835A second_quest_patch_data_9:
ROM6:83A2 second_quest_patch_data: .WORD $FFFF
ROM6:83A4   .WORD second_quest_patch_data_1
ROM6:83A6   .WORD second_quest_patch_data_2
ROM6:83A8   .WORD second_quest_patch_data_3
ROM6:83AA   .WORD second_quest_patch_data_4
ROM6:83AC   .WORD second_quest_patch_data_5
ROM6:83AE   .WORD second_quest_patch_data_6
ROM6:83B0   .WORD second_quest_patch_data_7
ROM6:83B2   .WORD second_quest_patch_data_8
ROM6:83B4 second_quest_patch_data_size: .WORD second_quest_patch_data_9
ROM6:83B6   .BYTE $39
ROM6:83B7   .BYTE $37
ROM6:83B8   .BYTE $3D
ROM6:83B9   .BYTE $39
ROM6:83BA   .BYTE $43
ROM6:83BB   .BYTE $40
ROM6:83BC   .BYTE $3F
ROM6:83BD   .BYTE $43
ROM6:83BE   .BYTE $4A
ROM6:83BF Skipped empty chunk
ROM6:8400 dungeon_screen_attr_overworld:
ROM6:8700 dungeon_screen_attr_1Q_1:
ROM6:8A00 dungeon_screen_attr_1Q_2:
ROM6:8D00 dungeon_screen_attr_2Q_1:
ROM6:9000 dungeon_screen_attr_2Q_2:
ROM6:9300 dungeon_data_overworld: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:9303   .BYTE $F $30 0 $12 $F $16 $27 $36 $F $1A $37 ; ppu_data
ROM6:930E   .BYTE $12 $F $17 $37 $12 $F $29 $27 $17 $F 2 ; ppu_data
ROM6:9319   .BYTE $22 $30 $F $16 $27 $30 $F $C $1C $2C ; ppu_data
ROM6:9323   .BYTE $FF ; ppu_end_ff
ROM6:9324   .BYTE 1 4 5 6 ; enemy_count
ROM6:9328   .BYTE $8D ; start_y_pos
ROM6:9329   .BYTE $57 $49 $99 $69 ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:932D   .BYTE 0 ; map_start_pos_x
ROM6:932E   .BYTE 0 ; map_pos_x
ROM6:932F   .BYTE $77 ; start_loc
ROM6:9330   .BYTE $2A ; triforce_loc
ROM6:9331   .WORD $67F ; screen_status_ptr
ROM6:9333   .BYTE 0 ; displayed_level_number
ROM6:9334   .BYTE $1D $23 $49 $79 $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:933E   .BYTE $2A ; boss_loc
ROM6:933F   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; minimap_data
ROM6:9349   .BYTE $FF $FF $FF $FF $FF $FF ; minimap_data
ROM6:934F   .BYTE $20 $62 $48 $F5 $20 $82 $48 $F5 ; ppu_0
ROM6:9357   .BYTE $20 $A2 $48 $F5 $20 $C2 $48 $F5 ; ppu_1
ROM6:935F   .BYTE $FF $FF $FF $FF $FF $FF ; ppu_2
ROM6:9365   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:936F   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9379   .BYTE $FF $FF $FF ; padding
ROM6:937C   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_enter_stairway
ROM6:9386   .BYTE $FF $FF $FF $FF $FF $FF ; palette_enter_stairway
ROM6:938C   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:9396   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93A0   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93AA   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93B4   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93BE   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93C8   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93D2   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; palette_exit_stairway
ROM6:93DC   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:93E8   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:93F6   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:93FC dungeon_data_1: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:93FF   .BYTE $F $30 0 $12 $F $16 $27 $36 $F $C $1C ; ppu_data
ROM6:940A   .BYTE $2C $F $12 $1C $2C $F $29 $27 $17 $F 2 ; ppu_data
ROM6:9415   .BYTE $22 $30 $F $16 $27 $30 $F $C $1C $2C ; ppu_data
ROM6:941F   .BYTE $FF ; ppu_end_ff
ROM6:9420   .BYTE 3 5 6 8 ; enemy_count
ROM6:9424   .BYTE $DD ; start_y_pos
ROM6:9425   .BYTE $C9 $AC $89 $87 ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9429   .BYTE 4 ; map_start_pos_x
ROM6:942A   .BYTE 0 ; map_pos_x
ROM6:942B   .BYTE $73 ; start_loc
ROM6:942C   .BYTE $36 ; triforce_loc
ROM6:942D   .WORD $6FF ; screen_status_ptr
ROM6:942F   .BYTE 1 ; displayed_level_number
ROM6:9430   .BYTE $7F $FF $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:943A   .BYTE $35 ; boss_loc
ROM6:943B   .BYTE 0 0 0 0 0 8 $2D $3F $D $18 $10 0 0 0 ; minimap_data
ROM6:9449   .BYTE 0 0 ; minimap_data
ROM6:944B   .BYTE $20 $84 5 $67 $FF $24 $FB $FB ; ppu_0
ROM6:9453   .BYTE $20 $A3 5 $67 $FF $FF $FF $67 ; ppu_1
ROM6:945B   .BYTE $20 $C4 3 $FB $FF $FB ; ppu_2
ROM6:9461   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:946B   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9475   .BYTE $FF $FF $FF ; padding
ROM6:9478   .BYTE $F $C $1C $2C $F $12 $1C $2C $F $C $C ; palette_enter_stairway
ROM6:9483   .BYTE $1C $F $11 $C $1C ; palette_enter_stairway
ROM6:9488   .BYTE $F $F $C $C $F 2 $C $C $F $F $F $F $F ; palette_exit_stairway
ROM6:9495   .BYTE $F $F $F $F 0 $10 $30 $F 0 $10 $30 $F ; palette_exit_stairway
ROM6:94A1   .BYTE 0 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 ; palette_exit_stairway
ROM6:94AF   .BYTE 0 $F $F $F $F $F $F $F $F $F $C $1C $2C ; palette_exit_stairway
ROM6:94BC   .BYTE $F $12 $1C $2C $F $C $C $1C $F $11 $C ; palette_exit_stairway
ROM6:94C7   .BYTE $1C $F $F $C $C $F 2 $C $C $F $F $F $C ; palette_exit_stairway
ROM6:94D4   .BYTE $F $F $F $F ; palette_exit_stairway
ROM6:94D8   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:94E4   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:94F2   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:94F8 dungeon_data_2: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:94FB   .BYTE $F $30 0 $12 $F $16 $27 $36 $F 2 $12 $22 ; ppu_data
ROM6:9507   .BYTE $F $16 $12 $22 $F $29 $27 $17 $F 2 $22 ; ppu_data
ROM6:9512   .BYTE $30 $F $16 $27 $30 $F 2 $12 $22 ; ppu_data
ROM6:951B   .BYTE $FF ; ppu_end_ff
ROM6:951C   .BYTE 3 5 6 8 ; enemy_count
ROM6:9520   .BYTE $DD ; start_y_pos
ROM6:9521   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9525   .BYTE $A ; map_start_pos_x
ROM6:9526   .BYTE $B0 ; map_pos_x
ROM6:9527   .BYTE $7D ; start_loc
ROM6:9528   .BYTE $D ; triforce_loc
ROM6:9529   .WORD $6FF ; screen_status_ptr
ROM6:952B   .BYTE 2 ; displayed_level_number
ROM6:952C   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:9536   .BYTE $E ; boss_loc
ROM6:9537   .BYTE 0 0 0 0 0 0 2 $83 $FF $7E 0 0 0 0 0 ; minimap_data
ROM6:9546   .BYTE 0 ; minimap_data
ROM6:9547   .BYTE $20 $65 3 $67 $FF $FB $20 $86 ; ppu_0
ROM6:954F   .BYTE 2 $FF $FF $20 $A6 2 $FF $FF ; ppu_1
ROM6:9557   .BYTE $20 $C4 4 $67 $FF $FF ; ppu_2
ROM6:955D   .BYTE $67 $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9567   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9571   .BYTE $FF $FF $FF ; padding
ROM6:9574   .BYTE $F 2 $12 $22 $F $16 $12 $22 $F 1 2 $12 ; palette_enter_stairway
ROM6:9580   .BYTE $F $17 2 $12 ; palette_enter_stairway
ROM6:9584   .BYTE $F $F 1 2 $F 6 1 2 $F $F $F $F $F $F ; palette_exit_stairway
ROM6:9592   .BYTE $F $F $F 0 $10 $30 $F 0 $10 $30 $F 0 ; palette_exit_stairway
ROM6:959E   .BYTE 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 0 ; palette_exit_stairway
ROM6:95AC   .BYTE $F $F $F $F $F $F $F $F $F 2 $12 $22 ; palette_exit_stairway
ROM6:95B8   .BYTE $F $16 $12 $22 $F 1 2 $12 $F $17 2 $12 ; palette_exit_stairway
ROM6:95C4   .BYTE $F $F 1 2 $F 6 1 2 $F $F $F 1 $F $F ; palette_exit_stairway
ROM6:95D2   .BYTE $F $F ; palette_exit_stairway
ROM6:95D4   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:95E0   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:95EE   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:95F4 dungeon_data_3: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:95F7   .BYTE $F $30 0 $12 $F $16 $27 $36 $F $B $1B ; ppu_data
ROM6:9602   .BYTE $2B $F $16 $1B $2B $F $29 $37 $17 $F 2 ; ppu_data
ROM6:960D   .BYTE $22 $30 $F $16 $27 $30 $F $B $1B $2B ; ppu_data
ROM6:9617   .BYTE $FF ; ppu_end_ff
ROM6:9618   .BYTE 3 5 6 8 ; enemy_count
ROM6:961C   .BYTE $DD ; start_y_pos
ROM6:961D   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9621   .BYTE $C ; map_start_pos_x
ROM6:9622   .BYTE $C0 ; map_pos_x
ROM6:9623   .BYTE $7C ; start_loc
ROM6:9624   .BYTE $3D ; triforce_loc
ROM6:9625   .WORD $6FF ; screen_status_ptr
ROM6:9627   .BYTE 3 ; displayed_level_number
ROM6:9628   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:9632   .BYTE $4D ; boss_loc
ROM6:9633   .BYTE 0 0 0 0 0 $E $2C $3F $D $1C 0 0 0 0 ; minimap_data
ROM6:9641   .BYTE 0 0 ; minimap_data
ROM6:9643   .BYTE $20 $84 4 $67 $FF $24 $FB $20 ; ppu_0
ROM6:964B   .BYTE $A3 5 $FF $FF $FF $FF $FF $20 ; ppu_1
ROM6:9653   .BYTE $C3 4 $67 $24 $FF $FB ; ppu_2
ROM6:9659   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9663   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:966D   .BYTE $FF $FF $FF ; padding
ROM6:9670   .BYTE $F $B $1B $2B $F $16 $1B $2B $F $B $B ; palette_enter_stairway
ROM6:967B   .BYTE $1B $F $17 $B $1B ; palette_enter_stairway
ROM6:9680   .BYTE $F $F $B $B $F 6 $B $B $F $F $F $F $F ; palette_exit_stairway
ROM6:968D   .BYTE $F $F $F $F 0 $10 $30 $F 0 $10 $30 $F ; palette_exit_stairway
ROM6:9699   .BYTE 0 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 ; palette_exit_stairway
ROM6:96A7   .BYTE 0 $F $F $F $F $F $F $F $F $F $B $1B $2B ; palette_exit_stairway
ROM6:96B4   .BYTE $F $16 $1B $2B $F $B $B $1B $F $17 $B ; palette_exit_stairway
ROM6:96BF   .BYTE $1B $F $F $B $B $F 6 $B $B $F $F $F $B ; palette_exit_stairway
ROM6:96CC   .BYTE $F $F $F $F ; palette_exit_stairway
ROM6:96D0   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:96DC   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:96EA   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:96F0 dungeon_data_4: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:96F3   .BYTE $F $30 0 $12 $F $16 $27 $36 $F 8 $18 $28 ; ppu_data
ROM6:96FF   .BYTE $F $12 $18 $28 $F $29 $27 $17 $F 2 $22 ; ppu_data
ROM6:970A   .BYTE $30 $F $16 $27 $30 $F $F $18 $28 ; ppu_data
ROM6:9713   .BYTE $FF ; ppu_end_ff
ROM6:9714   .BYTE 3 5 6 8 ; enemy_count
ROM6:9718   .BYTE $DD ; start_y_pos
ROM6:9719   .BYTE $DC $99 $88 $89 ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:971D   .BYTE 6 ; map_start_pos_x
ROM6:971E   .BYTE $10 ; map_pos_x
ROM6:971F   .BYTE $71 ; start_loc
ROM6:9720   .BYTE 3 ; triforce_loc
ROM6:9721   .WORD $6FF ; screen_status_ptr
ROM6:9723   .BYTE 4 ; displayed_level_number
ROM6:9724   .BYTE $60 $FF $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:972E   .BYTE $13 ; boss_loc
ROM6:972F   .BYTE 0 0 0 0 0 0 $FD $B7 $D2 $C0 0 0 0 0 ; minimap_data
ROM6:973D   .BYTE 0 0 ; minimap_data
ROM6:973F   .BYTE $20 $64 4 $FF $67 $FF $FF $20 ; ppu_0
ROM6:9747   .BYTE $84 3 $FF $FF $FB $20 $A4 2 ; ppu_1
ROM6:974F   .BYTE $FF $FB $20 $C4 3 $FB ; ppu_2
ROM6:9755   .BYTE $FF $67 $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:975F   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9769   .BYTE $FF $FF $FF ; padding
ROM6:976C   .BYTE $F 8 $18 $28 $F $12 $18 $28 $F 8 8 $18 ; palette_enter_stairway
ROM6:9778   .BYTE $F $11 8 $18 ; palette_enter_stairway
ROM6:977C   .BYTE $F $F 8 8 $F 2 8 8 $F $F $F $F $F $F ; palette_exit_stairway
ROM6:978A   .BYTE $F $F $F 0 $10 $30 $F 0 $10 $30 $F 0 ; palette_exit_stairway
ROM6:9796   .BYTE 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 0 ; palette_exit_stairway
ROM6:97A4   .BYTE $F $F $F $F $F $F $F $F $F 8 $18 $28 ; palette_exit_stairway
ROM6:97B0   .BYTE $F $12 $18 $28 $F 8 8 $18 $F $11 8 $18 ; palette_exit_stairway
ROM6:97BC   .BYTE $F $F 8 8 $F 2 8 8 $F $F $F 8 $F $F ; palette_exit_stairway
ROM6:97CA   .BYTE $F $F ; palette_exit_stairway
ROM6:97CC   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:97D8   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:97E6   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:97EC dungeon_data_5: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:97EF   .BYTE $F $30 0 $12 $F $16 $27 $36 $F $A $1A ; ppu_data
ROM6:97FA   .BYTE $2A $F $16 $1A $2A $F $29 $27 $17 $F 2 ; ppu_data
ROM6:9805   .BYTE $22 $30 $F $16 $27 $30 $F $A $1A $2A ; ppu_data
ROM6:980F   .BYTE $FF ; ppu_end_ff
ROM6:9810   .BYTE 3 5 6 8 ; enemy_count
ROM6:9814   .BYTE $DD ; start_y_pos
ROM6:9815   .BYTE $87 $C8 $8A $89 ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9819   .BYTE 2 ; map_start_pos_x
ROM6:981A   .BYTE $F0 ; map_pos_x
ROM6:981B   .BYTE $76 ; start_loc
ROM6:981C   .BYTE $14 ; triforce_loc
ROM6:981D   .WORD $6FF ; screen_status_ptr
ROM6:981F   .BYTE 5 ; displayed_level_number
ROM6:9820   .BYTE 7 4 $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:982A   .BYTE $24 ; boss_loc
ROM6:982B   .BYTE 0 0 0 0 0 0 $72 $A6 $EF $7F 0 0 0 0 ; minimap_data
ROM6:9839   .BYTE 0 0 ; minimap_data
ROM6:983B   .BYTE $20 $64 4 $FB $67 $FF $FB $20 ; ppu_0
ROM6:9843   .BYTE $84 4 $FF $67 $67 $FF $20 $A5 ; ppu_1
ROM6:984B   .BYTE 3 $FB $FF $FF $20 $C4 ; ppu_2
ROM6:9851   .BYTE 4 $67 $67 $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:985C   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9866   .BYTE $FF $FF ; padding
ROM6:9868   .BYTE $F $A $1A $2A $F $16 $1A $2A $F $A $A ; palette_enter_stairway
ROM6:9873   .BYTE $1A $F $17 $A $1A ; palette_enter_stairway
ROM6:9878   .BYTE $F $F $A $A $F 6 $A $A $F $F $F $F $F ; palette_exit_stairway
ROM6:9885   .BYTE $F $F $F $F 0 $10 $30 $F 0 $10 $30 $F ; palette_exit_stairway
ROM6:9891   .BYTE 0 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 ; palette_exit_stairway
ROM6:989F   .BYTE 0 $F $F $F $F $F $F $F $F $F $A $1A $2A ; palette_exit_stairway
ROM6:98AC   .BYTE $F $16 $1A $2A $F $A $A $1A $F $17 $A ; palette_exit_stairway
ROM6:98B7   .BYTE $1A $F $F $A $A $F 6 $A $A $F $F $F $A ; palette_exit_stairway
ROM6:98C4   .BYTE $F $F $F $F ; palette_exit_stairway
ROM6:98C8   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:98D4   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:98E2   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:98E8 dungeon_data_6: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:98EB   .BYTE $F $30 0 $12 $F $16 $27 $36 $F 8 $18 $28 ; ppu_data
ROM6:98F7   .BYTE $F $16 $18 $28 $F $29 $27 $17 $F 2 $22 ; ppu_data
ROM6:9902   .BYTE $30 $F $16 $27 $30 $F 8 $18 $28 ; ppu_data
ROM6:990B   .BYTE $FF ; ppu_end_ff
ROM6:990C   .BYTE 3 5 6 8 ; enemy_count
ROM6:9910   .BYTE $DD ; start_y_pos
ROM6:9911   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9915   .BYTE $D ; map_start_pos_x
ROM6:9916   .BYTE $C8 ; map_pos_x
ROM6:9917   .BYTE $79 ; start_loc
ROM6:9918   .BYTE $C ; triforce_loc
ROM6:9919   .WORD $6FF ; screen_status_ptr
ROM6:991B   .BYTE 6 ; displayed_level_number
ROM6:991C   .BYTE 8 $75 $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:9926   .BYTE $1C ; boss_loc
ROM6:9927   .BYTE 0 0 0 0 0 $7F $F1 $D3 $C0 $F0 $60 0 0 ; minimap_data
ROM6:9934   .BYTE 0 0 0 ; minimap_data
ROM6:9937   .BYTE $20 $63 6 $FB $FF $FF $FF $FF ; ppu_0
ROM6:993F   .BYTE $FB $20 $83 6 $FF $FF $FB $24 ; ppu_1
ROM6:9947   .BYTE $FF $67 $20 $A3 1 $FF ; ppu_2
ROM6:994D   .BYTE $20 $C3 3 $FF $FB $FF $FF $FF $FF $FF $FF ; padding
ROM6:9958   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9962   .BYTE $FF $FF ; padding
ROM6:9964   .BYTE $F 8 $18 $28 $F $16 $18 $28 $F 8 8 $18 ; palette_enter_stairway
ROM6:9970   .BYTE $F $17 8 $18 ; palette_enter_stairway
ROM6:9974   .BYTE $F $F 8 8 $F 6 8 8 $F $F $F $F $F $F ; palette_exit_stairway
ROM6:9982   .BYTE $F $F $F 0 $10 $30 $F 0 $10 $30 $F 0 ; palette_exit_stairway
ROM6:998E   .BYTE 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 0 ; palette_exit_stairway
ROM6:999C   .BYTE $F $F $F $F $F $F $F $F $F 8 $18 $28 ; palette_exit_stairway
ROM6:99A8   .BYTE $F $16 $18 $28 $F 8 8 $18 $F $17 8 $18 ; palette_exit_stairway
ROM6:99B4   .BYTE $F $F 8 8 $F 6 8 8 $F $F $F 8 $F $F ; palette_exit_stairway
ROM6:99C2   .BYTE $F $F ; palette_exit_stairway
ROM6:99C4   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:99D0   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:99DE   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:99E4 dungeon_data_7: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:99E7   .BYTE $F $30 0 $12 $F $16 $27 $36 $F $A $1A ; ppu_data
ROM6:99F2   .BYTE $2A $F $12 $1A $2A $F $29 $27 $17 $F 2 ; ppu_data
ROM6:99FD   .BYTE $22 $30 $F $16 $27 $30 $F $A $1A $2A ; ppu_data
ROM6:9A07   .BYTE $FF ; ppu_end_ff
ROM6:9A08   .BYTE 3 5 6 8 ; enemy_count
ROM6:9A0C   .BYTE $DD ; start_y_pos
ROM6:9A0D   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9A11   .BYTE $D ; map_start_pos_x
ROM6:9A12   .BYTE $C8 ; map_pos_x
ROM6:9A13   .BYTE $79 ; start_loc
ROM6:9A14   .BYTE $2B ; triforce_loc
ROM6:9A15   .WORD $77F ; screen_status_ptr
ROM6:9A17   .BYTE 7 ; displayed_level_number
ROM6:9A18   .BYTE $7B $4A $FF $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:9A22   .BYTE $2A ; boss_loc
ROM6:9A23   .BYTE 0 0 0 0 0 $7F $FF $B7 $E6 $C2 $82 0 0 ; minimap_data
ROM6:9A30   .BYTE 0 0 0 ; minimap_data
ROM6:9A33   .BYTE $20 $63 6 $FB $FF $67 $FF $FF ; ppu_0
ROM6:9A3B   .BYTE $67 $20 $83 4 $FF $FF $FF $67 ; ppu_1
ROM6:9A43   .BYTE $20 $A3 4 $FF $FF $FB ; ppu_2
ROM6:9A49   .BYTE $FB $20 $C3 6 $FF $FF $FF $67 $67 $67 $FF ; padding
ROM6:9A54   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9A5E   .BYTE $FF $FF ; padding
ROM6:9A60   .BYTE $F $A $1A $2A $F $12 $1A $2A $F $A $A ; palette_enter_stairway
ROM6:9A6B   .BYTE $1A $F $11 $A $1A ; palette_enter_stairway
ROM6:9A70   .BYTE $F $F $A $A $F 2 $A $A $F $F $F $F $F ; palette_exit_stairway
ROM6:9A7D   .BYTE $F $F $F $F 0 $10 $30 $F 0 $10 $30 $F ; palette_exit_stairway
ROM6:9A89   .BYTE 0 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 ; palette_exit_stairway
ROM6:9A97   .BYTE 0 $F $F $F $F $F $F $F $F $F $A $1A $2A ; palette_exit_stairway
ROM6:9AA4   .BYTE $F $12 $1A $2A $F $A $A $1A $F $11 $A ; palette_exit_stairway
ROM6:9AAF   .BYTE $1A $F $F $A $A $F 2 $A $A $F $F $F $A ; palette_exit_stairway
ROM6:9ABC   .BYTE $F $F $F $F ; palette_exit_stairway
ROM6:9AC0   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:9ACC   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:9ADA   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:9AE0 dungeon_data_8: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:9AE3   .BYTE $F $30 0 $12 $F $16 $27 $36 $F 0 $10 $30 ; ppu_data
ROM6:9AEF   .BYTE $F $22 $10 $30 $F $29 $27 $17 $F 2 $22 ; ppu_data
ROM6:9AFA   .BYTE $30 $F $16 $27 $30 $F 0 $10 $30 ; ppu_data
ROM6:9B03   .BYTE $FF ; ppu_end_ff
ROM6:9B04   .BYTE 3 5 6 8 ; enemy_count
ROM6:9B08   .BYTE $DD ; start_y_pos
ROM6:9B09   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9B0D   .BYTE $A ; map_start_pos_x
ROM6:9B0E   .BYTE $B0 ; map_pos_x
ROM6:9B0F   .BYTE $7E ; start_loc
ROM6:9B10   .BYTE $2C ; triforce_loc
ROM6:9B11   .WORD $77F ; screen_status_ptr
ROM6:9B13   .BYTE 8 ; displayed_level_number
ROM6:9B14   .BYTE $2F $F $6F $FF $FF $FF $FF $FF $FF $FF ; stairs_loc
ROM6:9B1E   .BYTE $3C ; boss_loc
ROM6:9B1F   .BYTE 0 0 0 0 0 $18 $3D $5D $FF $55 0 0 0 ; minimap_data
ROM6:9B2C   .BYTE 0 0 0 ; minimap_data
ROM6:9B2F   .BYTE $20 $65 3 $FB $FF $FB $20 $83 ; ppu_0
ROM6:9B37   .BYTE 5 $FB $FF $FB $FF $FB $20 $A3 ; ppu_1
ROM6:9B3F   .BYTE 5 $67 $FF $FF $FF $FB ; ppu_2
ROM6:9B45   .BYTE $20 $C4 4 $FB $FB $FF $FB $FF $FF $FF $FF ; padding
ROM6:9B50   .BYTE $FF $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9B5A   .BYTE $FF $FF ; padding
ROM6:9B5C   .BYTE $F 0 $10 $30 $F $22 $10 $30 $F 0 0 $10 ; palette_enter_stairway
ROM6:9B68   .BYTE $F $12 0 $10 ; palette_enter_stairway
ROM6:9B6C   .BYTE $F $F 0 0 $F 2 0 0 $F $F $F $F $F $F ; palette_exit_stairway
ROM6:9B7A   .BYTE $F $F $F 0 $10 $30 $F 0 $10 $30 $F 0 ; palette_exit_stairway
ROM6:9B86   .BYTE 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 0 ; palette_exit_stairway
ROM6:9B94   .BYTE $F $F $F $F $F $F $F $F $F 0 $10 $30 ; palette_exit_stairway
ROM6:9BA0   .BYTE $F $22 $10 $30 $F 0 0 $10 $F $12 0 $10 ; palette_exit_stairway
ROM6:9BAC   .BYTE $F $F 0 0 $F 2 0 0 $F $F $F 0 $F $F ; palette_exit_stairway
ROM6:9BBA   .BYTE $F $F ; palette_exit_stairway
ROM6:9BBC   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:9BC8   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:9BD6   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:9BDC dungeon_data_9: .BYTE $3F 0 $20 ; ppu_cmd_0
ROM6:9BDF   .BYTE $F $30 0 $12 $F $16 $27 $36 $F 0 $10 $30 ; ppu_data
ROM6:9BEB   .BYTE $F $16 $10 $30 $F $29 $27 $17 $F 2 $22 ; ppu_data
ROM6:9BF6   .BYTE $30 $F $16 $27 $30 $F $F $10 $30 ; ppu_data
ROM6:9BFF   .BYTE $FF ; ppu_end_ff
ROM6:9C00   .BYTE 3 5 6 8 ; enemy_count
ROM6:9C04   .BYTE $DD ; start_y_pos
ROM6:9C05   .BYTE $89 $D6 $26 $2C ; stair_or_item_pos
  ; 0xF0 is one coordinate, 0x0F is the other
ROM6:9C09   .BYTE 4 ; map_start_pos_x
ROM6:9C0A   .BYTE 0 ; map_pos_x
ROM6:9C0B   .BYTE $76 ; start_loc
ROM6:9C0C   .BYTE $32 ; triforce_loc
ROM6:9C0D   .WORD $77F ; screen_status_ptr
ROM6:9C0F   .BYTE 9 ; displayed_level_number
ROM6:9C10   .BYTE $60 $70 $72 $75 $67 $77 0 $4F $FF $FF ; stairs_loc
ROM6:9C1A   .BYTE $42 ; boss_loc
ROM6:9C1B   .BYTE 0 0 0 0 $7C $FF $EE $FF $FF $EE $FF $7C ; minimap_data
ROM6:9C27   .BYTE 0 0 0 0 ; minimap_data
ROM6:9C2B   .BYTE $20 $62 8 $FB $FF $FF $FF $FF ; ppu_0
ROM6:9C33   .BYTE $FF $FF $FB $20 $82 8 $FF $FF ; ppu_1
ROM6:9C3B   .BYTE $67 $FF $FF $67 $FF $FF ; ppu_2
ROM6:9C41   .BYTE $20 $A2 $48 $FF $20 $C3 6 $FF $67 $FF $FF ; padding
ROM6:9C4C   .BYTE $67 $FF $FF $FF $FF $FF $FF $FF $FF $FF ; padding
ROM6:9C56   .BYTE $FF $FF ; padding
ROM6:9C58   .BYTE $F 0 $10 $30 $F $16 $10 $30 $F 0 0 $10 ; palette_enter_stairway
ROM6:9C64   .BYTE $F $17 0 $10 ; palette_enter_stairway
ROM6:9C68   .BYTE $F $F 0 0 $F 6 0 0 $F $F $F $F $F $F ; palette_exit_stairway
ROM6:9C76   .BYTE $F $F $F 0 $10 $30 $F 0 $10 $30 $F 0 ; palette_exit_stairway
ROM6:9C82   .BYTE 0 $10 $F 0 0 $10 $F $F 0 0 $F $F 0 0 ; palette_exit_stairway
ROM6:9C90   .BYTE $F $F $F $F $F $F $F $F $F 0 $10 $30 ; palette_exit_stairway
ROM6:9C9C   .BYTE $F $16 $10 $30 $F 0 0 $10 $F $17 0 $10 ; palette_exit_stairway
ROM6:9CA8   .BYTE $F $F 0 0 $F 6 0 0 $F $F $F 0 $F $F ; palette_exit_stairway
ROM6:9CB6   .BYTE $F $F ; palette_exit_stairway
ROM6:9CB8   .BYTE $F 6 $17 $16 $F 6 $17 $16 $F 7 6 $16 ; palette_death
ROM6:9CC4   .BYTE $F 7 6 $16 $F $F 7 6 $F $F 7 6 $F $F ; palette_death
ROM6:9CD2   .BYTE $F $F $F $F $F $F ; palette_death
ROM6:9CD8 some_ppu_data_0: .WORD $3F ; This is copied to copied_ppu_data (SRAM:67F0) by copy_some_ppu_data.
  ; PPU addr: 0x3F00 (palettes)
ROM6:9CDA   .BYTE $20 ; Copy 0x20 bytes
ROM6:9CDB   .BYTE $F
ROM6:9CDC   .BYTE $30
ROM6:9CDD   .BYTE 0
ROM6:9CDE   .BYTE $12
ROM6:9CDF   .BYTE $F
ROM6:9CE0   .BYTE $16
ROM6:9CE1   .BYTE $27
ROM6:9CE2   .BYTE $36
ROM6:9CE3   .BYTE $F
ROM6:9CE4   .BYTE $C
ROM6:9CE5   .BYTE $1C
ROM6:9CE6   .BYTE $2C
ROM6:9CE7   .BYTE $F
ROM6:9CE8   .BYTE $12
ROM6:9CE9   .BYTE $1C
ROM6:9CEA   .BYTE $2C
ROM6:9CEB   .BYTE $F
ROM6:9CEC   .BYTE $29
ROM6:9CED   .BYTE $27
ROM6:9CEE   .BYTE 7
ROM6:9CEF   .BYTE $F
ROM6:9CF0   .BYTE $22
ROM6:9CF1   .BYTE $27
ROM6:9CF2   .BYTE 7
ROM6:9CF3   .BYTE $F
ROM6:9CF4   .BYTE $26
ROM6:9CF5   .BYTE $27
ROM6:9CF6   .BYTE 7
ROM6:9CF7   .BYTE $F
ROM6:9CF8   .BYTE $15
ROM6:9CF9   .BYTE $27
ROM6:9CFA   .BYTE $30
ROM6:9CFB   .BYTE $FF ; Terminator
ROM6:9CFC some_ppu_data_1: .WORD $1C3F ; PPU addr: 0x3F1C (sprite palette 3)
ROM6:9CFE   .BYTE 4 ; Copy 4 bytes
ROM6:9CFF   .BYTE $F
ROM6:9D00   .BYTE $F
ROM6:9D01   .BYTE $F
ROM6:9D02   .BYTE $F
ROM6:9D03   .BYTE $FF ; Terminator
ROM6:9D04 some_ppu_data_2: .WORD $4220 ; PPU addr: 0x2042
ROM6:9D06   .BYTE 7
ROM6:9D07   .BYTE $15
ROM6:9D08   .BYTE $E
ROM6:9D09   .BYTE $1F
ROM6:9D0A   .BYTE $E
ROM6:9D0B   .BYTE $15
ROM6:9D0C   .BYTE $62
ROM6:9D0D   .BYTE 0
ROM6:9D0E   .BYTE $FF
ROM6:9D0F   .BYTE $D8
ROM6:9D10   .BYTE $9B
ROM6:9D11   .BYTE $D
ROM6:9D12   .BYTE $9C
ROM6:9D13   .BYTE $3E
ROM6:9D14   .BYTE $9C
ROM6:9D15   .BYTE $80
ROM6:9D16   .BYTE $9C
ROM6:9D17   .BYTE $C4
ROM6:9D18   .BYTE $9C
ROM6:9D19   .BYTE $F6
ROM6:9D1A   .BYTE $9C
ROM6:9D1B   .BYTE $32
ROM6:9D1C   .BYTE $9D
ROM6:9D1D   .BYTE $6D
ROM6:9D1E   .BYTE $9D
ROM6:9D1F   .BYTE $A8
ROM6:9D20   .BYTE $9D
ROM6:9D21   .BYTE $E6
ROM6:9D22   .BYTE $9D
ROM6:9D23   .BYTE $27
ROM6:9D24   .BYTE $9E
ROM6:9D25   .BYTE $6C
ROM6:9D26   .BYTE $9E
ROM6:9D27   .BYTE $A9
ROM6:9D28   .BYTE $9E
ROM6:9D29   .BYTE $DF
ROM6:9D2A   .BYTE $9E
ROM6:9D2B   .BYTE $21
ROM6:9D2C   .BYTE $9F
ROM6:9D2D   .BYTE $55
ROM6:9D2E   .BYTE $9F
ROM6:9D2F some_ppu_data_3: .WORD $EE2A ; PPU addr: 0x2AEE
ROM6:9D31   .BYTE 4
ROM6:9D32   .BYTE $ED
ROM6:9D33   .BYTE $E9
ROM6:9D34   .BYTE $EA
ROM6:9D35   .BYTE $EE
ROM6:9D36   .BYTE $FF
ROM6:9D37 some_ppu_data_4: .WORD $D2B ; PPU addr: 0x2B0D
ROM6:9D39   .BYTE 6
ROM6:9D3A   .BYTE $ED
ROM6:9D3B   .BYTE $E9
ROM6:9D3C   .BYTE $24
ROM6:9D3D   .BYTE $24
ROM6:9D3E   .BYTE $EA
ROM6:9D3F   .BYTE $EE
ROM6:9D40   .BYTE $FF ; Terminator
ROM6:9D41 some_ppu_data_5: .WORD $2C2B ; PPU addr: 0x2B2C
ROM6:9D43   .BYTE 8
ROM6:9D44   .BYTE $ED
ROM6:9D45   .BYTE $E9
ROM6:9D46   .BYTE $24
ROM6:9D47   .BYTE $24
ROM6:9D48   .BYTE $24
ROM6:9D49   .BYTE $24
ROM6:9D4A   .BYTE $EA
ROM6:9D4B   .BYTE $EE
ROM6:9D4C   .BYTE $FF ; Terminator
ROM6:9D4D some_ppu_data_6: .WORD $4B2B ; PPU addr: 0x2B4B
ROM6:9D4F   .BYTE $A
ROM6:9D50   .BYTE $ED
ROM6:9D51   .BYTE $E9
ROM6:9D52   .BYTE $24
ROM6:9D53   .BYTE $24
ROM6:9D54   .BYTE $24
ROM6:9D55   .BYTE $24
ROM6:9D56   .BYTE $24
ROM6:9D57   .BYTE $24
ROM6:9D58   .BYTE $EA
ROM6:9D59   .BYTE $EE
ROM6:9D5A   .BYTE $FF ; Terminator
ROM6:9D5B some_ppu_data_7: .WORD $AC2B ; PPU addr: 0x2BAC
ROM6:9D5D   .BYTE 8
ROM6:9D5E   .BYTE $1D
ROM6:9D5F   .BYTE $1B
ROM6:9D60   .BYTE $12
ROM6:9D61   .BYTE $F
ROM6:9D62   .BYTE $18
ROM6:9D63   .BYTE $1B
ROM6:9D64   .BYTE $C
ROM6:9D65   .BYTE $E
ROM6:9D66   .BYTE $FF ; Terminator
ROM6:9D67 Skipped empty chunk
ROM6:A000 ppu_command_table: .WORD ppu_command_buffer ; 0x00
ROM6:A002   .WORD ppu_cmd_02
ROM6:A004   .WORD ppu_cmd_04
ROM6:A006   .WORD copied_ppu_data_1 ; PPUCommandIndices_Unknown_Copied_Data_1
ROM6:A008   .WORD ppu_cmd_palette_aquamentus ; PPUCommandIndices_SpecialPaletteMapping_Aquamentus
ROM6:A00A   .WORD ppu_cmd_palette_digdogger_dodongo ; PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo
ROM6:A00C   .WORD copied_ppu_data_2
ROM6:A00E   .WORD ppu_cmd_0E
ROM6:A010   .WORD ppu_cmd_10
ROM6:A012   .WORD copied_ppu_data_0 ; PPUCommandIndices_Unknown_Copied_Data_0
ROM6:A014   .WORD ppu_cmd_14
ROM6:A016   .WORD ppu_cmd_16
ROM6:A018   .WORD ppu_data_for_current_dungeon ; PPUCommandIndices_DungeonPPUData
ROM6:A01A   .WORD ppu_command_buffer
ROM6:A01C   .WORD ppu_command_buffer
ROM6:A01E   .WORD ppu_cmd_1E
ROM6:A020   .WORD ppu_cmd_20 ; 0x20
ROM6:A022   .WORD ppu_cmd_22
ROM6:A024   .WORD ppu_cmd_24
ROM6:A026   .WORD ppu_cmd_26
ROM6:A028   .WORD ppu_command_buffer
ROM6:A02A   .WORD ppu_cmd_2A
ROM6:A02C   .WORD ppu_cmd_2C
ROM6:A02E   .WORD copied_ppu_data_2
ROM6:A030   .WORD ppu_cmd_30
ROM6:A032   .WORD ppu_cmd_32
ROM6:A034   .WORD ppu_cmd_34
ROM6:A036   .WORD ppu_cmd_palette_ganon ; PPUCommandIndices_SpecialPaletteMapping_Ganon
ROM6:A038   .WORD ppu_cmd_38
ROM6:A03A   .WORD ppu_cmd_3A
ROM6:A03C   .WORD ppu_cmd_3C
ROM6:A03E   .WORD ppu_cmd_3E
ROM6:A040   .WORD ppu_cmd_40 ; 0x40
ROM6:A042   .WORD ppu_cmd_42
ROM6:A044   .WORD ppu_data_for_current_dungeon.ppu_0
ROM6:A046   .WORD ppu_cmd_46
ROM6:A048   .WORD ppu_cmd_48
ROM6:A04A   .WORD ppu_cmd_4A
ROM6:A04C   .WORD ppu_cmd_4C
ROM6:A04E   .WORD ppu_cmd_4E
ROM6:A050   .WORD ppu_cmd_50
ROM6:A052   .WORD copied_ppu_data_3 ; PPUCommandIndices_Unknown_Copied_Data_3
ROM6:A054   .WORD copied_ppu_data_4 ; PPUCommandIndices_Unknown_Copied_Data_4
ROM6:A056   .WORD copied_ppu_data_5 ; PPUCommandIndices_Unknown_Copied_Data_5
ROM6:A058   .WORD copied_ppu_data_6 ; PPUCommandIndices_Unknown_Copied_Data_6
ROM6:A05A   .WORD tiles_triforce_base
ROM6:A05C   .WORD copied_ppu_data_7 ; PPUCommandIndices_Unknown_Copied_Data_7
ROM6:A05E   .WORD ppu_cmd_5E
ROM6:A060   .WORD ppu_cmd_60 ; 0x60
ROM6:A062   .WORD ppu_cmd_62
ROM6:A064   .WORD ppu_command_buffer
ROM6:A066   .WORD ppu_command_buffer
ROM6:A068   .WORD ppu_command_buffer
ROM6:A06A   .WORD ppu_cmd_6A
ROM6:A06C   .WORD ppu_cmd_6C
ROM6:A06E   .WORD ppu_command_buffer
ROM6:A070   .WORD ppu_command_buffer
ROM6:A072   .WORD ppu_command_buffer
ROM6:A074   .WORD ppu_command_buffer
ROM6:A076   .WORD ppu_cmd_76
ROM6:A078   .WORD ppu_cmd_78 ; PPUCommandIndices_PickedUpTriforce
ROM6:A07A   .WORD ppu_cmd_7A
ROM6:A07C   .WORD ppu_cmd_palette_gleeok ; PPUCommandIndices_SpecialPaletteMapping_Gleeok
ROM6:A07E   .WORD ppu_command_buffer
 
Subroutine send_current_ppu_command
; If current_ppu_command_index is set, send the current PPU command.
ROM6:A080 send_current_ppu_command:
ROM6:A080 LDX current_ppu_command_index ; Get the PPU command index to send this frame.
ROM6:A081 LDA ppu_command_table,X ; Get the address of the PPU command to execute.
ROM6:A082 STA var_0
ROM6:A083 LDA ppu_command_table+1,X ; 0x00
ROM6:A084 STA var_1
ROM6:A085 JSR send_ppu_data ; Write a 0xFF-terminated PPU command buffer. This writes
  ; a list of PPU command blocks until we hit 0xFF.
ROM6:A086 LDA #$3F
ROM6:A087 STA ppu_unknown_0 ; Set to 0x3F
ROM6:A088 LDX #0
ROM6:A089 STX current_ppu_command_index ; Set to 0
ROM6:A08A STX alternate_ppu_nametable ; Set to 0
ROM6:A08B STX ppu_command_buffer_bytes_used ; Set to 0
ROM6:A08C DEX
ROM6:A08D STX ppu_command_buffer ; Set to 0xFF, which erases ppu_command_buffer so it won't
  ; be sent again (if it's the one we just sent).
ROM6:A08E RTS
 
Subroutine send_ppu_data_inner
ROM6:A0A2 send_ppu_data_inner:
ROM6:A0A2 PHA ; Write a single block from a PPU command buffer. This isn't
  ; fully pieced apart, but it specifies an address, number of
  ; bytes, and allows writing either a string of values or writing
  ; a single value repeatedly to clear a region to a single value.
ROM6:A0A3 STA PPUADDR ; Write PPU address MSB
ROM6:A0A4 INY
ROM6:A0A5 LDA (var_0),Y
ROM6:A0A6 STA PPUADDR ; Write PPU address LSB
ROM6:A0A7 INY
ROM6:A0A8 LDA (var_0),Y
ROM6:A0A9 ASL A ; Shift out 0x80 (write vertically flag)
ROM6:A0AA PHA ; Push cmd[2] << 1
ROM6:A0AB LDA current_ppuctrl
ROM6:A0AC ORA #PPUCTRLBits_WriteVertically ; Set bit PPUCTRLBits_WriteVertically
ROM6:A0AD BCS skip_clear_write_vertically ; Skip if cmd[2] & 0x80 was set.
ROM6:A0AE AND #$FB ; Clear bit PPUCTRLBits_WriteVertically
 
ROM6:A0AF skip_clear_write_vertically: ; Write the current PPUCTRL value.
ROM6:A0AF STA PPUCTRL
ROM6:A0B0 STA current_ppuctrl ; Store it, in case we cleared bit 4 above.
ROM6:A0B1 PLA ; Restore cmd[2] << 1
ROM6:A0B2 ASL A ; Shift out 0x40
ROM6:A0B3 PHP ; Push flags
ROM6:A0B4 BCC cmd2_bit_0x40_clear ; 0x40 was clear
ROM6:A0B5 ORA #2 ; 0x40 was set. A |= 2, Y++
ROM6:A0B6 INY
 
ROM6:A0B7 cmd2_bit_0x40_clear: ; Restore flags from after the above ASL A.
ROM6:A0B7 PLP
ROM6:A0B8 CLC ; Clear carry.
ROM6:A0B9 BNE clear_carry ; Branch if (cmd[2] << 2) == 0.
ROM6:A0BA SEC ; Set carry.
 
ROM6:A0BB clear_carry: ; Shift either 0 or 1 into 0x80.
ROM6:A0BB ROR A
ROM6:A0BC LSR A ; A >>= 1
ROM6:A0BD TAX ; X = A (number of bytes to write)
 
ROM6:A0BE loop: ; If carry is set, don't increment Y. Write the same
ROM6:A0BE BCS skip_y_increment ; single byte each time instead of writing a string of
  ; values.
ROM6:A0BF INY
 
ROM6:A0C0 skip_y_increment: ; Read the next byte
ROM6:A0C0 LDA (var_0),Y
ROM6:A0C1 STA PPUDATA ; Write the next PPU data byte
ROM6:A0C2 DEX
ROM6:A0C3 BNE loop
ROM6:A0C4 PLA ; Restore byte cmd[2]
ROM6:A0C5 CMP #$3F
ROM6:A0C6 BNE cmd_not_0x3F
ROM6:A0C7 STA PPUADDR ; If cmd[2] is 0x3F, write 3F 00 00 00 to PPUADDR.
ROM6:A0C8 STX PPUADDR ; Write 0
ROM6:A0C9 STX PPUADDR ; Write 0
ROM6:A0CA STX PPUADDR ; Write 0
 
ROM6:A0CB cmd_not_0x3F:
ROM6:A0CB SEC
ROM6:A0CC TYA
ROM6:A0CD ADC var_0 ; Update the pointer at var_0 to point to the next command in the buffer, and fall through to repeat.
ROM6:A0CE STA var_0
ROM6:A0CF LDA #0
ROM6:A0D0 ADC var_1
ROM6:A0D1 STA var_1
 
ROM6:A0F6 send_ppu_data: ; Write a 0xFF-terminated PPU command buffer. This writes
ROM6:A0F6 LDX PPUSTATUS ; a list of PPU command blocks until we hit 0xFF.
ROM6:A0F7 LDY #0
ROM6:A0F8 LDA (var_0),Y
ROM6:A0F9 BPL send_ppu_data_inner ; Branch unless the next byte is 0xFF, which finishes the command.
ROM6:A0FA RTS
 
ROM6:A100 ppu_cmd_14:
ROM6:A183 ppu_cmd_16:
ROM6:A202 ppu_cmd_palette_ganon: .WORD $1C3F ; PPU addr: 0x3F1C (sprite palette 3)
ROM6:A204   .BYTE 4 ; Write 4 bytes.
ROM6:A205   .BYTE $F ; Palette data
ROM6:A206   .BYTE $16
ROM6:A207   .BYTE $2C
ROM6:A208   .BYTE $3C
ROM6:A209   .BYTE $FF ; Terminator
ROM6:A20A ppu_cmd_6A: .WORD $83F
ROM6:A20C   .BYTE 8
ROM6:A20D   .BYTE $F
ROM6:A20E   .BYTE $22
ROM6:A20F   .BYTE $10
ROM6:A210   .BYTE 0
ROM6:A211   .BYTE $F
ROM6:A212   .BYTE $2A
ROM6:A213   .BYTE $10
ROM6:A214   .BYTE 0
ROM6:A215   .BYTE $3F
ROM6:A216   .BYTE $1C
ROM6:A217   .BYTE 4
ROM6:A218   .BYTE $F
ROM6:A219   .BYTE $27
ROM6:A21A   .BYTE 6
ROM6:A21B   .BYTE $16
ROM6:A21C   .BYTE $FF ; Terminator
ROM6:A21D ppu_cmd_1E: .WORD $A421
ROM6:A21F   .BYTE $58
ROM6:A220   .BYTE $24
ROM6:A221   .BYTE $21
ROM6:A222   .BYTE $C4
ROM6:A223   .BYTE $58
ROM6:A224   .BYTE $24
ROM6:A225   .BYTE $FF ; Terminator
ROM6:A226 ppu_cmd_2A: .WORD $E421
ROM6:A228   .BYTE $58
ROM6:A229   .BYTE $24
ROM6:A22A   .BYTE $22
ROM6:A22B   .BYTE $C8
ROM6:A22C   .BYTE $4D
ROM6:A22D   .BYTE $24
ROM6:A22E   .BYTE $FF ; Terminator
ROM6:A22F ppu_cmd_50: .WORD $CF2A
ROM6:A231   .BYTE 2
ROM6:A232   .BYTE $ED
ROM6:A233   .BYTE $EE
ROM6:A234   .BYTE $FF ; Terminator
ROM6:A235 tiles_triforce_base: .WORD $6A2B
ROM6:A237   .BYTE $C
ROM6:A238   .BYTE $EB
ROM6:A239   .BYTE $EF
ROM6:A23A   .BYTE $F1
ROM6:A23B   .BYTE $F1
ROM6:A23C   .BYTE $F1
ROM6:A23D   .BYTE $F1
ROM6:A23E   .BYTE $F1
ROM6:A23F   .BYTE $F1
ROM6:A240   .BYTE $F1
ROM6:A241   .BYTE $F1
ROM6:A242   .BYTE $F0
ROM6:A243   .BYTE $EC
ROM6:A244   .BYTE $FF ; Terminator
ROM6:A245 ppu_cmd_20: .BYTE $3F
ROM6:A246   .BYTE $1C
ROM6:A247   .BYTE 4
ROM6:A248   .BYTE $F
ROM6:A249   .BYTE $30
ROM6:A24A   .BYTE 0
ROM6:A24B   .BYTE $12
ROM6:A24C   .BYTE $FF ; Terminator
ROM6:A24D ppu_cmd_22: .WORD $1C3F
ROM6:A24F   .BYTE 4
ROM6:A250   .BYTE $F
ROM6:A251   .BYTE $1A
ROM6:A252   .BYTE $37
ROM6:A253   .BYTE $12
ROM6:A254   .BYTE $FF ; Terminator
ROM6:A255 ppu_cmd_24: .WORD $1C3F
ROM6:A257   .BYTE 4
ROM6:A258   .BYTE $F
ROM6:A259   .BYTE $17
ROM6:A25A   .BYTE $37
ROM6:A25B   .BYTE $12
ROM6:A25C   .BYTE $FF ; Terminator
ROM6:A25D ppu_cmd_3E: .WORD $83F
ROM6:A25F   .BYTE 8
ROM6:A260   .BYTE $F
ROM6:A261   .BYTE $30
ROM6:A262   .BYTE 0
ROM6:A263   .BYTE $12
ROM6:A264   .BYTE $F
ROM6:A265   .BYTE 7
ROM6:A266   .BYTE $F
ROM6:A267   .BYTE $17
ROM6:A268   .BYTE $FF ; Terminator
ROM6:A269 ppu_cmd_26: .WORD $D023
ROM6:A26B   .BYTE $60
ROM6:A26C   .BYTE $AA
ROM6:A26D   .BYTE $23
ROM6:A26E   .BYTE $F0
ROM6:A26F   .BYTE $50
ROM6:A270   .BYTE $AA
ROM6:A271   .BYTE $FF ; Terminator
ROM6:A272 ppu_cmd_78: .WORD $83F ; PPU addr: 0x0F08 (pattern table data)
ROM6:A274   .BYTE 8 ; Write 8 bytes.
ROM6:A275   .BYTE $F
ROM6:A276   .BYTE $30
ROM6:A277   .BYTE $30
ROM6:A278   .BYTE $30
ROM6:A279   .BYTE $F
ROM6:A27A   .BYTE $30
ROM6:A27B   .BYTE $30
ROM6:A27C   .BYTE $30
ROM6:A27D   .BYTE $FF ; Terminator
ROM6:A27E ppu_cmd_7A: .WORD $1C3F
ROM6:A280   .BYTE 4
ROM6:A281   .BYTE $F
ROM6:A282   .BYTE $F
ROM6:A283   .BYTE $1C
ROM6:A284   .BYTE $16
ROM6:A285   .BYTE $FF ; Terminator
ROM6:A286 ppu_cmd_palette_gleeok: .WORD $1C3F ; PPU addr: 0x3F1C (sprite palette 3)
ROM6:A288   .BYTE 4 ; Write 4 bytes.
ROM6:A289   .BYTE $F ; Palette data
ROM6:A28A   .BYTE $2A
ROM6:A28B   .BYTE $1A
ROM6:A28C   .BYTE $C
ROM6:A28D   .BYTE $FF ; Terminator
ROM6:A28E ppu_cmd_palette_aquamentus: .WORD $1C3F ; PPU addr: 0x3F1C (sprite palette 3)
ROM6:A290   .BYTE 4 ; Write 4 bytes.
ROM6:A291   .BYTE $F ; Palette data
ROM6:A292   .BYTE $A
ROM6:A293   .BYTE $29
ROM6:A294   .BYTE $30
ROM6:A295   .BYTE $FF ; Terminator
ROM6:A296 ppu_cmd_palette_digdogger_dodongo: .WORD $1C3F ; PPU addr: 0x3F1C (sprite palette 3)
ROM6:A298   .BYTE 4 ; Write 4 bytes.
ROM6:A299   .BYTE $F ; Palette data
ROM6:A29A   .BYTE $17
ROM6:A29B   .BYTE $27
ROM6:A29C   .BYTE $30
ROM6:A29D   .BYTE $FF ; Terminator
ROM6:A29E ppu_cmd_6C: .BYTE $22
ROM6:A29F   .BYTE $CD
ROM6:A2A0   .BYTE 4
ROM6:A2A1   .BYTE $62
ROM6:A2A2   .BYTE 1
ROM6:A2A3   .BYTE 0
ROM6:A2A4   .BYTE 0
ROM6:A2A5   .BYTE $FF ; Terminator
ROM6:A2A6 ppu_cmd_76: .BYTE $22
ROM6:A2A7   .BYTE $CB
ROM6:A2A8   .BYTE $A
ROM6:A2A9   .BYTE $62
ROM6:A2AA   .BYTE 1
ROM6:A2AB   .BYTE $24
ROM6:A2AC   .BYTE $24
ROM6:A2AD   .BYTE $24
ROM6:A2AE   .BYTE $24
ROM6:A2AF   .BYTE $24
ROM6:A2B0   .BYTE $62
ROM6:A2B1   .BYTE 5
ROM6:A2B2   .BYTE 0
ROM6:A2B3   .BYTE $FF ; Terminator
ROM6:A2B4 ppu_cmd_04:
ROM6:A35E ppu_cmd_0E:
ROM6:A3A1 ppu_cmd_30: .BYTE $29
ROM6:A3A2   .BYTE $84
ROM6:A3A3   .BYTE 9
ROM6:A3A4   .BYTE $12
ROM6:A3A5   .BYTE $17
ROM6:A3A6   .BYTE $1F
ROM6:A3A7   .BYTE $E
ROM6:A3A8   .BYTE $17
ROM6:A3A9   .BYTE $1D
ROM6:A3AA   .BYTE $18
ROM6:A3AB   .BYTE $1B
ROM6:A3AC   .BYTE $22
ROM6:A3AD   .BYTE $FF ; Terminator
ROM6:A3AE ppu_cmd_32: .BYTE $29
ROM6:A3AF   .BYTE $C7
ROM6:A3B0   .BYTE 4
ROM6:A3B1   .BYTE $69
ROM6:A3B2   .BYTE $6A
ROM6:A3B3   .BYTE $6A
ROM6:A3B4   .BYTE $6B
ROM6:A3B5   .BYTE $29
ROM6:A3B6   .BYTE $CF
ROM6:A3B7   .BYTE 1
ROM6:A3B8   .BYTE $69
ROM6:A3B9   .BYTE $29
ROM6:A3BA   .BYTE $D0
ROM6:A3BB   .BYTE $4B
ROM6:A3BC   .BYTE $6A
ROM6:A3BD   .BYTE $29
ROM6:A3BE   .BYTE $DB
ROM6:A3BF   .BYTE 1
ROM6:A3C0   .BYTE $6B
ROM6:A3C1   .BYTE $FF ; Terminator
ROM6:A3C2 ppu_cmd_34: .BYTE $29
ROM6:A3C3   .BYTE $E7
ROM6:A3C4   .BYTE $C2
ROM6:A3C5   .BYTE $6C
ROM6:A3C6   .BYTE $29
ROM6:A3C7   .BYTE $EA
ROM6:A3C8   .BYTE $C2
ROM6:A3C9   .BYTE $6C
ROM6:A3CA   .BYTE $29
ROM6:A3CB   .BYTE $EF
ROM6:A3CC   .BYTE $C4
ROM6:A3CD   .BYTE $6C
ROM6:A3CE   .BYTE $29
ROM6:A3CF   .BYTE $FB
ROM6:A3D0   .BYTE $C4
ROM6:A3D1   .BYTE $6C
ROM6:A3D2   .BYTE $FF ; Terminator
ROM6:A3D3 ppu_cmd_38: .BYTE $2A
ROM6:A3D4   .BYTE $27
ROM6:A3D5   .BYTE 4
ROM6:A3D6   .BYTE $6E
ROM6:A3D7   .BYTE $6A
ROM6:A3D8   .BYTE $6A
ROM6:A3D9   .BYTE $6D
ROM6:A3DA   .BYTE $FF ; Terminator
ROM6:A3DB ppu_cmd_3A: .BYTE $2A
ROM6:A3DC   .BYTE $42
ROM6:A3DD   .BYTE $C
ROM6:A3DE   .BYTE $1E
ROM6:A3DF   .BYTE $1C
ROM6:A3E0   .BYTE $E
ROM6:A3E1   .BYTE $24
ROM6:A3E2   .BYTE $B
ROM6:A3E3   .BYTE $24
ROM6:A3E4   .BYTE $B
ROM6:A3E5   .BYTE $1E
ROM6:A3E6   .BYTE $1D
ROM6:A3E7   .BYTE $1D
ROM6:A3E8   .BYTE $18
ROM6:A3E9   .BYTE $17
ROM6:A3EA   .BYTE $FF ; Terminator
ROM6:A3EB ppu_cmd_3C: .BYTE $2A
ROM6:A3EC   .BYTE $64
ROM6:A3ED   .BYTE 8
ROM6:A3EE   .BYTE $F
ROM6:A3EF   .BYTE $18
ROM6:A3F0   .BYTE $1B
ROM6:A3F1   .BYTE $24
ROM6:A3F2   .BYTE $1D
ROM6:A3F3   .BYTE $11
ROM6:A3F4   .BYTE $12
ROM6:A3F5   .BYTE $1C
ROM6:A3F6   .BYTE $2A
ROM6:A3F7   .BYTE $6F
ROM6:A3F8   .BYTE 1
ROM6:A3F9   .BYTE $6E
ROM6:A3FA   .BYTE $2A
ROM6:A3FB   .BYTE $70
ROM6:A3FC   .BYTE $4B
ROM6:A3FD   .BYTE $6A
ROM6:A3FE   .BYTE $2A
ROM6:A3FF   .BYTE $7B
ROM6:A400   .BYTE 1
ROM6:A401   .BYTE $6D
ROM6:A402   .BYTE $FF ; Terminator
ROM6:A403 ppu_cmd_40: .BYTE $2B
ROM6:A404   .BYTE $43
ROM6:A405   .BYTE 7
ROM6:A406   .BYTE $C
ROM6:A407   .BYTE $18
ROM6:A408   .BYTE $16
ROM6:A409   .BYTE $19
ROM6:A40A   .BYTE $A
ROM6:A40B   .BYTE $1C
ROM6:A40C   .BYTE $1C
ROM6:A40D   .BYTE $2A
ROM6:A40E   .BYTE $A5
ROM6:A40F   .BYTE 3
ROM6:A410   .BYTE $16
ROM6:A411   .BYTE $A
ROM6:A412   .BYTE $19
ROM6:A413   .BYTE $2A
ROM6:A414   .BYTE $8C
ROM6:A415   .BYTE $10
ROM6:A416   .BYTE $F5
ROM6:A417   .BYTE $F5
ROM6:A418   .BYTE $FD
ROM6:A419   .BYTE $F5
ROM6:A41A   .BYTE $F5
ROM6:A41B   .BYTE $FD
ROM6:A41C   .BYTE $F5
ROM6:A41D   .BYTE $F5
ROM6:A41E   .BYTE $FD
ROM6:A41F   .BYTE $F5
ROM6:A420   .BYTE $F5
ROM6:A421   .BYTE $F5
ROM6:A422   .BYTE $FD
ROM6:A423   .BYTE $F5
ROM6:A424   .BYTE $F5
ROM6:A425   .BYTE $F5
ROM6:A426   .BYTE $FF ; Terminator
ROM6:A427 ppu_cmd_42: .BYTE $2B
ROM6:A428   .BYTE $AC
ROM6:A429   .BYTE $10
ROM6:A42A   .BYTE $F5
ROM6:A42B   .BYTE $FE
ROM6:A42C   .BYTE $F5
ROM6:A42D   .BYTE $F5
ROM6:A42E   .BYTE $F5
ROM6:A42F   .BYTE $FE
ROM6:A430   .BYTE $F5
ROM6:A431   .BYTE $F5
ROM6:A432   .BYTE $F5
ROM6:A433   .BYTE $F5
ROM6:A434   .BYTE $FE
ROM6:A435   .BYTE $F5
ROM6:A436   .BYTE $F5
ROM6:A437   .BYTE $F5
ROM6:A438   .BYTE $FE
ROM6:A439   .BYTE $F5
ROM6:A43A   .BYTE $FF ; Terminator
ROM6:A43B ppu_cmd_48: .BYTE $2B
ROM6:A43C   .BYTE $D9
ROM6:A43D   .BYTE $43
ROM6:A43E   .BYTE 5
ROM6:A43F   .BYTE $2B
ROM6:A440   .BYTE $DC
ROM6:A441   .BYTE $4B
ROM6:A442   .BYTE 0
ROM6:A443   .BYTE $FF ; Terminator
ROM6:A444 ppu_cmd_4A: .BYTE $2B
ROM6:A445   .BYTE $E9
ROM6:A446   .BYTE $56
ROM6:A447   .BYTE $55
ROM6:A448   .BYTE $FF ; Terminator
ROM6:A449 ppu_cmd_4C: .BYTE $2B
ROM6:A44A   .BYTE $A0
ROM6:A44B   .BYTE $60
ROM6:A44C   .BYTE $24
ROM6:A44D   .BYTE $FF ; Terminator
ROM6:A44E ppu_cmd_4E: .BYTE $28
ROM6:A44F   .BYTE $E0
ROM6:A450   .BYTE $60
ROM6:A451   .BYTE $24
ROM6:A452   .BYTE $FF ; Terminator
ROM6:A453 ppu_cmd_2C: .BYTE $3F
ROM6:A454   .BYTE $10
ROM6:A455   .BYTE 4
ROM6:A456   .BYTE $F
ROM6:A457   .BYTE $10
ROM6:A458   .BYTE $30
ROM6:A459   .BYTE 0
ROM6:A45A   .BYTE $FF ; Terminator
ROM6:A45B ppu_cmd_46: .BYTE $23
ROM6:A45C   .BYTE $E3
ROM6:A45D   .BYTE 3
ROM6:A45E   .BYTE $F
ROM6:A45F   .BYTE $F
ROM6:A460   .BYTE $CF
ROM6:A461   .BYTE $22
ROM6:A462   .BYTE $4C
ROM6:A463   .BYTE $A
ROM6:A464   .BYTE $10
ROM6:A465   .BYTE $A
ROM6:A466   .BYTE $16
ROM6:A467   .BYTE $E
ROM6:A468   .BYTE $24
ROM6:A469   .BYTE $18
ROM6:A46A   .BYTE $1F
ROM6:A46B   .BYTE $E
ROM6:A46C   .BYTE $1B
ROM6:A46D   .BYTE $24
ROM6:A46E   .BYTE $22
ROM6:A46F   .BYTE $6C
ROM6:A470   .BYTE $4A
ROM6:A471   .BYTE $24
ROM6:A472   .BYTE $FF ; Terminator
ROM6:A473 ppu_cmd_5E: .BYTE $3F
ROM6:A474   .BYTE 8
ROM6:A475   .BYTE 8
ROM6:A476   .BYTE $F
ROM6:A477   .BYTE $17
ROM6:A478   .BYTE $16
ROM6:A479   .BYTE $26
ROM6:A47A   .BYTE $F
ROM6:A47B   .BYTE $17
ROM6:A47C   .BYTE $16
ROM6:A47D   .BYTE $26
ROM6:A47E   .BYTE $FF ; Terminator
ROM6:A47F ppu_cmd_60: .BYTE $23
ROM6:A480   .BYTE $D0
ROM6:A481   .BYTE $58
ROM6:A482   .BYTE $FF
ROM6:A483   .BYTE $FF ; Terminator
ROM6:A484 ppu_cmd_62: .BYTE $23
ROM6:A485   .BYTE $E8
ROM6:A486   .BYTE $58
ROM6:A487   .BYTE $FF
ROM6:A488   .BYTE $FF ; Terminator
ROM6:A489 ppu_cmd_02:
ROM6:A8F4 ppu_cmd_10:
ROM6:A8F4 Skipped empty chunk
 
Subroutine rom6_OnReset
ROM6:BF50 rom6_OnReset:
ROM6:BF50 SEI
ROM6:BF51 CLD
ROM6:BF52 LDA #0
ROM6:BF53 STA $2000
ROM6:BF54 LDX #$FF
ROM6:BF55 TXS
 
ROM6:BF56 loop1:
ROM6:BF56 LDA PPUSTATUS
ROM6:BF57 AND #$80
ROM6:BF58 BEQ loop1
 
ROM6:BF59 loop2:
ROM6:BF59 LDA PPUSTATUS
ROM6:BF5A AND #$80
ROM6:BF5B BEQ loop2
ROM6:BF5C ORA #$FF
ROM6:BF5D STA rom2_sprite_data_ptrs
ROM6:BF5E STA ppu_command_table ; 0x00
ROM6:BF5F STA byte_1C000
ROM6:BF60 STA byte_1E000
ROM6:BF61 LDA #$F
ROM6:BF62 JSR rom6_set_mmc_control_register
ROM6:BF63 LDA #0
ROM6:BF64 STA ppu_command_table ; 0x00
ROM6:BF65 LSR A
ROM6:BF66 STA ppu_command_table ; 0x00
ROM6:BF67 LSR A
ROM6:BF68 STA ppu_command_table ; 0x00
ROM6:BF69 LSR A
ROM6:BF6A STA ppu_command_table ; 0x00
ROM6:BF6B LSR A
ROM6:BF6C STA ppu_command_table ; 0x00
ROM6:BF6D LDA #7
ROM6:BF6E JSR rom6_set_prg_bank
ROM6:BF6F JMP continue_setup
 
Subroutine rom6_set_mmc_control_register
ROM6:BF98 rom6_set_mmc_control_register:
ROM6:BF98 STA rom2_sprite_data_ptrs
ROM6:BF99 LSR A
ROM6:BF9A STA rom2_sprite_data_ptrs
ROM6:BF9B LSR A
ROM6:BF9C STA rom2_sprite_data_ptrs
ROM6:BF9D LSR A
ROM6:BF9E STA rom2_sprite_data_ptrs
ROM6:BF9F LSR A
ROM6:BFA0 STA rom2_sprite_data_ptrs
ROM6:BFA1 RTS
 
Subroutine rom6_set_prg_bank
ROM6:BFAC rom6_set_prg_bank:
ROM6:BFAC STA byte_1E000
ROM6:BFAD LSR A
ROM6:BFAE STA byte_1E000
ROM6:BFAF LSR A
ROM6:BFB0 STA byte_1E000
ROM6:BFB1 LSR A
ROM6:BFB2 STA byte_1E000
ROM6:BFB3 LSR A
ROM6:BFB4 STA byte_1E000
ROM6:BFB5 RTS
 
ROM6:BFB6 Skipped empty chunk
 
Segment: ROM7
ROM7:C000 byte_1C000:
Function chunk for call_jump_table
ROM7:E400 room_tile_ptrs: .WORD room_tiles_x_00
ROM7:E402   .WORD room_tiles_x_01
ROM7:E404   .WORD room_tiles_x_02
ROM7:E406   .WORD room_tiles_x_03
ROM7:E408   .WORD room_tiles_x_04
ROM7:E40A   .WORD room_tiles_x_05
ROM7:E40C   .WORD room_tiles_x_06
ROM7:E40E   .WORD room_tiles_x_07
ROM7:E410   .WORD room_tiles_x_08
ROM7:E412   .WORD room_tiles_x_09
ROM7:E414   .WORD room_tiles_x_10
ROM7:E416   .WORD room_tiles_x_11
ROM7:E418   .WORD room_tiles_x_12
ROM7:E41A   .WORD room_tiles_x_13
ROM7:E41C   .WORD room_tiles_x_14
ROM7:E41E   .WORD room_tiles_x_15
ROM7:E420   .WORD room_tiles_x_16
ROM7:E422   .WORD room_tiles_x_17
ROM7:E424   .WORD room_tiles_x_18
ROM7:E426   .WORD room_tiles_x_19
ROM7:E428   .WORD room_tiles_x_20
ROM7:E42A   .WORD room_tiles_x_21
ROM7:E42C   .WORD room_tiles_x_22
ROM7:E42E   .WORD room_tiles_x_23
ROM7:E430   .WORD room_tiles_x_24
ROM7:E432   .WORD room_tiles_x_25
ROM7:E434   .WORD room_tiles_x_26
ROM7:E436   .WORD room_tiles_x_27
ROM7:E438   .WORD room_tiles_x_28
ROM7:E43A   .WORD room_tiles_x_29
ROM7:E43C   .WORD room_tiles_x_30
ROM7:E43E   .WORD room_tiles_x_31
 
Function chunk for OnReset
ROM7:E440 continue_setup:
ROM7:E440 LDA #0
ROM7:E441 STA sram_init_finished ; Set to 0.
ROM7:E442 LDA #5
ROM7:E443 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E444 JSR check_sram
ROM7:E445 JSR init_memory
ROM7:E446 JSR stop_audio_and_clear_nametables
ROM7:E447 LDA current_ppuctrl
ROM7:E448 ORA #PPUCTRLBits_SpriteSize_8x16|PPUCTRLBits_VBlank_NMI_On
ROM7:E449 STA PPUCTRL
ROM7:E44A STA current_ppuctrl
 
ROM7:E44B loop: ; NMI continues from here
ROM7:E44B JMP loop
 
Subroutine stop_audio_and_clear_nametables
ROM7:E45E stop_audio_and_clear_nametables:
ROM7:E45E LDA #0
ROM7:E45F STA pAPU_DM_DAR
ROM7:E460 LDA #$F
ROM7:E461 STA pAPU_SV_CSR
ROM7:E462 LDA #6
ROM7:E463 STA PPUMASK
 
ROM7:E46D clear_nametables: ; Clear the OAM buffer.
ROM7:E46D JSR clear_oam
ROM7:E46E JSR init_ppuscroll
ROM7:E46F JSR clear_ppumask
ROM7:E470 LDA #$20 ; Clear PPU nametable data at 0x2000.
ROM7:E471 JSR clear_one_nametable
ROM7:E472 LDA #$28 ; Clear PPU nametable data at 0x2800.
 
ROM7:E473 clear_one_nametable:
ROM7:E473 LDX #$24
ROM7:E474 LDY #0
ROM7:E475 JMP clear_ppu_data ; Call with A = 0x20 or 0x28, X = 0x24 and Y = 0
 
Subroutine OnNMI
ROM7:E484 OnNMI:
ROM7:E484 LDA current_ppuctrl
ROM7:E485 LDX alternate_ppu_nametable ; Check if we should flip the nametable.
ROM7:E486 BEQ no_nametable_swap
ROM7:E487 EOR #PPUCTRLBits_BaseNametable_2800 ; Alternate between 0x2000 and 0x2800 (or 0x2400 and 0x2C00).
 
ROM7:E488 no_nametable_swap: ; Clear PPUCTRLBits_VBlank_NMI_On
ROM7:E488 AND #$7F
ROM7:E489 STA current_ppuctrl
ROM7:E48A AND #$7E ; Clear Clear PPUCTRLBits_VBlank_NMI_On and PPUCTRLBits_BaseNametable_2400
ROM7:E48B STA PPUCTRL
ROM7:E48C LDA current_ppumask
ROM7:E48D LDY do_ppu_work_after_sprite0_next_frame
ROM7:E48E BNE add_ppu_mask_bits
ROM7:E48F LDY current_ppu_command_index ; Don't change PPUMASK if we have a PPU command to send.
ROM7:E490 BNE skip_add_ppu_mask_bits
ROM7:E491 LDY curtains_currently_opening
ROM7:E492 BNE skip_add_ppu_mask_bits
 
ROM7:E493 add_ppu_mask_bits:
ROM7:E493 ORA #PPUMaskBits_BackgroundOnLeft8PX|PPUMaskBits_SpritesOnLeft8PX|PPUMaskBits_ShowBackground|PPUMaskBits_ShowSprites
 
ROM7:E494 skip_add_ppu_mask_bits:
ROM7:E494 STA PPUMASK
ROM7:E495 STA current_ppumask
ROM7:E496 LDA #0
ROM7:E497 STA OAMADDR ; Set to 0.
ROM7:E498 LDA #2
ROM7:E499 STA SPRITE_DMAR
ROM7:E49A LDA #0
ROM7:E49B STA PPUSCROLL ; Set to 0x0.
ROM7:E49C STA PPUSCROLL
ROM7:E49D LDA #6
ROM7:E49E JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E49F JSR send_current_ppu_command ; If current_ppu_command_index is set, send the current PPU command.
ROM7:E4A0 LDA #$3F
ROM7:E4A1 STA PPUADDR ; Send 0x3F00.
ROM7:E4A2 LDA #0
ROM7:E4A3 STA PPUADDR
ROM7:E4A4 STA PPUADDR
ROM7:E4A5 STA PPUADDR
 
  ; Wait for the sprite 0 hit flag to be clear. This seems
  ; to usually happen immediately.
 
ROM7:E4A6 wait_for_sprite_0_hit_clear:
ROM7:E4A6 LDA PPUSTATUS
ROM7:E4A7 AND #PPUStatusBits_Sprite0Hit
ROM7:E4A8 BNE wait_for_sprite_0_hit_clear
ROM7:E4A9 LDA PPUSTATUS
ROM7:E4AA LDA do_ppu_work_after_sprite0_next_frame
ROM7:E4AB BEQ check_change_ppu_scroll
ROM7:E4AC LDA #5
ROM7:E4AD JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E4AE JSR ppu_work_after_sprite_0_hit ; This function is related to scrolling the screen during
  ; screen transitions. This waits for a sprite 0 hit and
  ; then has a bunch of hard delays, so it seems tightly
  ; synchronized with PPU rendering.
 
ROM7:E4AF check_change_ppu_scroll: ; Skip PPUSCROLL update when in game_mode_task 0 (task0).
ROM7:E4AF LDA active_game_mode_task
ROM7:E4B0 BEQ update_timers
ROM7:E4B1 LDA game_mode ; Only update PPUSCROLL in these game modes.
ROM7:E4B2 BEQ change_ppu_scroll ; GameMode_Title
ROM7:E4B3 CMP #GameMode_Normal
ROM7:E4B4 BEQ change_ppu_scroll
ROM7:E4B5 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM7:E4B6 BEQ change_ppu_scroll
ROM7:E4B7 CMP #GameMode_InOverworldCellar ; We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal.
  ; The map location doesn't change.
ROM7:E4B8 BEQ change_ppu_scroll
ROM7:E4B9 CMP #GameMode_ExitingOverworldCellar
ROM7:E4BA BEQ change_ppu_scroll
ROM7:E4BB CMP #GameMode_FoundZelda
ROM7:E4BC BNE update_timers
 
ROM7:E4BD change_ppu_scroll: ; Reset address latch
ROM7:E4BD LDA PPUSTATUS
ROM7:E4BE LDA desired_ppuscroll_x
ROM7:E4BF STA PPUSCROLL
ROM7:E4C0 LDA desired_ppuscroll_y
ROM7:E4C1 STA PPUSCROLL
ROM7:E4C2 LDA current_ppuctrl
ROM7:E4C3 STA PPUCTRL
 
ROM7:E4C4 update_timers:
ROM7:E4C4 LDA gameplay_menu_state
ROM7:E4C5 ORA paused
ROM7:E4C6 BNE check_update_controllers ; Don't update timers when paused, or when the start menu is open.
ROM7:E4C7 LDX #ten_frame_counter
ROM7:E4C8 LDA #recorder_lock_timer
ROM7:E4C9 LDY #unknown_timer_6
ROM7:E4CA STX var_0
ROM7:E4CB DEC 0,X ; Decrement ten_frame_counter. This determines whether we
  ; decrement all timers or just single-frame counters (skipping
  ; ten-frame counters).
ROM7:E4CC BPL decrement_recorder_lock_timer ; Branch if count_down_from_nine wrapped to 0xFF, with A = recorder_lock_timer.
  ; We'll decrement all timers between unknown_timer_1 (0x27) and recorder_lock_timer (0x3C).
ROM7:E4CD LDA #9
ROM7:E4CE STA 0,X ; Reset ten_frame_counter to 9.
ROM7:E4CF TYA ; A = unknown_timer_4. Decrement all timers between unknown_timer_1 (0x27) and unknown_timer_6 (0x4E).
 
ROM7:E4D0 decrement_recorder_lock_timer: ; X = A (either recorder_lock_timer or unknown_timer_4)
ROM7:E4D0 TAX
 
ROM7:E4D1 decrement_timer_loop: ; Decrement timers X down to ten_frame_counter.
ROM7:E4D1 LDA 0,X
ROM7:E4D2 BEQ skip_decrement_timer ; Skip if this timer is already 0.
ROM7:E4D3 DEC 0,X ; Decrement this timer.
 
ROM7:E4D4 skip_decrement_timer:
ROM7:E4D4 DEX
ROM7:E4D5 CPX var_0 ; = ten_frame_counter
ROM7:E4D6 BNE decrement_timer_loop ; Loop until we reach ten_frame_counter.
 
ROM7:E4D7 check_update_controllers:
ROM7:E4D7 LDA do_ppu_work_after_sprite0_next_frame
ROM7:E4D8 BNE update_prng
ROM7:E4D9 JSR update_controllers
 
ROM7:E4DA update_prng:
ROM7:E4DA LDX #prng_0
ROM7:E4DB LDY #var_13
ROM7:E4DC LDA 0,X ; a = x[0]
ROM7:E4DD AND #2 ; a = x[0] & 2
ROM7:E4DE STA var_0
ROM7:E4DF LDA 1,X ; a = x[1]
ROM7:E4E0 AND #2 ; a = x[1] & 2
ROM7:E4E1 EOR var_0 ; (a[0] & 2) xor (a[1] & 2)
ROM7:E4E2 CLC ; shift in a 0 if false
ROM7:E4E3 BEQ prng_update_loop
ROM7:E4E4 SEC ; shift in a 1 if true
 
ROM7:E4E5 prng_update_loop:
ROM7:E4E5 ROR var_0,X
ROM7:E4E6 INX
ROM7:E4E7 DEY ; loop 13 (Y)
ROM7:E4E8 BNE prng_update_loop
ROM7:E4E9 LDA #0 ; Update audio.
ROM7:E4EA JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E4EB JSR audio_update ; This is the main audio update.
ROM7:E4EC INC frame_counter ; Bump the frame counter.
ROM7:E4ED LDA active_game_mode_task ; See if we should be running task0 or task1.
ROM7:E4EE BNE run_task1 ; If active_game_mode_task != 0, jump down and run task1.
ROM7:E4EF JSR run_game_mode_task0 ; Otherwise, run task0.
ROM7:E4F0 JMP finish_frame
 
ROM7:E4F1 run_task1:
ROM7:E4F1 JSR run_game_mode_task1
 
ROM7:E4F2 finish_frame: ; Turn PPUCTRLBits_VBlank_NMI_On back on before returning.
ROM7:E4F2 LDA PPUSTATUS
ROM7:E4F3 LDA current_ppuctrl
ROM7:E4F4 ORA #PPUCTRLBits_VBlank_NMI_On
ROM7:E4F5 STA PPUCTRL
ROM7:E4F6 STA current_ppuctrl
ROM7:E4F7 RTI
 
Subroutine init_ppuscroll
ROM7:E580 init_ppuscroll:
ROM7:E580 LDA #0
ROM7:E581 STA PPUSCROLL
ROM7:E582 STA desired_ppuscroll_x
ROM7:E583 STA PPUSCROLL
ROM7:E584 STA desired_ppuscroll_y
ROM7:E585 LDA #$30
ROM7:E586 STA PPUCTRL
ROM7:E587 STA current_ppuctrl
ROM7:E588 RTS
 
Subroutine clear_ppu_data
ROM7:E594 clear_ppu_data:
ROM7:E594 STA var_0 ; var_0 = A (0x20 or 0x28)
ROM7:E595 STX var_1 ; var_1 = X (byte to write)
ROM7:E596 STY var_2 ; var_2 = Y (number of 256-byte pages to write)
ROM7:E597 LDA PPUSTATUS ; Clear PPUCTRLBits_WriteVertically
ROM7:E598 LDA current_ppuctrl
ROM7:E599 AND #$FB
ROM7:E59A STA PPUCTRL
ROM7:E59B STA current_ppuctrl
ROM7:E59C LDA var_0 ; Reload input A
ROM7:E59D STA PPUADDR ; Write 0x20 or 0x28 to write to 0x2000 or 0x2800
ROM7:E59E LDY #0 ; Y = 0
ROM7:E59F STY PPUADDR ; Write 0x00
ROM7:E5A0 LDX #4 ; X = 4: number of 256-byte pages to write (1k, a single nametable)
ROM7:E5A1 CMP #$20
ROM7:E5A2 BCS high_byte_gte_0x20 ; Branch if A >= 0x20, eg. we're writing to 0x2000 or higher
ROM7:E5A3 LDX var_2 ; X = input Y
 
ROM7:E5A4 high_byte_gte_0x20: ; Y = 0. It looks like Y can only be 0 when we get here anyway.
ROM7:E5A4 LDY #0
ROM7:E5A5 LDA var_1 ; A = input X
 
ROM7:E5A6 loop1: ; Write input X.
ROM7:E5A6 STA PPUDATA
ROM7:E5A7 DEY ; Y--
ROM7:E5A8 BNE loop1 ; Loop if Y != 0
ROM7:E5A9 DEX ; X--
ROM7:E5AA BNE loop1 ; Loop if X != 0
ROM7:E5AB LDY var_2 ; Y = input Y
ROM7:E5AC LDA var_0
ROM7:E5AD CMP #$20
ROM7:E5AE BCC ret ; Branch if A < 0x20
ROM7:E5AF ADC #2 ; Add 0x03 to the high address byte (this adds 3 rather than 2 since carry is set from the above).
ROM7:E5B0 STA PPUADDR ; Write 0x22 or 0x2A to write to 0x23C0 or 0x2BC0, which is this nametable's attribute table.
ROM7:E5B1 LDA #$C0
ROM7:E5B2 STA PPUADDR ; Write 0xC0.
ROM7:E5B3 LDX #64
 
ROM7:E5B4 loop2: ; Write input X 64 times (the size of the attribute table).
ROM7:E5B4 STY PPUDATA
ROM7:E5B5 DEX
ROM7:E5B6 BNE loop2
 
ROM7:E5B7 ret: ; Restore input X.
ROM7:E5B7 LDX var_1
ROM7:E5B8 RTS
 
Subroutine call_jump_table
ROM7:E5E2 call_jump_table:
 
ROM7:E5E2 ASL A ; A = offset past the return address to call
ROM7:E5E3 TAY ; y = a
ROM7:E5E4 PLA ; Pop the return address into var_0, var_1.
ROM7:E5E5 STA var_0
ROM7:E5E6 PLA
ROM7:E5E7 STA var_1
ROM7:E5E8 INY ; y++: y = a*2+1
ROM7:E5E9 LDA (0),Y ; c = stack1[y+0]
ROM7:E5EA STA var_2
ROM7:E5EB INY
ROM7:E5EC LDA (0),Y ; c |= stack1[y+1]
ROM7:E5ED STA var_3
ROM7:E5EE JMP (var_2)
 
Subroutine clear_oam
; Clear the OAM buffer.
ROM7:E5F7 clear_oam:
ROM7:E5F7 LDY #0
ROM7:E5F8 LDX #$40 ; 0x40 sprites
 
ROM7:E5F9 clear_oam_loop:
ROM7:E5F9 LDA #$F8
ROM7:E5FA STA sprite_oam_data,Y
ROM7:E5FB INY
ROM7:E5FC INY
ROM7:E5FD INY
ROM7:E5FE INY
ROM7:E5FF DEX
ROM7:E600 BNE clear_oam_loop
ROM7:E601 RTS
 
  ; Clear game state.
 
  ; Clear from 0x0300 to (A << 8) + Y. On startup this is called with A = 0x07, Y = 0xFE to clear
  ; 0x0300..0x07FE. When entering a new room, this is called with A = 0x05, Y = 0x1F to clear
  ; 0x0300..0x051F.
 
  ; This also sets 0x0302 to 0xFF. All other bytes are cleared to 0.
 
Subroutine reset_room_state
ROM7:E608 reset_room_state:
ROM7:E608 STA var_1 ; var_1 = A
ROM7:E609 LDA #0
ROM7:E60A STA var_0 ; var_0 = 0
 
ROM7:E60B zero_memory_loop: ; A = 0
ROM7:E60B LDA #0
ROM7:E60C STA (var_0),Y ; (*0)[y] = A
ROM7:E60D DEY ; y--
ROM7:E60E CPY #$FF ; Check if we looped
ROM7:E60F BNE zero_memory_loop ; Branch if we haven't looped
ROM7:E610 DEC var_1
ROM7:E611 LDA var_1
ROM7:E612 CMP #3
ROM7:E613 BCS zero_memory_loop
ROM7:E614 LDA #$FF
ROM7:E615 STA ppu_command_buffer ; set to 0xFF
ROM7:E616 RTS
 
Subroutine clear_ppumask
ROM7:E625 clear_ppumask:
ROM7:E625 LDA #0
ROM7:E626 STA PPUMASK ; Set to 0
ROM7:E627 STA current_ppumask ; Set to 0
ROM7:E628 RTS
 
Subroutine update_controllers
ROM7:E62D update_controllers:
ROM7:E62D LDA #1 ; update joypad
ROM7:E62E STA Joypad_1
ROM7:E62F LDA #0
ROM7:E630 STA Joypad_1
ROM7:E631 STA var_3 ; Set to 0
ROM7:E632 STA var_4 ; Set to 0
ROM7:E633 TAX
ROM7:E634 JSR read_one_controller ; Read controller 0
ROM7:E635 INX ; Fall through and read controller 1.
 
ROM7:E636 read_one_controller: ; X = controller to read
ROM7:E636 STA var_2
ROM7:E637 LDA #1
ROM7:E638 STA Joypad_1
ROM7:E639 LDA #0
ROM7:E63A STA Joypad_1
ROM7:E63B LDY #8 ; 8 buttons
 
ROM7:E63C loop: ; Read Joypad_1 or Joypad_2.
ROM7:E63C LDA Joypad_1,X
ROM7:E63D LSR A ; shift bit 1 into carry
ROM7:E63E ROL controller_1_pressed,X ; shift carry into output
ROM7:E63F LSR A
ROM7:E640 ROL var_0
ROM7:E641 DEY ; y--
ROM7:E642 BNE loop
ROM7:E643 LDA controller_1_pressed,X ; P1 buttons pressed on this frame
ROM7:E644 CMP var_2
ROM7:E645 BNE read_one_controller
ROM7:E646 INC var_3,X
ROM7:E647 LDY var_3,X
ROM7:E648 CPY #2
ROM7:E649 BCC read_one_controller
ROM7:E64A LDA var_0
ROM7:E64B ORA controller_1_pressed,X ; P1 buttons pressed on this frame
ROM7:E64C STA controller_1_pressed,X ; P1 buttons pressed on this frame
ROM7:E64D PHA
ROM7:E64E EOR controller_1_cur,X ; P1 buttons being held
ROM7:E64F AND controller_1_pressed,X ; P1 buttons pressed on this frame
ROM7:E650 STA controller_1_pressed,X ; P1 buttons pressed on this frame
ROM7:E651 PLA
ROM7:E652 STA controller_1_cur,X ; P1 buttons being held
ROM7:E653 RTS
 
Subroutine setup_minimap_triforce_position_if_holding_compass
ROM7:E679 setup_minimap_triforce_position_if_holding_compass:
ROM7:E679 LDA dungeon_idx
ROM7:E67A BEQ locret_1E6CD ; Skip if we're on the overworld.
ROM7:E67B LDA #5
ROM7:E67C JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E67D JSR check_has_compass_in_current_dungeon ; Set not equal if we have the compass for this dungeon.
ROM7:E67E BEQ locret_1E6CD ; Skip if we don't have the compass for this dungeon.
ROM7:E67F LDA ppu_data_for_current_dungeon.triforce_loc
ROM7:E680 LDX #4
ROM7:E681 JMP setup_minimap_triforce_position
 
Subroutine task0_Scrolling_1_subtask
ROM7:E68F task0_Scrolling_1_subtask:
ROM7:E68F LDY dungeon_idx
ROM7:E690 BEQ in_overworld
ROM7:E691 LDA object_direction
ROM7:E692 STA var_2
ROM7:E693 LDA #5
ROM7:E694 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E695 JSR get_dungeon_door_type ; Set A to the door type we're facing.
 
  ; In var_2: a bitmask for the directions the caller wants.
ROM7:E696 LDY var_1 ; var_1 seems to be set to var_2 by get_dungeon_door_type,
  ; which should be a bitmask for the direction we're facing.
  ; I'm not sure how this differs from object_direction, which
  ; is used in the overworld path below.
 
ROM7:E697 call_scrolling_1_task:
ROM7:E697 STY transitioning_direction
ROM7:E698 JSR call_jump_table
 
ROM7:E699   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_Door
ROM7:E69B   .WORD task0_Scrolling_1_subtask_no_transition ; DungeonDoor_Wall
ROM7:E69D   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_Push
ROM7:E69F   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_PushSilent
ROM7:E6A1   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_BombWall
ROM7:E6A3   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_LockedDoor
ROM7:E6A5   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_LockedDoor2
ROM7:E6A7   .WORD task0_Scrolling_1_subtask_0 ; DungeonDoor_ShutterDoor
ROM7:E6A9   .WORD task0_Scrolling_1_subtask_no_transition ; unknown
 
ROM7:E6AB in_overworld:
ROM7:E6AB LDY object_direction
ROM7:E6AC LDA #DungeonDoor_Door
 
ROM7:E6BC call_scrolling_1_task_thunk: ; Always branches
ROM7:E6BC BEQ call_scrolling_1_task
 
ROM7:E6BE powers_of_two: .BYTE 1
ROM7:E6BF   .BYTE 2
ROM7:E6C0   .BYTE 4
ROM7:E6C1   .BYTE 8
ROM7:E6C2   .BYTE $10
ROM7:E6C3   .BYTE $20
ROM7:E6C4   .BYTE $40
ROM7:E6C5   .BYTE $80
 
Subroutine mark_map_location_visited
ROM7:E6C6 mark_map_location_visited:
ROM7:E6C6 JSR get_screen_status ; Load to set ScreenStatus_Visited.
ROM7:E6C7 ORA #ScreenStatusDungeon_Visited
ROM7:E6C8 STA (var_0),Y
 
ROM7:E6CD locret_1E6CD:
ROM7:E6CD RTS
 
Subroutine get_screen_status
; Out Y = map location ; Out A = screen status for the current screen ; Out var_0 = pointer to screen status for this dungeon ; Bits 0x0F (dungeons): direction mask for bombed/opened doors ; Bits 0x07 (overworld): number of enemies killed or 0x7 if all killed
ROM7:E6CE get_screen_status:
ROM7:E6CE LDA ppu_data_for_current_dungeon.screen_status_ptr
ROM7:E6CF STA var_0
ROM7:E6D0 LDA ppu_data_for_current_dungeon.screen_status_ptr+1
ROM7:E6D1 STA var_1
ROM7:E6D2 LDY map_location
ROM7:E6D3 LDA (var_0),Y
ROM7:E6D4 RTS
 
Function chunk for update_floor_item_sprite
ROM7:E6D5 move_floor_item_to_first_enemy:
ROM7:E6D5 LDA object_x_1
ROM7:E6D6 STA floor_item_x
ROM7:E6D7 LDA object_y_1
ROM7:E6D8 STA floor_item_y
ROM7:E6D9 JMP return_from_move_floor_item
 
ROM7:E6DA pop_a_and_return:
ROM7:E6DA PLA
 
ROM7:E6DB ret:
ROM7:E6DB RTS
 
Subroutine update_floor_item_sprite
ROM7:E6EA update_floor_item_sprite:
 
ROM7:E6EA JSR get_room_status_floor_item_picked_up
ROM7:E6EB BNE ret
ROM7:E6EC LDA current_room_floor_item_hidden ; Return if 0xFF.
ROM7:E6ED BMI ret
ROM7:E6EE LDA current_floor_item ; Return if the floor item is ObjectType_Flame.
ROM7:E6EF CMP #ObjectType_Flame
ROM7:E6F0 BEQ ret
ROM7:E6F1 LDX #1 ; X = 1 if this is a floor item being held by an enemy.
ROM7:E6F2 LDA object_type_1 ; Check if the first enemy in the screen is one that can
  ; hold items.
ROM7:E6F3 CMP #ObjectType_LikeLike
ROM7:E6F4 BEQ move_floor_item_to_first_enemy
ROM7:E6F5 CMP #ObjectType_Stalfos
ROM7:E6F6 BEQ move_floor_item_to_first_enemy
ROM7:E6F7 CMP #ObjectType_Gibdo
ROM7:E6F8 BEQ move_floor_item_to_first_enemy
ROM7:E6F9 LDX #$13 ; X = 13 if this is a regular floor item.
 
ROM7:E6FA return_from_move_floor_item:
ROM7:E6FA LDA current_floor_item
 
ROM7:E70E setup_sprite: ; Push floor item
ROM7:E70E PHA
ROM7:E70F LDA object_tile_offset_fraction,X ; Get the tile offset fraction either for the floor item or
  ; the enemy that's holding it.
ROM7:E710 CMP #$F0
ROM7:E711 BCC not_out_of_bounds ; Branch if object_tile_offset_fraction[X] < 0xF0
ROM7:E712 LSR A
ROM7:E713 BCC pop_a_and_return ; Branch if (object_tile_offset_fraction[X] & 0x01) == 0
 
ROM7:E714 not_out_of_bounds: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:E714 JSR set_var_0_to_object_position
ROM7:E715 PLA ; Pop floor item
ROM7:E716 TAX ; X = A (floor item)
ROM7:E717 LDA floor_item_flags,X ; 0xF is the level of the item or the number of the item to
  ; give. This is used both to tell what level to set items to
  ; after a pickup, and the frame offset for the item's sprite.
 
  ; FloorItem_Bomb
ROM7:E718 CMP #$30 ; 0x30 isn't a value in this table. This doesn't seem to be used.
ROM7:E719 BEQ sprite_offset_minus_one
ROM7:E71A AND #$F
 
ROM7:E71B return_from_sprite_offset_minus_one: ; Store the offset to the item level's sprite.
ROM7:E71B STA var_4
ROM7:E71C LDA floor_item_to_inventory_item,X
ROM7:E71D TAX
ROM7:E71E TAY
ROM7:E71F JMP load_frame_offset
 
ROM7:E720 sprite_offset_minus_one: ; Set to -1, to subtract one from the object's sprite instead
ROM7:E720 LDA #$FF ; of adding a value.
ROM7:E721 BNE return_from_sprite_offset_minus_one ; Always branch
 
ROM7:E735 update_inventory_item_sprite: ; This points to num_rupees.
ROM7:E735 LDA sword_type,X
ROM7:E736 STA var_4 ; Store the item upgrade level for this inventory item.
 
ROM7:E737 load_frame_offset:
ROM7:E737 LDA floor_item_frame_offset,X
ROM7:E738 CPX #InventoryItem_Rupee
ROM7:E739 BEQ flash_every_8_frames
ROM7:E73A CPX #InventoryItem_TriforcePiece
ROM7:E73B BEQ flash_every_8_frames
ROM7:E73C CPX #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
ROM7:E73D BEQ flash_every_8_frames
ROM7:E73E CPX #InventoryItem_Heart
ROM7:E73F BNE no_flash ; For other items, use the frame offset from floor_item_frame_offset.
 
ROM7:E740 flash_every_8_frames: ; These floor items switch every 8 frames.
ROM7:E740 LDA frame_counter
ROM7:E741 AND #8
ROM7:E742 LSR A
ROM7:E743 LSR A
ROM7:E744 LSR A
ROM7:E745 ADC #1 ; ((frame >> 3) & 1) + 1
 
ROM7:E746 no_flash: ; Items that have more than one version
ROM7:E746 CPX #InventoryItem_Sword
ROM7:E747 BEQ get_frame_from_inventory
ROM7:E748 CPX #InventoryItem_Candle
ROM7:E749 BEQ get_frame_from_inventory
ROM7:E74A CPX #InventoryItem_Arrow
ROM7:E74B BEQ get_frame_from_inventory
ROM7:E74C CPX #InventoryItem_Potion
ROM7:E74D BEQ get_frame_from_inventory
ROM7:E74E CPX #InventoryItem_Ring ; Passives
ROM7:E74F BEQ get_frame_from_inventory
 
ROM7:E750 loop2:
ROM7:E750 LDX #0
ROM7:E751 STX var_12 ; Set to 0
ROM7:E752 LDX #$F
ROM7:E753 JMP sub_10790C
 
ROM7:E754 get_frame_from_inventory:
ROM7:E754 CLC
ROM7:E755 ADC var_4 ; Add var_4 (the item upgrade level) to floor_item_frame_offset
  ; to change it to the upgraded item sprite.
ROM7:E756 CPX #InventoryItem_Sword ; Check if we're drawing the magical sword.
ROM7:E757 BNE loop2
ROM7:E758 CMP #2 ; Item level 2 (magical sword)
ROM7:E759 BNE loop2
ROM7:E75A LDY #$20 ; This changes the sprite index to 0x20 for the magical sword.
  ; I'm not sure what this is for (this changes the OAM sprite
  ; offset, not the sprite tile).
ROM7:E75B JMP loop2
 
Subroutine select_potion
ROM7:E783 select_potion:
ROM7:E783 LDX #InventoryItem_Potion
ROM7:E784 STX current_item
ROM7:E785 BNE letter_not_selected ; Always branch
 
ROM7:E78A check_if_item_selection_is_valid:
ROM7:E78A LDX current_item
ROM7:E78B BEQ no_item_selected
ROM7:E78C LDA sword_type,X
ROM7:E78D BEQ selected_item_not_owned ; branch if 0 (don't have item)
ROM7:E78E CPX #InventoryItem_Letter
ROM7:E78F BNE letter_not_selected
ROM7:E790 LDY have_potion_type
ROM7:E791 BNE select_potion ; If the letter is selected and we have a potion, select the potion instead.
ROM7:E792 LSR A
ROM7:E793 ORA #1
 
ROM7:E794 letter_not_selected:
ROM7:E794 STA var_4
ROM7:E795 LDA #$1F
ROM7:E796 STA var_1
ROM7:E797 LDA #$7C
ROM7:E798 STA var_0
ROM7:E799 LDA #5
ROM7:E79A JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E79B JSR loc_1781C
ROM7:E79C JMP loc_1E7D7
 
ROM7:E79D no_item_selected:
ROM7:E79D LDX #InventoryItem_MagicBoomerang
 
ROM7:E79E find_owned_item: ; Find an item that the player has for us to select.
ROM7:E79E LDA sword_type,X
ROM7:E79F BNE letter_not_selected
ROM7:E7A0 DEX
ROM7:E7A1 CPX #$1C
ROM7:E7A2 BNE find_owned_item
ROM7:E7A3 LDX #0
ROM7:E7A4 JMP loc_1E7CB
 
ROM7:E7C6 loc_1E7C6:
ROM7:E7C6 LDA sword_type,X
ROM7:E7C7 BNE loc_1E7D7
 
ROM7:E7CB loc_1E7CB:
ROM7:E7CB TXA
ROM7:E7CC TAY
ROM7:E7CD LDA #5
ROM7:E7CE JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E7CF LDA #2
ROM7:E7D0 JSR loc_177C8
 
ROM7:E7D7 loc_1E7D7:
ROM7:E7D7 LDX #0
ROM7:E7D8 LDA sword_type,X
ROM7:E7D9 BEQ locret_1E847
ROM7:E7DA LDA #$1F
ROM7:E7DB STA var_1
ROM7:E7DC LDA #$94
ROM7:E7DD STA var_0
ROM7:E7DE LDA #5
ROM7:E7DF JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E7E0 JMP loc_1781C
 
ROM7:E7E1 selected_item_not_owned:
ROM7:E7E1 CPX #InventoryItem_Potion
ROM7:E7E2 BNE loc_1E7C6
ROM7:E7E3 LDA have_letter ; The potion was selected, and we don't have any potions.
  ; Do we have the letter?
ROM7:E7E4 BEQ loc_1E7CB
ROM7:E7E5 LDX #InventoryItem_Letter ; Switch to the letter after using up potions.
ROM7:E7E6 STX current_item
ROM7:E7E7 BNE loc_1E7C6 ; Always branch
 
Subroutine update_hold_up_item
; Update Link holding an item over his head.
ROM7:E7FE update_hold_up_item:
ROM7:E7FE LDA picking_up_item ; Return if we're not holding up an item.
ROM7:E7FF BEQ ret
ROM7:E800 DEC picking_up_item_timer ; Branch if it's time to stop holding up the item.
ROM7:E801 BEQ picking_up_item_timer_expired
ROM7:E802 LDA #WalkState_3_MovementLocked ; Lock movement while holding up an item.
ROM7:E803 STA walk_state_and_weapon_state
 
ROM7:E80C update_hold_up_item_1: ; Put the held item at Link's X position, and Link's Y position - 0x10.
ROM7:E80C LDA object_x
ROM7:E80D STA floor_item_x
ROM7:E80E LDA object_y
ROM7:E80F SEC
ROM7:E810 SBC #$10
ROM7:E811 STA floor_item_y
 
ROM7:E817 update_hold_up_item_2:
ROM7:E817 LDX #0
ROM7:E818 JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:E819 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:E81A STA var_12
ROM7:E81B LDA #$48
ROM7:E81C STA updating_oam_sprite_id_1
ROM7:E81D LDA #$4C
ROM7:E81E STA updating_oam_sprite_id_2
ROM7:E81F LDY #$21
ROM7:E820 JSR loc_10792C
ROM7:E821 INC disable_sprite_horizontal_offset ; Set to 1, so setup_sprite will place the sprite further
  ; left than it normally does to align it over Link correctly.
ROM7:E822 LDA picking_up_item ; If Link is holding an item above his head, this is the InventoryItem being held up.
ROM7:E823 LDX #$13
ROM7:E824 JSR setup_sprite
ROM7:E825 DEC disable_sprite_horizontal_offset ; Set to 0
ROM7:E826 LDA byte_52
ROM7:E827 BEQ locret_1E847
ROM7:E828 LDA #8
ROM7:E829 STA sprite_oam_data_4D
 
ROM7:E847 locret_1E847:
ROM7:E847 RTS
 
ROM7:E848 picking_up_item_timer_expired:
ROM7:E848 LDA #0
ROM7:E849 STA walk_state_and_weapon_state ; Set to 0
ROM7:E84A STA picking_up_item ; Set to 0
ROM7:E84B LDY dungeon_idx
ROM7:E84C BEQ ret
ROM7:E84D LDA music_per_dungeon,Y
ROM7:E84E STA play_music ; Play Music_Overworld, Music_Dungeon or Music_DeathMountain
 
ROM7:E84F ret:
ROM7:E84F RTS
 
Subroutine dungeon_get_screen_code
; Set A to the screen code of the current location when in a dungeon.
ROM7:E85A dungeon_get_screen_code:
ROM7:E85A LDY map_location
ROM7:E85B LDA dungeon_screen_data_3,Y
ROM7:E85C AND #ScreenData_Dungeon_3_ScreenCode
ROM7:E85D RTS
 
Subroutine change_background_tile_at_current_object_position
; Change the background tile at the screen position of the ; current object to A. This is used to remove things like ; Armos statues and candle spots after they've been activated. ; ; This is called from both ROM4 and ROM5. ; ; If ppu_unknown_task_returns_to_ROM4 is set, this is being ; called from ROM4 and needs to reset bank 0 to ROM4 before ; it returns. ; ; Otherwise, it's being called from ROM5 and will set bank ROM5 ; before returning.
ROM7:E862 change_background_tile_at_current_object_position:
ROM7:E862 STA var_5
ROM7:E863 TXA
ROM7:E864 PHA
ROM7:E865 LDA object_x,X
ROM7:E866 STA var_3
ROM7:E867 LDA object_y,X
ROM7:E868 STA var_2
ROM7:E869 JSR sub_107570
ROM7:E86A LDX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM7:E86B LDA var_0
ROM7:E86C STA ppu_command_buffer,X
ROM7:E86D STA ppu_command_buffer_05,X
ROM7:E86E LDA var_1
ROM7:E86F STA ppu_command_buffer_01,X
ROM7:E870 STA ppu_command_buffer_06,X
ROM7:E871 INC ppu_command_buffer_06,X
ROM7:E872 LDA var_5
ROM7:E873 STA ppu_command_buffer_03,X
ROM7:E874 STA ppu_command_buffer_04,X
ROM7:E875 STA ppu_command_buffer_08,X
ROM7:E876 STA ppu_command_buffer_09,X
ROM7:E877 CMP #$46
ROM7:E878 BCC loc_1E8AC
ROM7:E879 CMP #$F3
ROM7:E87A BCS loc_1E8AC
ROM7:E87B CLC
ROM7:E87C ADC #2
ROM7:E87D STA ppu_command_buffer_08,X
ROM7:E87E STA ppu_command_buffer_09,X
ROM7:E87F INC ppu_command_buffer_04,X
ROM7:E880 INC ppu_command_buffer_09,X
 
ROM7:E8AC loc_1E8AC:
ROM7:E8AC LDA #$82
ROM7:E8AD STA ppu_command_buffer_02,X
ROM7:E8AE STA ppu_command_buffer_07,X
ROM7:E8AF LDA #$FF
ROM7:E8B0 STA ppu_command_buffer_0A,X
ROM7:E8B1 TXA
ROM7:E8B2 CLC
ROM7:E8B3 ADC #$A
ROM7:E8B4 STA ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM7:E8B5 PLA
ROM7:E8B6 TAX
ROM7:E8B7 LDA #5
ROM7:E8B8 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E8B9 JSR sub_16BC4
ROM7:E8BA LDA ppu_unknown_task_returns_to_ROM4 ; Check which bank needs to be set before returning.
  ; If this is set, change to ROM4.
ROM7:E8BB BEQ skip_bank_change
ROM7:E8BC LDA #4
ROM7:E8BD JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
 
ROM7:E8BE skip_bank_change:
ROM7:E8BE LDA #0
ROM7:E8BF STA ppu_unknown_task_returns_to_ROM4
ROM7:E8C0 RTS
 
Subroutine clear_room_tiles_to_var_10
; Clear the current room's tile data (0x6530-0x67EF) to var_10.
ROM7:E8D8 clear_room_tiles_to_var_10:
ROM7:E8D8 LDA #5
ROM7:E8D9 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E8DA JSR set_var0_to_current_tile_data ; Set 16-bit var0 to room_tiles_x_00 (0x6530), which is
  ; the memory block holding the current room's tile data.
ROM7:E8DB LDY #0
 
ROM7:E8DC loop:
ROM7:E8DC LDA var_10
ROM7:E8DD STA (0),Y
ROM7:E8DE JSR increment_16bit_var0_by_1 ; 16-bit var0++
ROM7:E8DF LDA var_0
ROM7:E8E0 CMP #$F0 ; Loop until 16-bit var_0 == 0x67F0
ROM7:E8E1 BNE loop
ROM7:E8E2 LDA var_1
ROM7:E8E3 CMP #$67
ROM7:E8E4 BNE loop
ROM7:E8E5 RTS
 
ROM7:E8E6   .BYTE $FF
ROM7:E8E7   .BYTE $FF
 
Subroutine run_game_mode_task0
ROM7:E8F8 run_game_mode_task0:
ROM7:E8F8 LDA sram_init_finished ; If 0, run_game_mode_task0 will copy the code block to SRAM.
ROM7:E8F9 BNE call_task0 ; Skip if the SRAM code block initialization has already been done.
ROM7:E8FA LDA #1
ROM7:E8FB JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E8FC JSR init_sram_code ; Copy the code block from ROM1:90A5 to CODE:6C90.
ROM7:E8FD LDA #6
ROM7:E8FE JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E8FF JSR copy_some_ppu_data
ROM7:E900 LDA #$5A
ROM7:E901 STA sram_check_byte ; Save "valid sram"
ROM7:E902 LDA #$A5
ROM7:E903 STA sram_check_byte2
ROM7:E904 INC sram_init_finished ; If 0, run_game_mode_task0 will copy the code block to SRAM.
ROM7:E905 RTS
 
ROM7:E906 call_task0:
ROM7:E906 LDA #5
ROM7:E907 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E908 LDA game_mode
ROM7:E909 JSR call_jump_table
 
ROM7:E90A   .WORD task0_Title ; GameMode_Title
ROM7:E90C   .WORD task0_MainMenu ; GameMode_MainMenu
ROM7:E90E   .WORD task0_LoadDungeon ; GameMode_LoadDungeon
ROM7:E910   .WORD task0_CurtainsOpening ; GameMode_CurtainsOpening
ROM7:E912   .WORD task0_FinishingScroll ; GameMode_FinishScroll
ROM7:E914   .WORD task0_Normal ; GameMode_Normal
ROM7:E916   .WORD task0_PreparingScroll ; GameMode_PrepareScroll
ROM7:E918   .WORD task0_Scrolling ; GameMode_Scroll
ROM7:E91A   .WORD task0_GameOverMenu ; GameMode_GameOverMenu
ROM7:E91C   .WORD task0_InDungeonCellar ; GameMode_InDungeonCellar
ROM7:E91E   .WORD task0_ExitingCellar ; GameMode_ExitingCellar
ROM7:E920   .WORD task0_InOverworldCellar ; GameMode_InOverworldCellar
ROM7:E922   .WORD task0_ExitingOverworldCellar ; GameMode_ExitingOverworldCellar
ROM7:E924   .WORD task0_EndCredits ; GameMode_EndCredits
ROM7:E926   .WORD task0_CreateDeleteSave ; GameMode_CreateSave
ROM7:E928   .WORD task0_CreateDeleteSave ; GameMode_DeleteSave
ROM7:E92A   .WORD task0_EnteringDoor ; GameMode_EnteringDoor
ROM7:E92C   .WORD task0_JustDied ; GameMode_JustDied
ROM7:E92E   .WORD task0_PickedUpTriforce ; GameMode_PickedUpTriforce
ROM7:E930   .WORD task0_FoundZelda ; GameMode_FoundZelda
 
Subroutine task0_Title
ROM7:E94B task0_Title:
 
ROM7:E94B LDA sprite_data_1_initialized
ROM7:E94C CMP #$5A
ROM7:E94D BEQ skip_setup_sprite_data_1 ; Branch if we've already done this initialization.
  ; I'm not sure if there's any special meaning to the 0x5A
  ; constant.
ROM7:E94E LDA #2
ROM7:E94F JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E950 JMP setup_rom2_sprite_data ; Copy a block of sprite data to the PPU.
 
ROM7:E951 skip_setup_sprite_data_1: ; This is set to a magic value 0xA5 after first initialization,
ROM7:E951 LDA sprite_data_2_initialized ; and set to the controller start input after a start press.
ROM7:E952 CMP #$A5
ROM7:E953 BEQ skip_setup_sprite_data_2
ROM7:E954 LDA #1
ROM7:E955 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E956 JMP setup_rom1_sprite_data ; Copy a block of sprite data to the PPU.
 
ROM7:E957 skip_setup_sprite_data_2:
ROM7:E957 LDA #2
ROM7:E958 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E959 JMP task0_title_continue
 
Subroutine task0_MainMenu
ROM7:E96F task0_MainMenu:
ROM7:E96F LDA #2
ROM7:E970 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E971 JMP task0_MainMenu_main
 
Subroutine task0_LoadDungeon
ROM7:E977 task0_LoadDungeon:
ROM7:E977 JSR clear_ppumask
ROM7:E978 LDA task_state ; In task_state 0, clear our a bunch of dungeon-specific
  ; data and reinitialize SRAM code.
ROM7:E979 BNE task_state_not_zero
ROM7:E97A JSR clear_screen_history_and_clear_force_beam_sword
ROM7:E97B LDY #$7F ; Clear number_of_enemies_killed_in_dungeon_room.
 
ROM7:E97C loop: ; Set to 0
ROM7:E97C STA number_of_enemies_killed_in_dungeon_room,Y
ROM7:E97D DEY
ROM7:E97E BPL loop
ROM7:E97F LDA #3
ROM7:E980 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E981 JSR task0_LoadDungeon_0
ROM7:E982 LDA #1
ROM7:E983 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E984 JSR init_sram_code ; Copy the code block from ROM1:90A5 to CODE:6C90.
 
ROM7:E985 task_state_not_zero:
ROM7:E985 LDA #6
ROM7:E986 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E987 JMP setup_dungeon
 
Subroutine task0_Scrolling
ROM7:E9A1 task0_Scrolling:
ROM7:E9A1 LDA #5
ROM7:E9A2 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E9A3 JSR task0_Scrolling_work
ROM7:E9A4 LDA do_ppu_work_after_sprite0_next_frame
ROM7:E9A5 BEQ ret
ROM7:E9A6 LDA byte_F3
ROM7:E9A7 BNE ret
ROM7:E9A8 INC byte_F3
ROM7:E9A9 LDA object_direction
ROM7:E9AA CMP #ControllerBits_Dpad_Down
ROM7:E9AB BCC horizontal
ROM7:E9AC LDA #MMCControl_HorizontalMirroring|MMCControl_PRGMode_FixedBank1 ; #MMCControl_HorizontalMirroring for vertical movement.
ROM7:E9AD BNE call_set_mmc_control_register ; Always branch.
 
ROM7:E9AE horizontal: ; MMCControl_VerticalMirroring for horizontal movement.
ROM7:E9AE LDA #MMCControl_VerticalMirroring|MMCControl_PRGMode_FixedBank1
 
ROM7:E9AF call_set_mmc_control_register:
ROM7:E9AF JSR set_mmc_control_register
 
ROM7:E9B0 ret:
ROM7:E9B0 RTS
 
Subroutine task0_CreateDeleteSave
ROM7:E9C3 task0_CreateDeleteSave:
 
ROM7:E9C3 LDA #2
ROM7:E9C4 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E9C5 JMP task0_CreateDeleteSave_main
 
Subroutine task0_FoundZelda
ROM7:E9CB task0_FoundZelda:
 
ROM7:E9CB LDA #$F
ROM7:E9CC JSR set_mmc_control_register
ROM7:E9CD LDA #2
ROM7:E9CE JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E9CF JMP secondary_FoundZelda_main
 
Subroutine task0_CurtainsOpening
ROM7:E9D8 task0_CurtainsOpening:
ROM7:E9D8 LDA #5
ROM7:E9D9 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:E9DA JSR clear_ppumask
ROM7:E9DB LDA task_state
ROM7:E9DC JSR call_jump_table
 
ROM7:E9DD   .WORD task0_CurtainsOpening_0
ROM7:E9DF   .WORD task0_CurtainsOpening_1
ROM7:E9E1   .WORD task0_CurtainsOpening_2
ROM7:E9E3   .WORD task0_CurtainsOpening_3
ROM7:E9E5   .WORD task0_CurtainsOpening_4
ROM7:E9E7   .WORD task0_CurtainsOpening_5
ROM7:E9E9   .WORD task0_CurtainsOpening_6
ROM7:E9EB   .WORD task0_CurtainsOpening_7
ROM7:E9ED   .WORD task0_CurtainsOpening_8
 
Subroutine task0_CurtainsOpening_0
ROM7:E9F7 task0_CurtainsOpening_0:
ROM7:E9F7 LDA #1
ROM7:E9F8 STA curtains_currently_opening
ROM7:E9F9 INC task_state
ROM7:E9FA JSR clear_nametables
 
Subroutine clear_screen_history_and_clear_force_beam_sword
ROM7:EA00 clear_screen_history_and_clear_force_beam_sword:
ROM7:EA00 LDY #5
ROM7:EA01 LDA #0
ROM7:EA02 STA force_beam_sword ; Set to 0
 
ROM7:EA03 loop:
ROM7:EA03 STA screen_history_0,Y
ROM7:EA04 DEY
ROM7:EA05 BPL loop
ROM7:EA06 RTS
 
ROM7:EA0E byte_1EA0E: .BYTE 0
ROM7:EA0F   .BYTE 4
ROM7:EA10   .BYTE 8
 
Subroutine task0_CurtainsOpening_1
ROM7:EA11 task0_CurtainsOpening_1:
ROM7:EA11 LDA dungeon_idx
ROM7:EA12 BNE entering_dungeon
ROM7:EA13 LDA overworld_return_pos ; If we're entering the overworld, restore the position we left it from
ROM7:EA14 CMP #$FF
ROM7:EA15 BNE valid_return_pos ; Store the initial map position
 
ROM7:EA16 entering_dungeon: ; If we're entering a dungeon, load the dungeon's start position
ROM7:EA16 LDA ppu_data_for_current_dungeon.start_loc
 
ROM7:EA17 valid_return_pos: ; Store the initial map position
ROM7:EA17 STA map_location
ROM7:EA18 CMP overworld_return_pos
ROM7:EA19 BNE loc_1EA2B
ROM7:EA1A LDA #$FF
ROM7:EA1B STA overworld_return_pos ; Set to 0xFF
 
ROM7:EA2B loc_1EA2B:
ROM7:EA2B LDX current_save_slot
ROM7:EA2C LDY byte_1EA0E,X
ROM7:EA2D LDA byte_26804,Y
ROM7:EA2E STA ppu_data_for_current_dungeon.ppu_data+$11
ROM7:EA2F LDA #PPUCommandIndices_DungeonPPUData ; This sends ppu_data_for_current_dungeon.
ROM7:EA30 STA current_ppu_command_index ; Set to PPUCommandIndices_PickedUpTriforce_1.
ROM7:EA31 INC task_state
ROM7:EA32 RTS
 
Subroutine update_minimap_and_link_sprite
ROM7:EA3D update_minimap_and_link_sprite:
ROM7:EA3D JSR clear_oam ; Clear the OAM buffer.
ROM7:EA3E JSR setup_minimap_triforce_position_unless_in_cellar_or_whirlwind
ROM7:EA3F JSR setup_minimap_triforce_position_if_holding_compass
ROM7:EA40 LDA #5
ROM7:EA41 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EA42 JSR update_link_sprite_and_other_stuff ; This calls update_link_sprite_and_check_ladder_if_overworld (if not in GameMode_InOverworldCellar
  ; or GameMode_ExitingOverworldCellar), and does some other things that I haven't traced. They seem
  ; to be sprite update-related.
ROM7:EA43 JMP check_if_item_selection_is_valid
 
Subroutine deactivate_clock_and_walk_state
ROM7:EA51 deactivate_clock_and_walk_state:
ROM7:EA51 LDA #0
ROM7:EA52 STA walk_state_and_weapon_state
ROM7:EA53 STA clock_active
ROM7:EA54 RTS
 
ROM7:EA59 special_palette_mapping_values: .BYTE PPUCommandIndices_SpecialPaletteMapping_Aquamentus
ROM7:EA5A   .BYTE PPUCommandIndices_SpecialPaletteMapping_Ganon
ROM7:EA5B   .BYTE PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo
ROM7:EA5C   .BYTE PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo
ROM7:EA5D   .BYTE PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo
ROM7:EA5E   .BYTE PPUCommandIndices_SpecialPaletteMapping_Digdogger_Dodongo
ROM7:EA5F   .BYTE PPUCommandIndices_SpecialPaletteMapping_Gleeok
ROM7:EA60   .BYTE PPUCommandIndices_SpecialPaletteMapping_Gleeok
ROM7:EA61   .BYTE PPUCommandIndices_SpecialPaletteMapping_Gleeok
ROM7:EA62 objects_with_special_palette_mappings: .BYTE ObjectType_Aquamentus
ROM7:EA63   .BYTE ObjectType_Ganon
ROM7:EA64   .BYTE ObjectType_Digdogger_3
ROM7:EA65   .BYTE ObjectType_Digdogger_1
ROM7:EA66   .BYTE ObjectType_DodongoBoss
ROM7:EA67   .BYTE ObjectType_DodongoMiniboss
ROM7:EA68   .BYTE ObjectType_Gleeok_2_Heads
ROM7:EA69   .BYTE ObjectType_Gleeok_3_Heads
ROM7:EA6A   .BYTE ObjectType_Gleeok_4_Heads
 
Subroutine task0_Normal
ROM7:EA6B task0_Normal:
 
ROM7:EA6B JSR update_minimap_and_link_sprite
ROM7:EA6C JSR update_link_sprite_and_check_ladder ; This handles a couple things: updating Link's walking sprite
  ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
ROM7:EA6D LDA dungeon_idx
ROM7:EA6E BEQ overworld
ROM7:EA6F LDY #8 ; 8 special_palette_mapping entries
ROM7:EA70 LDA object_type_1 ; See if the first enemy has a special palette mapping.
 
ROM7:EA71 find_special_palette_mapping:
ROM7:EA71 CMP objects_with_special_palette_mappings,Y
ROM7:EA72 BNE wrong_enemy_id
ROM7:EA73 LDX special_palette_mapping_values,Y ; Get the palette index
ROM7:EA74 BNE store_x_to_current_ppu_command_index
 
ROM7:EA75 wrong_enemy_id:
ROM7:EA75 DEY
ROM7:EA76 BPL find_special_palette_mapping
ROM7:EA77 BMI dungeon ; Always branch.
 
ROM7:EA78 overworld: ; Check if this overworld location plays the secret sound when entered.
ROM7:EA78 LDA map_location
ROM7:EA79 CMP #$F
ROM7:EA7A BNE no_secret_sound
ROM7:EA7B LDA is_in_cellar
ROM7:EA7C BNE no_secret_sound
ROM7:EA7D LDA #Sound1_Secret
ROM7:EA7E STA play_sound_1 ; Play Sound1_Secret
 
ROM7:EA7F no_secret_sound:
ROM7:EA7F LDX #PPUCommandIndices_Unknown_20
ROM7:EA80 LDA object_type_B
ROM7:EA81 CMP #ObjectType_OverworldSecret_Push_Tomb ; An overworld push block (tomb sprite).
ROM7:EA82 BEQ store_x_to_current_ppu_command_index
ROM7:EA83 CMP #ObjectType_OverworldSecret_Push_Armos ; An overworld push block (Armos sprite).
ROM7:EA84 BEQ loc_1EAAB
ROM7:EA85 CMP #ObjectType_OverworldSecret_Push_Rock ; An overworld push block (rock sprite).
ROM7:EA86 BNE loc_1EAB8
ROM7:EA87 LDX #PPUCommandIndices_Unknown_24
 
ROM7:EAAB loc_1EAAB:
ROM7:EAAB LDY map_location
ROM7:EAAC LDA dungeon_screen_data_1,Y
ROM7:EAAD AND #1
ROM7:EAAE BNE store_x_to_current_ppu_command_index
ROM7:EAAF LDX #PPUCommandIndices_Unknown_22
ROM7:EAB0 BNE store_x_to_current_ppu_command_index ; Always branch.
 
ROM7:EAB8 loc_1EAB8:
ROM7:EAB8 LDX #PPUCommandIndices_Unknown_7A
ROM7:EAB9 BNE store_x_to_current_ppu_command_index ; Always branch.
 
ROM7:EABA dungeon:
ROM7:EABA LDY #3
 
ROM7:EABB loop:
ROM7:EABB LDA ppu_data_for_current_dungeon.ppu_data+$1C,Y
ROM7:EABC STA unk_26817,Y
ROM7:EABD DEY
ROM7:EABE BPL loop
ROM7:EABF LDX #PPUCommandIndices_Unknown_Copied_Data_1
 
ROM7:EAC0 store_x_to_current_ppu_command_index: ; Set to PPUCommandIndices_Unknown_6, PPUCommandIndices_Unknown_22, PPUCommandIndices_Unknown_24, 0x65, 0x7A or special_palette_mapping_indices
ROM7:EAC0 STX current_ppu_command_index
 
ROM7:EACB task0_Normal_1: ; These are called from other task0 handlers that are partially like Normal,
ROM7:EACB LDA #5 ; like InOverworldCellar.
ROM7:EACC JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EACD JSR setup_screen_bounds
 
ROM7:EAD3 task0_Normal_2:
ROM7:EAD3 LDA dungeon_idx
ROM7:EAD4 BEQ task0_Normal_3 ; Skip this in the overworld
ROM7:EAD5 JSR mark_map_location_visited
ROM7:EAD6 JSR setup_dungeon_only_sprites
 
ROM7:EADD task0_Normal_3:
ROM7:EADD LDA #5
ROM7:EADE JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EADF JSR setup_room_items
ROM7:EAE0 LDY #0 ; Zero counter for the current screen in screen history
ROM7:EAE1 LDX #5 ; Loop over each screen history entry
ROM7:EAE2 LDA map_location
 
ROM7:EAE3 loop_screen_history: ; Find the current screen in screen history
ROM7:EAE3 CMP screen_history_0,X
ROM7:EAE4 BNE not_this_screen
ROM7:EAE5 INY ; Found it (probably only once)
 
ROM7:EAE6 not_this_screen:
ROM7:EAE6 DEX
ROM7:EAE7 BPL loop_screen_history
ROM7:EAE8 CPY #0 ; Y > 0 if the current screen is in history
ROM7:EAE9 BNE skip ; Branch if the current screen is already in screen history
ROM7:EAEA LDX screen_history_idx ; Load to store a new screen index in history
ROM7:EAEB STA screen_history_0,X ; Add the current screen to history.
  ; Note that this doesn't keep an MRU, it just overwrites entries
  ; in the order they were added.
ROM7:EAEC INC screen_history_idx ; Increment the next index to store screen history to
ROM7:EAED LDA screen_history_idx ; Load to wrap to 0
ROM7:EAEE CMP #6 ; If 6, wrap to 0.
ROM7:EAEF BCC skip
ROM7:EAF0 LDA #0
ROM7:EAF1 STA screen_history_idx ; Store after wrapping to 0
 
ROM7:EAF2 skip:
ROM7:EAF2 LDA game_mode
ROM7:EAF3 CMP #GameMode_Normal
ROM7:EAF4 BNE not_normal
ROM7:EAF5 LDA dungeon_idx
ROM7:EAF6 BEQ in_overworld
ROM7:EAF7 LDA #5
ROM7:EAF8 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EAF9 JSR check_boss_roar
 
ROM7:EAFA not_normal: ; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
ROM7:EAFA JMP start_task1
 
ROM7:EAFB in_overworld:
ROM7:EAFB LDA #1
ROM7:EAFC JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EAFD JMP task0_Normal_p2
 
ROM7:EAFE   .BYTE $FF
ROM7:EAFF   .BYTE $FF
ROM7:EB00   .BYTE $FF
ROM7:EB01   .BYTE $FF
ROM7:EB02   .BYTE $FF
ROM7:EB03   .BYTE $FF
 
Subroutine run_game_mode_task1
ROM7:EB30 run_game_mode_task1:
ROM7:EB30 LDA #2
ROM7:EB31 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB32 LDA game_mode
ROM7:EB33 JSR call_jump_table
 
ROM7:EB34   .WORD task1_Title ; GameMode_Title
ROM7:EB36   .WORD task1_MainMenu ; GameMode_MainMenu
ROM7:EB38   .WORD task1_LoadDungeon ; GameMode_LoadDungeon
ROM7:EB3A   .WORD task1_CurtainsOpening ; GameMode_CurtainsOpening
ROM7:EB3C   .WORD task1_FinishScroll ; GameMode_FinishScroll
ROM7:EB3E   .WORD task1_Normal ; GameMode_Normal
ROM7:EB40   .WORD task1_FinishScroll ; GameMode_PrepareScroll
ROM7:EB42   .WORD task1_Scroll ; GameMode_Scroll
ROM7:EB44   .WORD task1_GameOverMenu ; GameMode_GameOverMenu
ROM7:EB46   .WORD task1_Normal ; GameMode_InDungeonCellar
ROM7:EB48   .WORD task1_Normal ; GameMode_ExitingCellar
ROM7:EB4A   .WORD task1_Normal ; GameMode_InOverworldCellar
ROM7:EB4C   .WORD task1_Normal ; GameMode_ExitingOverworldCellar
ROM7:EB4E   .WORD task1_EndCredits ; GameMode_EndCredits
ROM7:EB50   .WORD task1_CreateSave ; GameMode_CreateSave
ROM7:EB52   .WORD task1_DeleteSave ; GameMode_DeleteSave
ROM7:EB54   .WORD task1_EnteringDoor ; GameMode_EnteringDoor
ROM7:EB56   .WORD task1_JustDied ; GameMode_JustDied
ROM7:EB58   .WORD task1_PickedUpTriforce ; GameMode_PickedUpTriforce
ROM7:EB5A   .WORD task1_FoundZelda ; GameMode_FoundZelda
 
Subroutine task1_Scroll
ROM7:EB62 task1_Scroll:
ROM7:EB62 LDA #5
ROM7:EB63 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB64 JSR task1_Scroll_run_task_state_and_continue
ROM7:EB65 LDA do_ppu_work_after_sprite0_next_frame
ROM7:EB66 BNE locret_1EB75
ROM7:EB67 STA byte_F3
ROM7:EB68 LDA #$F
ROM7:EB69 JSR set_mmc_control_register
 
ROM7:EB75 locret_1EB75:
ROM7:EB75 RTS
 
Subroutine task1_GameOverMenu
ROM7:EB76 task1_GameOverMenu:
 
ROM7:EB76 LDA #5
ROM7:EB77 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB78 JMP task1_GameOverMenu_main
 
Subroutine task1_EnteringDoor
ROM7:EB7E task1_EnteringDoor:
 
ROM7:EB7E LDA #5
ROM7:EB7F JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB80 JMP task1_EnteringDoor_main ; Check if 0x24
 
Subroutine task1_JustDied
ROM7:EB86 task1_JustDied:
 
ROM7:EB86 LDA #5
ROM7:EB87 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB88 JMP task1_JustDied_main
 
Subroutine task1_PickedUpTriforce
ROM7:EB8E task1_PickedUpTriforce:
 
ROM7:EB8E LDA #5
ROM7:EB8F JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB90 JMP task1_PickedUpTriforce_main
 
Subroutine task1_LoadDungeon
ROM7:EB96 task1_LoadDungeon:
ROM7:EB96 JSR clear_ppumask
ROM7:EB97 LDA #6
ROM7:EB98 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EB99 JSR task1_LoadDungeon_main ; Make some changes to map data for 2nd quest.
 
Subroutine increment_game_mode
ROM7:EBA1 increment_game_mode:
ROM7:EBA1 INC game_mode ; set GameMode_MainMenu or GameMode_DelayBeforeCurtainsOpening
 
ROM7:EBA3 clear_game_mode_task_and_state:
ROM7:EBA3 LDA #0
ROM7:EBA4 STA active_game_mode_task ; Set to 0
ROM7:EBA5 STA task_state ; Set to 0
ROM7:EBA6 RTS
 
Subroutine task1_CurtainsOpening
ROM7:EBAA task1_CurtainsOpening:
ROM7:EBAA JSR update_curtain ; This is related to curtains opening and closing.
ROM7:EBAB LDA object_x_12
ROM7:EBAC BNE locret_1EBF8
ROM7:EBAD LDA #$F
ROM7:EBAE JSR set_mmc_control_register
ROM7:EBAF LDA is_in_cellar
ROM7:EBB0 BEQ loc_1EBBD
ROM7:EBB1 JMP loc_1EBF2
 
ROM7:EBBD loc_1EBBD:
ROM7:EBBD JMP loc_1EBEA
 
ROM7:EBC0 task1_FinishScroll:
ROM7:EBC0 LDA is_in_cellar
ROM7:EBC1 BNE loc_1EBF9
ROM7:EBC2 LDA object_tile_offset_whole
ROM7:EBC3 BEQ loc_1EBF2
ROM7:EBC4 CMP #8
ROM7:EBC5 BEQ loc_1EBF2
ROM7:EBC6 CMP #$F8
ROM7:EBC7 BEQ loc_1EBF2
ROM7:EBC8 LDA object_direction
ROM7:EBC9 STA walking_directions
ROM7:EBCA STA var_15
ROM7:EBCB LDX #0
ROM7:EBCC JSR process_movement
ROM7:EBCD JMP update_link_sprite_and_door_clipping ; Update Link's sprite and dungeon door clipping.
 
ROM7:EBE0 music_per_dungeon: .BYTE Music_Overworld
ROM7:EBE1   .BYTE Music_Dungeon
ROM7:EBE2   .BYTE Music_Dungeon
ROM7:EBE3   .BYTE Music_Dungeon
ROM7:EBE4   .BYTE Music_Dungeon
ROM7:EBE5   .BYTE Music_Dungeon
ROM7:EBE6   .BYTE Music_Dungeon
ROM7:EBE7   .BYTE Music_Dungeon
ROM7:EBE8   .BYTE Music_Dungeon
ROM7:EBE9   .BYTE Music_DeathMountain
 
ROM7:EBEA loc_1EBEA:
ROM7:EBEA LDY dungeon_idx
ROM7:EBEB LDA music_per_dungeon,Y
ROM7:EBEC STA play_music ; Play Music_Overworld, Music_Dungeon or Music_DeathMountain
 
ROM7:EBF2 loc_1EBF2:
ROM7:EBF2 JSR increment_game_mode
ROM7:EBF3 STA object_tile_offset_whole
 
ROM7:EBF8 locret_1EBF8:
ROM7:EBF8 RTS
 
ROM7:EBF9 loc_1EBF9:
ROM7:EBF9 LDA dungeon_idx
ROM7:EBFA BNE loc_1EBEA
ROM7:EBFB LDA link_most_recent_overworld_tile_type
ROM7:EBFC CMP #OverworldTiles_CaveOrDungeonEntrance
ROM7:EBFD BNE loc_1EBEA
ROM7:EBFE LDA #5
ROM7:EBFF JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC00 JSR loc_14BB2
ROM7:EC01 LDA frame_counter
ROM7:EC02 AND #3
ROM7:EC03 BNE locret_1EC1A
ROM7:EC04 DEC object_y
ROM7:EC05 LDA object_y
ROM7:EC06 CMP enemy_state_0
ROM7:EC07 BEQ loc_1EBEA
 
ROM7:EC1A locret_1EC1A:
ROM7:EC1A RTS
 
Subroutine task1_Normal
ROM7:EC1B task1_Normal:
 
ROM7:EC1B LDA recorder_lock_timer ; Don't do anything if the recorder lock is active.
ROM7:EC1C BNE locret_1EBF8
ROM7:EC1D LDA paused_lighting_dungeon_room ; This is 1 while the candle palette shift is happening to
  ; light a dungeon room. The game doesn't update until this
  ; is set back to 0.
ROM7:EC1E BEQ skip_update_lighting_room
ROM7:EC1F LDA #4
ROM7:EC20 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC21 JMP update_lighting_room ; Handle the candle palette shift and return without doing any other updates.
 
ROM7:EC22 skip_update_lighting_room: ; Don't change the pause state while the start menu is open.
ROM7:EC22 LDA gameplay_menu_state
ROM7:EC23 BNE finished_handling_pause
ROM7:EC24 LDA paused ; Load to check if we're drinking a potion
ROM7:EC25 CMP #2 ; State 2 is only set while drinking a potion.
ROM7:EC26 BEQ finished_handling_pause_toggle ; Skip if we're paused to drink a potion. This can't be un-paused by the player.
ROM7:EC27 LDA controller_1_pressed ; P1 buttons pressed on this frame
ROM7:EC28 AND #ControllerBits_Select
ROM7:EC29 BEQ finished_handling_pause_toggle ; Skip if select hasn't been pressed
ROM7:EC2A LDA paused ; Toggle pause state
ROM7:EC2B EOR #1
ROM7:EC2C STA paused ; Toggle pause state
ROM7:EC2D BNE finished_handling_pause_toggle ; Branch if paused
ROM7:EC2E LDA #$F
ROM7:EC2F STA pAPU_SV_CSR
 
ROM7:EC30 finished_handling_pause_toggle:
ROM7:EC30 LDA paused
ROM7:EC31 BEQ finished_handling_pause ; Branch if not paused
ROM7:EC32 LDA #5
ROM7:EC33 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC34 JSR disable_greyscale ; If we're paused, turn off greyscale
ROM7:EC35 JMP update_fairy_refill_rupees_and_hud ; Update fairy/triforce health refill, rupee gain/loss and parts of the HUD.
  ; This is called during the Triforce fanfare (probably for health refill).
  ; It's also called from update_start_menu.
 
ROM7:EC36 finished_handling_pause: ; Clear the sprites created by update_object_sprite.
ROM7:EC36 JSR clear_some_oam_sprites
ROM7:EC37 LDA controller_1_cur ; P1 buttons being held
ROM7:EC38 AND #$F
ROM7:EC39 STA walking_directions
ROM7:EC3A LDA gameplay_menu_state
ROM7:EC3B BEQ start_menu_is_closed ; Check if the start menu was just closed
ROM7:EC3C LDA #5
ROM7:EC3D JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC3E JSR disable_greyscale
ROM7:EC3F JMP update_start_menu
 
ROM7:EC40 start_menu_is_closed: ; P1 buttons pressed on this frame
ROM7:EC40 LDA controller_1_pressed
ROM7:EC41 AND #ControllerBits_Start
ROM7:EC42 BEQ start_not_pressed
ROM7:EC43 INC gameplay_menu_state
ROM7:EC44 RTS
 
ROM7:EC45 start_not_pressed:
ROM7:EC45 LDA clock_active
ROM7:EC46 BEQ clock_not_active
ROM7:EC47 LDA invincibility_frames ; Triggers Link's palette shifting while the clock is active.
ROM7:EC48 CLC
ROM7:EC49 ADC #16
ROM7:EC4A STA invincibility_frames ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
 
ROM7:EC4B clock_not_active:
ROM7:EC4B JSR update_link_movement
ROM7:EC4C LDA active_game_mode_task ; Load to check if 1
ROM7:EC4D BNE skip_if_game_mode_task_1 ; If active_game_mode_task != 0
ROM7:EC4E JMP skip_set_ppu_command_index
 
ROM7:EC4F skip_if_game_mode_task_1:
ROM7:EC4F LDA enemy_behavior_seeking_mode
ROM7:EC50 BNE update_link_weapons
ROM7:EC51 LDA object_x ; We're in seek mode 0. Set the monster target position to the player position.
ROM7:EC52 STA enemy_behavior_seek_x ; Set to object_x
ROM7:EC53 LDA object_y
ROM7:EC54 STA enemy_behavior_seek_y ; Set to object_y
 
ROM7:EC55 update_link_weapons: ; Update each of Link's weapons.
ROM7:EC55 LDX #AttackType_Sword
ROM7:EC56 JSR update_sword_or_rod_melee ; Update either the sword or the melee portion of the rod attack.
ROM7:EC57 LDX #AttackType_SwordBeamOrRodBeam ; The beam of either the beam sword or the rod.
ROM7:EC58 JSR check_beam_sword_or_rod
ROM7:EC59 LDX #AttackType_BoomerangOrMeat ; Boomerangs and meat share a slot. Firing the boomerang
  ; while meat is on the ground makes the meat disappear.
ROM7:EC5A JSR update_boomerang_or_meat
ROM7:EC5B LDX #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
ROM7:EC5C JSR update_bomb_or_fire
ROM7:EC5D LDX #AttackType_BombOrFire2
ROM7:EC5E JSR update_bomb_or_fire
ROM7:EC5F LDX #AttackType_ArrowOrMeleeRod ; An arrow in the air, or the melee part of the rod attack.
ROM7:EC60 JSR update_arrow_or_melee_rod
ROM7:EC61 LDA enemy_behavior_seeking_timer
ROM7:EC62 BNE update_object_loop
ROM7:EC63 LDA prng_1
ROM7:EC64 AND #7
ROM7:EC65 STA enemy_behavior_seeking_timer ; Set to a random 0-7 value. This determines how long we'll stay in this state.
ROM7:EC66 LDA enemy_behavior_seeking_mode
ROM7:EC67 EOR #1
ROM7:EC68 STA enemy_behavior_seeking_mode ; Toggle
ROM7:EC69 BEQ update_object_loop ; Branch if we're now in seeking mode 0
ROM7:EC6A LDA enemy_behavior_seek_x ; Load to flip bits
ROM7:EC6B CMP object_x
ROM7:EC6C BNE update_object_loop ; If enemy_seeking_x is different from the player's X position, leave it locked there for this cycle.
  ; This probably happens when update_boomerang_or_meat overrides the seek position.
ROM7:EC6D EOR #$FF
  ; We're in seek mode 1. When we enter this mode, the enemy seek X/Y positions are set to the inverse
  ; of the player's position and left at that value for the whole cycle.
ROM7:EC6E STA enemy_behavior_seek_x ; Flip bits
ROM7:EC6F LDA enemy_behavior_seek_y ; Load to flip bits
ROM7:EC70 EOR #$FF
ROM7:EC71 STA enemy_behavior_seek_y ; Flip bits
 
ROM7:EC72 update_object_loop: ; Update all objects.
ROM7:EC72 LDX processing_object_index
ROM7:EC73 JSR decrease_invincibility_frames ; Reduce the i-frames for object X.
ROM7:EC74 LDA object_type,X
ROM7:EC75 BEQ skip ; Branch if there's no object in this slot
ROM7:EC76 LDA object_type,X
ROM7:EC77 JSR update_monster ; processing_object_index == X when we call this.
ROM7:EC78 LDX processing_object_index
ROM7:EC79 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:EC7A BNE skip ; Skip if this enemy hasn't yet spawned (still stuck
  ; in spawn cloud)
ROM7:EC7B LDA enemy_properties,X ; Load to check EnemyProperties_SkipAutomaticUpdate.
ROM7:EC7C AND #EnemyProperties_SkipAutomaticUpdate
ROM7:EC7D BNE skip ; Branch if EnemyProperties_SkipAutomaticUpdate is set
ROM7:EC7E LDA enemy_properties,X ; Load to check EnemyProperties_SkipAutomaticSpriteUpdate.
ROM7:EC7F AND #EnemyProperties_SkipAutomaticSpriteUpdate
ROM7:EC80 BNE do_check_enemy_hits ; Branch if we're not automatically updating the sprite for this object.
ROM7:EC81 JSR update_object_sprite
 
ROM7:EC82 do_check_enemy_hits:
ROM7:EC82 LDX processing_object_index
ROM7:EC83 JSR check_enemy_hits ; Check if Link hit this enemy, and if this enemy hit Link.
 
ROM7:EC84 skip: ; Decrement to handle the next object
ROM7:EC84 DEC processing_object_index
ROM7:EC85 BNE update_object_loop
ROM7:EC86 LDA #$B
ROM7:EC87 STA processing_object_index ; Reset to 0xB
 
ROM7:EC88 LDA hearts ; Check if we should be playing everyone's favorite low health warning
ROM7:EC89 AND #$F
ROM7:EC8A BNE not_out_of_hearts
ROM7:EC8B LDA play_sound_3 ; Load to add Sound3_LowHealth
ROM7:EC8C ORA #Sound3_LowHealth ; OR'd with other sounds
ROM7:EC8D STA play_sound_3 ; Add Sound3_LowHealth
 
ROM7:EC8E not_out_of_hearts:
ROM7:EC8E LDA dungeon_idx
ROM7:EC8F BEQ start_coast_water_sound ; Skip this if we're on the overworld.
ROM7:EC90 LDA #4
ROM7:EC91 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC92 JSR check_dungeon_shoot_fireball
ROM7:EC93 JSR setup_minimap_triforce_position_if_holding_compass
ROM7:EC94 LDA #5
ROM7:EC95 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC96 JSR dungeon_only_handle_secrets_and_shutters
ROM7:EC97 JSR handle_open_doors_in_dungeon_room ; If open_doors_in_room is set, open all doors in this dungeon room.
ROM7:EC98 JSR dungeon_only_update_door_background ; This isn't fully traced, but seems to handle updating the
  ; background to display opened/closed doors and bomb holes
  ; (not bomb explosions, which are sprites).
ROM7:EC99 LDA #1
ROM7:EC9A JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EC9B JSR update_picking_up_ganon_triforce
ROM7:EC9C JMP skip_water_sound_in_dungeons ; Skip checking the coast sound and Zola when in dungeons.
 
ROM7:EC9D start_coast_water_sound:
ROM7:EC9D LDA game_mode
ROM7:EC9E CMP #GameMode_Normal
ROM7:EC9F BNE not_normal_mode
ROM7:ECA0 LDY map_location ; Check if we should be looping the coast sound.
ROM7:ECA1 LDA dungeon_screen_data_0,Y ; This is copied from dungeon_screen_attr_1Q_1, etc.
ROM7:ECA2 AND #ScreenData_Overworld_0_WaterSound
ROM7:ECA3 ASL A ; Shift from water sound screen data bit 0x04 to Sound2_Coast (0x20)
ROM7:ECA4 ASL A
ROM7:ECA5 ASL A
ROM7:ECA6 JSR add_play_sound_2 ; Play Sound2_Coast
 
ROM7:ECA7 not_normal_mode: ; Still dungeons only. See if we should spawn Zola. This is
ROM7:ECA7 LDA #4 ; done each time it despawns itself (goes back underwater).
ROM7:ECA8 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:ECA9 JSR check_create_zola
 
ROM7:ECAA skip_water_sound_in_dungeons: ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
ROM7:ECAA LDA ppu_command_buffer_bytes_used
ROM7:ECAB BNE skip_set_ppu_command_index
ROM7:ECAC LDA reset_room_palette_idx_to_0x44 ; Check if this is set
ROM7:ECAD BEQ skip_set_ppu_command_index
ROM7:ECAE LDA #0
ROM7:ECAF STA reset_room_palette_idx_to_0x44 ; Set to 0
ROM7:ECB0 LDA #PPUCommandIndices_Unknown_44
ROM7:ECB1 STA current_ppu_command_index ; Set to PPUCommandIndices_Unknown_44.
 
ROM7:ECB2 skip_set_ppu_command_index: ; Update Link holding an item over his head.
ROM7:ECB2 JSR update_hold_up_item
ROM7:ECB3 JSR update_floor_item_sprite
ROM7:ECB4 JSR check_object_collision_0x13 ; Check collision with object 0x13. Is this the fixed room
  ; item?
ROM7:ECB5 JSR check_if_item_selection_is_valid
 
ROM7:ED89 update_fairy_refill_rupees_and_hud: ; Update fairy/triforce health refill, rupee gain/loss and parts of the HUD.
ROM7:ED89 LDA #5 ; This is called during the Triforce fanfare (probably for health refill).
  ; It's also called from update_start_menu.
ROM7:ED8A JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:ED8B JSR handle_potion_fairy_refill
ROM7:ED8C JMP task1_Normal_p1
 
ROM7:ED8D Skipped empty chunk
Subroutine update_link_movement
ROM7:EDA0 update_link_movement:
ROM7:EDA0 LDX #0
ROM7:EDA1 JSR decrease_invincibility_frames ; Decrease invincibility frames for Link.
ROM7:EDA2 LDA walk_state_and_weapon_state ; Load to check WalkState_3_MovementLocked
ROM7:EDA3 AND #$C0
ROM7:EDA4 CMP #WalkState_3_MovementLocked
ROM7:EDA5 BEQ ret ; Skip if locked
ROM7:EDA6 LDA held_by_like_like ; Check if Link is held by a like like.
ROM7:EDA7 BEQ not_held_by_like_like
ROM7:EDA8 LDA walking_directions ; Clear 0xF0 to prevent movement while held by a like like.
ROM7:EDA9 AND #$F0
ROM7:EDAA STA walking_directions
 
ROM7:EDAB not_held_by_like_like:
ROM7:EDAB LDA #5
ROM7:EDAC JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EDAD JSR update_walking_direction ; Check for item use and sword swords (A and B presses)
  ; Update Link's walking direction.
  ; If we're not on a tile, update Link's walking speed.
ROM7:EDAE JSR update_object_movement ; Handle walking. X = 0 for Link, X > 0 for enemies.
 
ROM7:EDC5 update_link_sprite_and_door_clipping: ; Update Link's sprite and dungeon door clipping.
ROM7:EDC5 LDA game_mode
ROM7:EDC6 CMP #GameMode_ExitingCellar ; Exiting a dungeon cellar, or after ExitingOverworldCellar when exiting an overworld cave.
ROM7:EDC7 BEQ ret
ROM7:EDC8 JSR update_link_sprite_and_check_ladder ; This handles a couple things: updating Link's walking sprite
  ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
ROM7:EDC9 LDA dungeon_idx
ROM7:EDCA BEQ in_overworld ; Skip updating clipping when on the overworld, since there
  ; are no doors.
ROM7:EDCB JSR update_clipping_sprites_under_wall ; Update clipping for the current object. This handles cutting
  ; off Link (and wall masters) as he goes under left/right side
  ; doors in dungeons.
 
ROM7:EDCC in_overworld:
ROM7:EDCC LDX #0
 
ROM7:EDD7 snap_to_tile:
ROM7:EDD7 LDA object_tile_offset_whole,X
ROM7:EDD8 BNE ret ; Branch if not on a whole tile
ROM7:EDD9 LDA object_x,X ; The tile offset is 0, so we must be exactly on a tile
  ; on both axes. Snap X and Y to lie on a tile. This may
  ; partially be a sanity check to make sure enemies never end up
  ; off-tile on both axes. This is also called by knockback for
  ; objects other than Link.
ROM7:EDDA AND #$F8
ROM7:EDDB STA object_x,X
ROM7:EDDC LDA object_y,X ; Snap Y to a half tile + 5
ROM7:EDDD AND #$F8
ROM7:EDDE ORA #5
ROM7:EDDF STA object_y,X
 
ROM7:EDE0 ret:
ROM7:EDE0 RTS
 
ROM7:EDEB byte_1EDEB: .BYTE $8D
ROM7:EDEC   .BYTE $91
ROM7:EDED   .BYTE $9C
ROM7:EDEE   .BYTE $AC
ROM7:EDEF   .BYTE $AD
ROM7:EDF0   .BYTE $CC
ROM7:EDF1   .BYTE $D2
ROM7:EDF2   .BYTE $D5
ROM7:EDF3   .BYTE $DF
 
Subroutine set_tile_walking_onto_1
; Set tile_walking_onto for the current object.
ROM7:EDF4 set_tile_walking_onto_1:
ROM7:EDF4 LDY #0
ROM7:EDF5 STY var_15
ROM7:EDF6 BEQ set_tile_walking_onto_3
 
ROM7:EDFA set_tile_walking_onto_2: ; Set tile_walking_onto for the current object.
ROM7:EDFA LDY #$F8 ; The caller sets var_15 to the walking direction.
ROM7:EDFB CPX #0 ; Link can't move past position 0xF8
ROM7:EDFC BEQ is_link
ROM7:EDFD LDY #$F0 ; Enemies can't move past position 0xF0
 
ROM7:EDFE is_link: ; The caller sets var_15 to the direction the current object is walking.
ROM7:EDFE LDA var_15
ROM7:EDFF AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
ROM7:EE00 BEQ set_tile_walking_onto_3 ; Branch if not moving right or down
ROM7:EE01 LDY #8 ; Down
ROM7:EE02 AND #ControllerBits_Dpad_Down
ROM7:EE03 BNE set_tile_walking_onto_3 ; Branch if moving down
ROM7:EE04 LDY #$10 ; Right
 
ROM7:EE10 set_tile_walking_onto_3:
ROM7:EE10 STY var_4
ROM7:EE11 LDA object_y,X ; A = object Y
ROM7:EE12 CLC
ROM7:EE13 ADC #11 ; A += 11
ROM7:EE14 TAY ; Y = A
ROM7:EE15 PHA ; Push A (object Y + 11)
ROM7:EE16 LDA var_15 ; Reload the direction the object is walking
ROM7:EE17 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:EE18 BEQ horizontal ; Branch if not moving up or down
ROM7:EE19 AND #ControllerBits_Dpad_Down
ROM7:EE1A BEQ y_in_bounds ; Branch if not moving down
ROM7:EE1B CPY #$DD ; Up
ROM7:EE1C BCS y_over_0xDD ; Branch if Y >= 0xDD
 
ROM7:EE1D y_in_bounds: ; Pop A
ROM7:EE1D PLA
ROM7:EE1E CLC
ROM7:EE1F ADC var_4
ROM7:EE20 PHA
 
ROM7:EE21 y_over_0xDD:
ROM7:EE21 LDY object_x,X
ROM7:EE22 JMP crossing_boundary
 
ROM7:EE23 horizontal: ; Y = object X
ROM7:EE23 LDY object_x,X
ROM7:EE24 LDA var_15
ROM7:EE25 AND #ControllerBits_Dpad_Right
ROM7:EE26 BEQ not_moving_right ; if !(walking_state & ControllerBits_Dpad_Right)
ROM7:EE27 CPY #$F0
ROM7:EE28 BCS crossing_boundary ; Branch if X position >= 0xF0 (right edge of the screen)
ROM7:EE29 BCC x_in_bounds ; Otherwise, X < 0xF0
 
ROM7:EE2A not_moving_right:
ROM7:EE2A CPY #$10
ROM7:EE2B BCC crossing_boundary ; Branch if X position < 0x10 (left edge of the screen)
 
ROM7:EE2C x_in_bounds: ; A = object X
ROM7:EE2C TYA
ROM7:EE2D CLC
ROM7:EE2E ADC var_4
ROM7:EE2F TAY
 
ROM7:EE30 crossing_boundary: ; A = object X
ROM7:EE30 TYA
ROM7:EE31 AND #$F8
ROM7:EE32 LSR A ; A /= 4
ROM7:EE33 LSR A
ROM7:EE34 TAY
ROM7:EE35 LDA room_tile_ptrs,Y
ROM7:EE36 STA var_0
ROM7:EE37 LDA room_tile_ptrs+1,Y
ROM7:EE38 STA var_1
ROM7:EE39 PLA ; Pop A
ROM7:EE3A SEC
ROM7:EE3B SBC #$40 ; A -= 0x40
ROM7:EE3C LSR A ; A >>= 3
ROM7:EE3D LSR A
ROM7:EE3E LSR A
ROM7:EE3F TAY
ROM7:EE40 LDA (var_0),Y
ROM7:EE41 STA tile_walking_onto,X
ROM7:EE42 LDA var_15
ROM7:EE43 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:EE44 BEQ horizontal_2
ROM7:EE45 TYA
ROM7:EE46 CLC
ROM7:EE47 ADC #$16
ROM7:EE48 TAY
ROM7:EE49 LDA (var_0),Y
ROM7:EE4A CMP tile_walking_onto,X
ROM7:EE4B BCC horizontal_2 ; if A < tile_walking_onto[X]
ROM7:EE4C STA tile_walking_onto,X ; Store if this value is lower than the previous value
 
ROM7:EE4D horizontal_2:
ROM7:EE4D LDA tile_walking_onto,X
ROM7:EE4E LDY dungeon_idx
ROM7:EE4F BNE ret ; Exit if not overworld
ROM7:EE50 LDA tile_walking_onto,X
ROM7:EE51 LDY #9
 
ROM7:EE52 loop:
ROM7:EE52 DEY
ROM7:EE53 BMI skip
ROM7:EE54 CMP byte_1EDEB,Y
ROM7:EE55 BNE loop
ROM7:EE56 LDA #$26
 
ROM7:EE57 skip: ; Store 0x9 or 0x26
ROM7:EE57 STA tile_walking_onto,X
ROM7:EE58 CPX #0
ROM7:EE59 BNE skip_secret_special_case
ROM7:EE5A LDA map_location
ROM7:EE5B CMP #$1F ; This is a special case for the walk-through secret in
  ; the top-right.
ROM7:EE5C BNE skip_secret_special_case
ROM7:EE5D LDA #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:EE5E AND var_15
ROM7:EE5F BEQ skip_secret_special_case ; Only allow moving up and down in this area.
ROM7:EE60 LDA object_x
ROM7:EE61 CMP #$80
ROM7:EE62 BNE skip_secret_special_case
ROM7:EE63 LDA object_y
ROM7:EE64 CMP #$56
ROM7:EE65 BCS skip_secret_special_case
ROM7:EE66 LDA #$26
ROM7:EE67 STA tile_walking_onto ; Store 0x26 when walking through the overworld NE secret (no collision)
 
ROM7:EE68 skip_secret_special_case:
ROM7:EE68 LDA tile_walking_onto,X
 
ROM7:EE69 ret:
ROM7:EE69 RTS
 
Subroutine update_object_knockback
ROM7:EEB8 update_object_knockback:
ROM7:EEB8 LDA object_knockback,X
ROM7:EEB9 ASL A
ROM7:EEBA BCC not_maintaining_tile_alignment
ROM7:EEBB LSR A ; Shift back.
ROM7:EEBC STA object_knockback,X ; Store object_knockback with AltMovementFlags_MaintainTileAlignment unset.
ROM7:EEBD LDY object_direction,X ; AltMovementFlags_MaintainTileAlignment is set.
 
  ; This is set for Link's knockback. Link is always aligned to a tile on either the X or Y axis.
  ; If Link gets knockback on the same axis he's moving this is fine, since he's being moved
  ; on the same axis, but if Link gets knockback on a perpendicular axis, applying
  ; knockback in that direction would push him off-axis on both axes, which isn't allowed.
 
  ; If this would happen, apply knockback in the direction opposite from Link's facing
  ; direction instead of the direction of the attack.
ROM7:EEBE CPY #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM7:EEBF BCC horizontal ; Branch if the object is facing left or right
ROM7:EEC0 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM7:EEC1 BEQ ret ; Branch if the attack direction is left or right
 
ROM7:EEC2 attack_and_facing_direction_are_on_different_axes: ; If we get here, the knockback direction is vertical and the object is facing horizontal, or vice versa.
ROM7:EEC2 LDA object_tile_offset_whole,X
ROM7:EEC3 BEQ ret ; If Link is aligned to a tile then this isn't needed, since he can move on any axis and he'll
  ; still be aligned on the other axis. Return, and we'll come back here next frame with
  ; AltMovementFlags_MaintainTileAlignment unset.
ROM7:EEC4 CPX #0 ; Check if we're Link.
ROM7:EEC5 BNE clear_knockback ; Branch if not Link. Hitting enemies off-axis simply doesn't cause knockback.
ROM7:EEC6 LDA object_direction
ROM7:EEC7 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:EEC8 STA object_knockback ; Store the direction opposite from the Link's direction, so knockback is backwards
  ; relative to the player's facing direction instead of the hit.
  ; This only happens if the attack and Link's facing direction
  ; are at right angles.
 
ROM7:EEC9 ret:
ROM7:EEC9 RTS
 
ROM7:EECA horizontal:
ROM7:EECA AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:EECB BNE attack_and_facing_direction_are_on_different_axes ; Branch if the attack direction is up or down
ROM7:EECC RTS
 
ROM7:EECD not_maintaining_tile_alignment: ; Check if knockback frames have reached 0.
ROM7:EECD LDA knockback_frames,X
ROM7:EECE BNE continue_knockback
 
ROM7:EEE4 clear_knockback: ; Set knockback to 0. This is called by monsters that don't
ROM7:EEE4 LDA #0 ; have knockback after hit.
 
ROM7:EEE6 clear_knockback2: ; Set to 0. A is always 0 when we reach this branch.
ROM7:EEE6 STA object_knockback,X
ROM7:EEE7 STA knockback_frames,X ; Set to 0.
ROM7:EEE8 RTS
 
ROM7:EEE9 continue_knockback:
ROM7:EEE9 LDA #4
ROM7:EEEA STA var_3 ; Set to 4. Knockback is applied four times per frame, like regular movement.
 
ROM7:EEEB knockback_loop:
ROM7:EEEB LDA object_tile_offset_whole,X
ROM7:EEEC BNE not_on_tile ; Branch if we're not on a tile.
ROM7:EEED JSR snap_to_tile
ROM7:EEEE LDA object_knockback,X
ROM7:EEEF AND #$F
ROM7:EEF0 STA var_15
ROM7:EEF1 JSR set_tile_walking_onto_2 ; On exit, A = walking_collision_flags[X]
ROM7:EEF2 CMP screen_first_solid_tile_id
ROM7:EEF3 BCS clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
 
ROM7:EEF4 not_on_tile:
ROM7:EEF4 LDA object_knockback,X
ROM7:EEF5 AND #$F
ROM7:EEF6 JSR check_object_against_screen_bounding_box_both_or_walking_state ; If the current object is out of the bounding box for the
  ; current screen on either axis and is moving in the direction
  ; it's out of bounds (A), clear walking_state to stop it
  ; moving further in that direction.
 
ROM7:EEF7 BEQ clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
ROM7:EEF8 LDA object_type_1
ROM7:EEF9 CMP #ObjectType_HungryGoriya ; Check if this is HungryGoriya or any OldMan
ROM7:EEFA BEQ hungry_goriya_or_old_man
ROM7:EEFB CMP #ObjectType_OldMan_Dungeon_Hint_0 ; DODONGO DISLIKES SMOKE.
ROM7:EEFC BCC not_hungry_goriya_or_old_man
ROM7:EEFD CMP #ObjectType_Octorok_Projectile
ROM7:EEFE BCS not_hungry_goriya_or_old_man
 
ROM7:EEFF hungry_goriya_or_old_man: ; If walking_state is Up and we're Y < 0x0x8E, stop walking.
ROM7:EEFF JSR stop_walking_to_top_half_of_screen ; This is used for old men/hungry goriya that block walking
  ; onto their half of the screen.
ROM7:EF00 LDA var_15
ROM7:EF01 BEQ clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
 
ROM7:EF02 not_hungry_goriya_or_old_man:
ROM7:EF02 LDY #1
ROM7:EF03 LDA object_knockback,X ; +1 for positive movement (right or down)
ROM7:EF04 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Down
ROM7:EF05 BNE not_right_or_down
ROM7:EF06 LDY #$FF ; -1 for negative movement (left or up)
 
ROM7:EF07 not_right_or_down:
ROM7:EF07 STY var_2
ROM7:EF08 DEC knockback_frames,X
ROM7:EF09 LDA object_tile_offset_whole,X
ROM7:EF0A CLC
ROM7:EF0B ADC var_2 ; Add or subtract 1
ROM7:EF0C STA object_tile_offset_whole,X
ROM7:EF0D AND #$F
ROM7:EF0E BEQ set_zero_tile_offset ; If the tile offset is aligned to 16 pixels, set it to 0.
ROM7:EF0F CPX #0
ROM7:EF10 BNE skip_reset_offset_to_0 ; Branch if not Link
ROM7:EF11 AND #7 ; For link, if the tile offset is aligned to 8 pixels, set it to 0.
ROM7:EF12 BNE skip_reset_offset_to_0
 
ROM7:EF13 set_zero_tile_offset:
ROM7:EF13 STA object_tile_offset_whole,X
 
ROM7:EF14 skip_reset_offset_to_0:
ROM7:EF14 LDA object_knockback,X
ROM7:EF15 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM7:EF16 BEQ vertical
ROM7:EF17 LDA object_x,X ; Add var_2 to the X position.
ROM7:EF18 CLC
ROM7:EF19 ADC var_2
ROM7:EF1A STA object_x,X
ROM7:EF1B JMP skip_vertical
 
ROM7:EF1C vertical:
ROM7:EF1C LDA object_y,X
ROM7:EF1D CLC ; Add var_2 to the Y position.
ROM7:EF1E ADC var_2
ROM7:EF1F STA object_y,X
 
ROM7:EF20 skip_vertical:
ROM7:EF20 DEC var_3
ROM7:EF21 BNE knockback_loop
ROM7:EF22 RTS
 
ROM7:EF66 overworld_recorder_locations: .BYTE $42 ; Pond (first quest only)
ROM7:EF67   .BYTE 6
ROM7:EF68   .BYTE $29
ROM7:EF69   .BYTE $2B
ROM7:EF6A   .BYTE $30
ROM7:EF6B   .BYTE $3A
ROM7:EF6C   .BYTE $3C
ROM7:EF6D   .BYTE $58
ROM7:EF6E   .BYTE $60
ROM7:EF6F   .BYTE $6E
ROM7:EF70   .BYTE $72
 
Subroutine use_item_recorder
ROM7:EF71 use_item_recorder:
ROM7:EF71 LDA #Sound1_Recorder
ROM7:EF72 STA play_sound_1 ; Play Sound1_Recorder
ROM7:EF73 LDA #$98
ROM7:EF74 STA recorder_lock_timer ; Set to 0x98 to pause the game during whistle
ROM7:EF75 LDA dungeon_idx
ROM7:EF76 BNE whistled_in_dungeon
ROM7:EF77 LDA game_mode
ROM7:EF78 CMP #GameMode_Normal
ROM7:EF79 BNE ret
ROM7:EF7A LDY current_save_slot
ROM7:EF7B LDA quest_no,Y
ROM7:EF7C PHA ; Push the quest number
ROM7:EF7D LDA map_location
ROM7:EF7E LDY #$A ; Check 10 whistle locations
 
ROM7:EF7F loop: ; Compare to the current map location
ROM7:EF7F CMP overworld_recorder_locations,Y
ROM7:EF80 BEQ found_map_location
ROM7:EF81 DEY
ROM7:EF82 BPL loop
ROM7:EF83 BMI pop_and_call_whistle_whirlwind
 
ROM7:EF84 found_map_location: ; If whistle location >= 1
ROM7:EF84 CPY #0
ROM7:EF85 BNE not_first_whistle_location
ROM7:EF86 PLA ; Whistle location 0. Pop quest number
ROM7:EF87 BNE call_whistle_whirlwind_thunk ; Branch if second quest. Returns from this function.
ROM7:EF88 BEQ first_quest
 
ROM7:EF89 not_first_whistle_location: ; Whistle location >= 1. Pop quest number
ROM7:EF89 PLA
ROM7:EF8A BEQ call_whistle_whirlwind_thunk ; Returns from this function
 
ROM7:EF8B first_quest: ; First quest, whistle location 0. This is a special
ROM7:EF8B LDA recorder_lake_state ; case for the whistle pond.
ROM7:EF8C BNE ret ; Skip if the pond is already open.
ROM7:EF8D LDY #9
 
ROM7:EF8E loop2: ; Loop to find an empty object slot
ROM7:EF8E DEY
ROM7:EF8F BMI ret
ROM7:EF90 LDA object_type_1,Y
ROM7:EF91 BNE loop2
ROM7:EF92 LDA #ObjectType_RecorderPondDaemon
ROM7:EF93 STA object_type_1,Y ; Create a ObjectType_WhistlePondDaemon, which will handle
  ; the pond emptying.
 
ROM7:EF94 ret:
ROM7:EF94 RTS
 
ROM7:EF95 pop_and_call_whistle_whirlwind:
ROM7:EF95 PLA
 
ROM7:EF96 call_whistle_whirlwind_thunk:
ROM7:EF96 LDA #1
ROM7:EF97 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:EF98 JSR recorder_call_whirlwind
ROM7:EF99 LDA #5
ROM7:EF9A JMP set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
 
ROM7:EF9B whistled_in_dungeon: ; Set used_recorder_in_dungeon to 1 if it's not already set.
ROM7:EF9B LDA used_recorder_in_dungeon
ROM7:EF9C BNE skip_walk_update
ROM7:EF9D INC used_recorder_in_dungeon
 
Function chunk for update_object_movement
ROM7:EFCF skip_walk_update:
ROM7:EFCF RTS
 
Subroutine update_object_movement
; Handle walking. X = 0 for Link, X > 0 for enemies.
ROM7:EFD0 update_object_movement:
 
ROM7:EFD0 LDA object_knockback,X ; Load to check if we should apply knockback movement instead of regular movement.
ROM7:EFD1 BEQ no_knockback
ROM7:EFD2 JMP update_object_knockback
 
ROM7:EFD3 no_knockback:
ROM7:EFD3 CPX #0
ROM7:EFD4 BNE skip ; Branch if not Link
ROM7:EFD5 LDA object_tile_offset_whole ; The pixel offset from the tile in the direction Link is walking
ROM7:EFD6 BEQ skip ; If we're not offset from a tile, skip down and just
  ; use walking_directions for movement.
 
  ; If we're offset from a tile, we'll use object_direction
  ; so we keep moving in the same direction.
ROM7:EFD7 LDA walking_directions ; Load the direction the player wants to move.
ROM7:EFD8 BEQ walking_direction_is_zero ; If the player isn't holding a direction, don't move.
ROM7:EFD9 LDA object_direction ; Load the direction the player is actually moving.
ROM7:EFDA BNE have_movement_direction
 
ROM7:EFDB skip:
ROM7:EFDB CPX #0
ROM7:EFDC BEQ skip_clock_check ; Branch if Link (clock/enemy stun doesn't affect Link).
ROM7:EFDD LDA clock_active
ROM7:EFDE ORA enemy_stun,X
ROM7:EFDF BNE skip_walk_update ; Skip movement update if this enemy can't move.
 
ROM7:EFE0 skip_clock_check: ; Get the direction this object is facing.
ROM7:EFE0 LDA walking_directions,X
ROM7:EFE1 BEQ walking_direction_is_zero
ROM7:EFE2 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:EFE3 LDA walking_bits_2,Y ; This seems to just give us the same direction bit we started with.
ROM7:EFE4 BNE have_movement_direction
 
ROM7:EFE5 walking_direction_is_zero: ; Don't move.
ROM7:EFE5 LDA #0
 
ROM7:EFE6 have_movement_direction:
ROM7:EFE6 AND #$F
ROM7:EFE7 STA var_15 ; Set to the object's movement direction.
ROM7:EFE8 LDA #0
ROM7:EFE9 STA var_14 ; Set to 0
ROM7:EFEA CPX #0
ROM7:EFEB BNE not_link
ROM7:EFEC LDA walk_state_and_weapon_state,X ; X is always 0 here.
ROM7:EFED AND #$F0
ROM7:EFEE CMP #WalkState_Unknown2_10
ROM7:EFEF BEQ loc_1F01B
ROM7:EFF0 CMP #WalkState_Unknown2_20
ROM7:EFF1 BNE not_link
 
ROM7:F01B loc_1F01B:
ROM7:F01B STX var_15
 
ROM7:F01C not_link:
ROM7:F01C CPX #0
ROM7:F01D BNE not_link3
ROM7:F01E LDA #1
ROM7:F01F JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F020 JSR check_push_blocks ; Set var_15 to 0 if Link is near any push blocks.
ROM7:F021 LDA object_type_1
ROM7:F022 CMP #ObjectType_HungryGoriya
ROM7:F023 BEQ hungry_goriya_or_old_man
ROM7:F024 CMP #ObjectType_OldMan_Dungeon_Hint_0 ; DODONGO DISLIKES SMOKE.
ROM7:F025 BCC not_hungry_goriya_or_old_man
ROM7:F026 CMP #ObjectType_Octorok_Projectile
ROM7:F027 BCS not_hungry_goriya_or_old_man
 
ROM7:F028 hungry_goriya_or_old_man: ; If walking_state is Up and we're Y < 0x0x8E, stop walking.
ROM7:F028 JSR stop_walking_to_top_half_of_screen ; This is used for old men/hungry goriya that block walking
  ; onto their half of the screen.
 
ROM7:F029 not_hungry_goriya_or_old_man: ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
ROM7:F029 LDA in_dungeon_door
ROM7:F02A BNE is_overworld ; Skip ahead if we're standing in a dungeon door
ROM7:F02B LDA game_mode
ROM7:F02C CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM7:F02D BEQ cellar_finished_stairs_or_exiting_cave
ROM7:F02E CMP #GameMode_InOverworldCellar ; We stay in this state when in stores (overworld) and cellars (dungeons), instead of going to Normal.
  ; The map location doesn't change.
ROM7:F02F BEQ cellar_finished_stairs_or_exiting_cave
ROM7:F030 CMP #GameMode_ExitingOverworldCellar
ROM7:F031 BNE skip_check_for_cellar_exit
 
ROM7:F032 cellar_finished_stairs_or_exiting_cave:
ROM7:F032 LDA #5
ROM7:F033 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F034 JSR check_for_cellar_exit ; This is called in GameMode_InDungeonCellar, GameMode_InOverworldCellar
  ; and GameMode_ExitingOverworldCellar.
 
  ; Check if we're exiting a cellar. This will change game_mode
  ; if a screen transition is triggered.
ROM7:F035 LDA game_mode
ROM7:F036 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM7:F037 BEQ is_overworld ; Skip ahead if we're still in InCellar.
 
ROM7:F038 skip_check_for_cellar_exit:
ROM7:F038 LDA dungeon_idx
ROM7:F039 BEQ is_overworld
ROM7:F03A LDA in_dungeon_door ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
ROM7:F03B BNE is_overworld
 
ROM7:F03C not_link3: ; If the current object is out of the bounding box for the
ROM7:F03C JSR check_object_against_screen_bounding_box_both ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
 
ROM7:F03D is_overworld:
ROM7:F03D CPX #0
ROM7:F03E BNE skip_check_door_entry ; Skip Skip checking for doors if not Link
ROM7:F03F LDA dungeon_idx
ROM7:F040 BEQ skip_check_door_entry ; Skip checking for doors when in the overworld
ROM7:F041 LDA game_mode
ROM7:F042 CMP #GameMode_InDungeonCellar ; If we're in a dungeon cellar.
ROM7:F043 BEQ skip_check_door_entry ; Skip checking for doors when in cellars
ROM7:F044 LDA #5
ROM7:F045 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F046 JSR check_door_entry ; Check entering dungeon doors. This handles locking movement
  ; to doors, and triggering the bomb door and push screen
  ; transitions.
ROM7:F047 LDX #0
 
ROM7:F048 skip_check_door_entry: ; Check if we're moving onto the screen boundary. For Link
ROM7:F048 JSR check_screen_boundary_movement ; this will trigger a screen transition, and for enemies this
  ; will change the enemy's direction.
ROM7:F049 CPX #0
ROM7:F04A BNE process_movement ; Skip check_remove_ladder if we're not Link.
ROM7:F04B LDA #5
ROM7:F04C JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F04D JSR check_remove_ladder ; If we're using the ladder, check if the ladder should be removed.
  ; In X: the object ID of the ladder.
 
ROM7:F08D process_movement: ; Set the tile size: 0x08 (half a tile) for Link, 0x10 (whole
ROM7:F08D LDA #8 ; tile) for enemies. Walking is updated four times per frame,
  ; but once the object reaches the tile size it only updates
  ; the fractional part and stops carrying into the whole part.
 
  ; This seems to be related to collision detection. Once we
  ; reach the tile size, we can't keep walking in this simple
  ; way until we check for collisions. Link checks for collisions
  ; every half tile, enemies check every tile.
ROM7:F08E LDY #$F8 ; Half tile for Link (-8, +8)
ROM7:F08F CPX #0
ROM7:F090 BEQ is_link
ROM7:F091 LDA #$10 ; Whole tile for enemies (-16, +16)
ROM7:F092 LDY #$F0
 
ROM7:F093 is_link:
ROM7:F093 STA current_object_tile_size_pos
ROM7:F094 STY current_object_tile_size_neg
ROM7:F095 LDA var_15 ; Load the movement direction.
ROM7:F096 BEQ locret_1F0C0 ; Skip if we're not moving in any direction.
ROM7:F097 JSR update_walking_repeated ; Process object movement four times per cycle.
ROM7:F098 JSR update_walking_repeated
ROM7:F099 JSR update_walking_repeated
 
Subroutine update_walking_repeated
ROM7:F0AC update_walking_repeated:
ROM7:F0AC LDA var_15
ROM7:F0AD LSR A
ROM7:F0AE BCS walk_positive_x ; if (F & 1): ControllerBits_Dpad_Right
ROM7:F0AF LSR A
ROM7:F0B0 BCS walk_negative_x ; if (F & 2): ControllerBits_Dpad_Left
ROM7:F0B1 LSR A
ROM7:F0B2 BCS walk_positive_y ; if (F & 4): ControllerBits_Dpad_Down
 
ROM7:F0B3 walk_negative_y: ; Otherwise, (F & 8): ControllerBits_Dpad_Up
ROM7:F0B3 JSR walk_negative
ROM7:F0B4 LDA object_y,X ; Apply movement on -Y.
ROM7:F0B5 SBC #0
ROM7:F0B6 STA object_y,X
 
ROM7:F0C0 locret_1F0C0:
ROM7:F0C0 RTS
 
ROM7:F0C1 walk_positive_y: ; Increase the object tile offset for the current object
ROM7:F0C1 JSR walk_positive ; by its walking speed.
 
  ; Return with carry set if the object's X or Y position should be
  ; increased by 1.
ROM7:F0C2 LDA object_y,X ; Apply movement on +Y.
ROM7:F0C3 ADC #0
ROM7:F0C4 STA object_y,X
ROM7:F0C5 RTS
 
ROM7:F0C6 walk_positive_x: ; Increase the object tile offset for the current object
ROM7:F0C6 JSR walk_positive ; by its walking speed.
 
  ; Return with carry set if the object's X or Y position should be
  ; increased by 1.
ROM7:F0C7 LDA object_x,X ; Apply movement on +X.
ROM7:F0C8 ADC #0
ROM7:F0C9 STA object_x,X
ROM7:F0CA RTS
 
ROM7:F0CB walk_negative_x: ; Decrease the object tile offset for the current object
ROM7:F0CB JSR walk_negative ; by its walking speed.
 
  ; Return with carry clear if the object's X or Y position should be
  ; decreased by 1.
ROM7:F0CC LDA object_x,X ; Apply movement on -X.
ROM7:F0CD SBC #0
ROM7:F0CE STA object_x,X
ROM7:F0CF RTS
 
ROM7:F0DF screen_transition_thresholds: .BYTE $3D ; Up
ROM7:F0E0   .BYTE $DD ; Down
ROM7:F0E1   .BYTE 0 ; Left
ROM7:F0E2   .BYTE $F0 ; Right
 
Subroutine check_screen_boundary_movement
; Check if we're moving onto the screen boundary. For Link ; this will trigger a screen transition, and for enemies this ; will change the enemy's direction.
ROM7:F0E3 check_screen_boundary_movement:
ROM7:F0E3 CPX #0 ; Check if we're Link.
ROM7:F0E4 BNE not_link
ROM7:F0E5 LDA in_dungeon_door ; If we're standing in a dungeon door, this is set to the direction we were facing when we entered it.
ROM7:F0E6 BEQ not_in_door
ROM7:F0E7 JMP check_if_walked_onto_screen_boundary ; Call check_walked_to_screen_boundary if we're standing in a dungeon door.
 
ROM7:F0E8 not_in_door:
ROM7:F0E8 LDA var_14
ROM7:F0E9 BMI locret_1F148
 
ROM7:F0EA not_link:
ROM7:F0EA LDA object_tile_offset_whole,X
ROM7:F0EB BNE locret_1F148 ; Stop if we're not standing on a tile.
ROM7:F0EC STA var_14 ; Set to 0
ROM7:F0ED LDA var_15 ; Load the walking direction (or 0 if we're walking into a wall)
ROM7:F0EE BNE set_new_direction
ROM7:F0EF CPX #0 ; The walking direction is 0, which means we're either not
  ; moving at all, or we've walked into the screen boundary.
ROM7:F0F0 BEQ locret_1F148 ; Branch if Link
ROM7:F0F1 LDA enemy_properties,X ; Load to check ReverseDirectionAtWalls
ROM7:F0F2 AND #EnemyProperties_ReverseDirectionAtWalls
ROM7:F0F3 BNE reverse_direction_at_wall
ROM7:F0F4 LDA walking_directions,X ; ReverseDirectionAtWalls isn't set. Restore our
  ; walking_direction into var_15. This undoes the screen
  ; clipping, so it'll be pointing us into the wall.
ROM7:F0F5 STA var_15
ROM7:F0F6 JMP change_enemy_direction_ignoring_flags
 
ROM7:F0F7 reverse_direction_at_wall: ; Flip the current object's object_direction in the opposite
ROM7:F0F7 JSR reverse_direction_2 ; direction. This seems to be the same as reverse_direction 1,
  ; except it starts with object_direction instead of var_15
  ; and also stores the result in var_15.
ROM7:F0F8 JMP check_walked_to_screen_boundary_not_link
 
ROM7:F0F9 set_new_direction: ; Set tile_walking_onto for the current object.
ROM7:F0F9 JSR set_tile_walking_onto_2 ; The caller sets var_15 to the walking direction.
ROM7:F0FA CMP screen_first_solid_tile_id
ROM7:F0FB BCC check_if_walked_onto_screen_boundary ; If this object is walking onto an open tile, see if it's at the
  ; screen boundary.
ROM7:F0FC CPX #0 ; This object is walking onto a solid object.
ROM7:F0FD BEQ link_hit_solid_object
 
ROM7:F122 change_enemy_direction_based_on_flags: ; Load to check ReverseDirectionAtWalls
ROM7:F122 LDA enemy_properties,X
ROM7:F123 AND #EnemyProperties_ReverseDirectionAtWalls
ROM7:F124 BNE reverse_direction_at_wall ; If EnemyProperties_ReverseDirectionAtWalls is set for this
  ; enemy, reverse its direction. Otherwise, fall through
  ; and rotate.
 
ROM7:F125 change_enemy_direction_ignoring_flags:
ROM7:F125 JSR change_direction
ROM7:F126 STA var_15
ROM7:F127 LDA var_14
ROM7:F128 BNE set_new_direction ; Branch to set the new direction. If the new direction
  ; still isn't valid, we'll come back here and try again.
ROM7:F129 RTS
 
ROM7:F12A link_hit_solid_object: ; Link walked into an obstacle.
ROM7:F12A LDA dungeon_idx
ROM7:F12B BNE in_overworld ; Skip checking to spawn Armos/Ghini in dungeons.
ROM7:F12C LDA #1
ROM7:F12D JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F12E JSR handle_spawning_armos_ghini_on_touch
 
ROM7:F12F in_overworld:
ROM7:F12F JSR set_var_15_to_0
ROM7:F130 STA controller_1_pressed ; Set to 0.
ROM7:F131 LDA dungeon_idx
ROM7:F132 BEQ check_if_walked_onto_screen_boundary ; Call check_walked_to_screen_boundary if we're on the overworld.
 
ROM7:F148 locret_1F148:
ROM7:F148 RTS
 
Subroutine set_var_15_to_0
ROM7:F149 set_var_15_to_0:
ROM7:F149 LDA #0
ROM7:F14A STA var_15
ROM7:F14B RTS
 
Subroutine check_if_walked_onto_screen_boundary
ROM7:F14E check_if_walked_onto_screen_boundary:
ROM7:F14E CPX #0
ROM7:F14F BNE check_walked_to_screen_boundary_not_link ; Branch if this isn't Link.
ROM7:F150 LDA game_mode
ROM7:F151 CMP #GameMode_Normal
ROM7:F152 BNE ret
ROM7:F153 LDA ladder_object_id ; Skip if we're using the ladder.
ROM7:F154 BNE locret_1F148
ROM7:F155 LDA object_tile_offset_whole
ROM7:F156 BNE ret
 
ROM7:F161 check_if_walked_onto_screen_boundary_cellar:
ROM7:F161 LDX object_y
ROM7:F162 LDA walking_directions
ROM7:F163 BEQ ret
ROM7:F164 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F165 LDA walking_bits_2,Y
ROM7:F166 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:F167 BNE horizontal
ROM7:F168 LDX object_x ; If we're facing horizontally, read X instead.
 
ROM7:F169 horizontal:
ROM7:F169 STX var_0
ROM7:F16A LDA var_0
ROM7:F16B CMP screen_transition_thresholds,Y ; Check if we're at a screen transition threshold.
ROM7:F16C BNE ret
ROM7:F16D LDA walking_bits_2,Y
ROM7:F16E STA object_direction
 
ROM7:F182 start_GameMode_PrepareScroll:
ROM7:F182 INC game_mode
ROM7:F183 LDA #0 ; Set to GameMode_PrepareScroll.
ROM7:F184 STA task_state ; Set to 0
ROM7:F185 STA active_game_mode_task ; Set to 0
ROM7:F186 STA var_15 ; Set to 0
ROM7:F187 STA walk_state_and_weapon_state ; Set to 0
ROM7:F188 STA object_knockback ; Set to 0
ROM7:F189 STA knockback_frames ; Set to 0
ROM7:F18A STA invincibility_frames ; Set to 0
 
ROM7:F18B ret:
ROM7:F18B LDX #0
ROM7:F18C RTS
 
ROM7:F198 check_walked_to_screen_boundary_not_link: ; If the current object is out of the bounding box for the
ROM7:F198 JSR check_object_against_screen_bounding_box_both ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM7:F199 BEQ change_enemy_direction_based_on_flags ; If this enemy has hit the screen bounding box, change
  ; its direction.
ROM7:F19A STA object_direction,X ; Otherwise, just store its walking direction.
ROM7:F19B RTS
 
Subroutine change_direction
ROM7:F1A0 change_direction:
ROM7:F1A0 LDA var_14
ROM7:F1A1 INC var_14
ROM7:F1A2 JSR call_jump_table
 
ROM7:F1A3   .WORD rotate_90_degrees_randomly ; Randomly rotate the current enemy's movement by 90 degrees left or right.
ROM7:F1A5   .WORD reverse_direction_1 ; Flip the current object's object_direction in the opposite direction.
ROM7:F1A7   .WORD reverse_direction_2 ; Flip the current object's object_direction in the opposite
  ; direction. This seems to be the same as reverse_direction 1,
  ; except it starts with object_direction instead of var_15
  ; and also stores the result in var_15.
ROM7:F1A9   .WORD switch_to_rotate_90_degrees
 
Subroutine rotate_90_degrees_randomly
; Randomly rotate the current enemy's movement by 90 degrees left or right.
ROM7:F1AF rotate_90_degrees_randomly:
ROM7:F1AF LDY #0
ROM7:F1B0 LDA prng_0,X ; 50% Up
ROM7:F1B1 ASL A
ROM7:F1B2 BCS up
ROM7:F1B3 INY ; 50% Down
 
ROM7:F1B4 up:
ROM7:F1B4 LDA object_direction,X
ROM7:F1B5 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:F1B6 BEQ horizontal
ROM7:F1B7 INY ; Increase from Up/Down to Left/Right.
ROM7:F1B8 INY
 
ROM7:F1B9 horizontal:
ROM7:F1B9 LDA walking_bits_2,Y
ROM7:F1BA RTS
 
Subroutine reverse_direction_1
; Flip the current object's object_direction in the opposite direction.
ROM7:F1C3 reverse_direction_1:
ROM7:F1C3 LDA var_15
ROM7:F1C4 PHA
ROM7:F1C5 AND #ControllerBits_Dpad_Left|ControllerBits_Dpad_Up
ROM7:F1C6 BEQ right_or_down
ROM7:F1C7 PLA
ROM7:F1C8 LSR A ; Left becomes Right, Up becomes Down
ROM7:F1C9 RTS
 
ROM7:F1CA right_or_down:
ROM7:F1CA PLA
ROM7:F1CB ASL A ; Right becomes Left, Down becomes Up
ROM7:F1CC RTS
 
Subroutine reverse_direction_2
; Flip the current object's object_direction in the opposite ; direction. This seems to be the same as reverse_direction 1, ; except it starts with object_direction instead of var_15 ; and also stores the result in var_15.
ROM7:F1D0 reverse_direction_2:
ROM7:F1D0 LDA object_direction,X
ROM7:F1D1 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F1D2 STA object_direction,X
ROM7:F1D3 STA var_15
ROM7:F1D4 RTS
 
Subroutine switch_to_rotate_90_degrees
ROM7:F1DA switch_to_rotate_90_degrees:
ROM7:F1DA LDA #0
ROM7:F1DB STA var_14
ROM7:F1DC RTS
 
Subroutine rope_handle_movement_changes
ROM7:F1DF rope_handle_movement_changes:
ROM7:F1DF LDA object_tile_offset_whole,X
ROM7:F1E0 BNE locret_1F1FC ; Branch if we're not on a whole tile
ROM7:F1E1 STA var_14
 
ROM7:F1E2 loop: ; Keep looping until we find a new direction to go
ROM7:F1E2 JSR change_direction
ROM7:F1E3 STA var_15
ROM7:F1E4 BEQ locret_1F1FC
ROM7:F1E5 JSR set_tile_walking_onto_2 ; Set tile_walking_onto for the current object.
  ; The caller sets var_15 to the walking direction.
ROM7:F1E6 CMP screen_first_solid_tile_id
ROM7:F1E7 BCS loop ; If we've hit an obstacle?
ROM7:F1E8 JSR check_object_against_screen_bounding_box_both ; If the current object is out of the bounding box for the
  ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
ROM7:F1E9 BEQ loop
ROM7:F1EA STA object_direction,X
 
ROM7:F1FC locret_1F1FC:
ROM7:F1FC RTS
 
ROM7:F1FD ladder_x_offsets: .BYTE 0
ROM7:F1FE   .BYTE 0
ROM7:F1FF   .BYTE $F0
ROM7:F200   .BYTE $10
ROM7:F201 ladder_y_offsets: .BYTE $FB
ROM7:F202   .BYTE $13
ROM7:F203   .BYTE 3
ROM7:F204   .BYTE 3
ROM7:F205 sprite_replacement_for_big_shield_from: .BYTE 2
ROM7:F206   .BYTE 6
ROM7:F207   .BYTE 8
ROM7:F208   .BYTE $A
ROM7:F209 sprite_replacement_for_big_shield_to: .BYTE $80
ROM7:F20A   .BYTE $54
ROM7:F20B   .BYTE $60
ROM7:F20C   .BYTE $60
ROM7:F20D overworld_ladder_locations: .BYTE $17 ; Screen numbers in the overworld where the ladder can be used (river and coast)
ROM7:F20E   .BYTE $18
ROM7:F20F   .BYTE $19
ROM7:F210   .BYTE $27
ROM7:F211   .BYTE $4F
ROM7:F212   .BYTE $5F
 
Subroutine update_link_sprite_and_check_ladder_in_bank_4
; Call update_link_sprite_and_check_ladder, then set bank 4 before returning.
ROM7:F213 update_link_sprite_and_check_ladder_in_bank_4:
ROM7:F213 JSR update_link_sprite_and_check_ladder ; This handles a couple things: updating Link's walking sprite
  ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
ROM7:F214 LDA #4
ROM7:F215 JMP set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
 
ROM7:F21B update_link_sprite_return_in_bank_1: ; Call reset_animation_frame_update_link_sprite_and_check_ladder,
ROM7:F21B JSR reset_animation_frame_update_link_sprite_and_check_ladder ; then set bank 1 before returning.
 
ROM7:F21C set_bank_1_and_return: ; Set back to bank 1 and return to the caller (since we're
ROM7:F21C LDA #1 ; jumping to set_prg_bank instead of JSR).
ROM7:F21D JMP set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
 
ROM7:F223 update_link_sprite_and_check_ladder_bank_1: ; Call update_link_sprite_and_check_ladder, then set bank 1 before returning.
ROM7:F223 JSR update_link_sprite_and_check_ladder
ROM7:F224 JMP set_bank_1_and_return ; Set back to bank 1 and return to the caller (since we're
  ; jumping to set_prg_bank instead of JSR).
 
Subroutine sub_1F229
ROM7:F229 sub_1F229:
ROM7:F229 JSR reset_animation_frame_update_link_sprite_and_check_ladder ; Like update_link_sprite_and_check_ladder, but reset the animation
  ; timer first.
ROM7:F22A LDA #4
ROM7:F22B JMP set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
 
Subroutine reset_animation_frame_update_link_sprite_and_check_ladder
; Like update_link_sprite_and_check_ladder, but reset the animation ; timer first.
ROM7:F231 reset_animation_frame_update_link_sprite_and_check_ladder:
ROM7:F231 LDA #6
ROM7:F232 STA object_animation_frame_timer ; Set to 0x06.
ROM7:F233 BNE update_link_sprite_and_check_ladder ; Always branch.
 
ROM7:F238 update_link_sprite_and_check_ladder_if_overworld: ; Like update_link_sprite_and_check_ladder, but do nothing if
ROM7:F238 LDA dungeon_idx ; we're in a dungeon.
ROM7:F239 BNE locret_1F1FC ; Skip if we're in a dungeon.
 
ROM7:F23C update_link_sprite_and_check_ladder: ; This handles a couple things: updating Link's walking sprite
ROM7:F23C LDA held_by_recorder_whirlwind ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
ROM7:F23D BNE locret_1F1FC ; Skip if held by the whirlwind
ROM7:F23E TAX ; Set to 0.
ROM7:F23F LDA game_mode
ROM7:F240 CMP #GameMode_PrepareScroll
ROM7:F241 BEQ not_using_ladder_thunk ; Branch if GameMode_PrepareScroll.
ROM7:F242 CMP #GameMode_Normal
ROM7:F243 BCC not_using_ladder_thunk ; Branch if < GameMode_Normal.
ROM7:F244 LDA object_tile_offset_whole
ROM7:F245 BEQ aligned_with_tile ; Jump if Link is aligned with a tile
ROM7:F246 AND #7
ROM7:F247 BEQ on_full_tile ; Branch if the (tile offset & 7) == 0.
 
ROM7:F248 not_using_ladder_thunk:
ROM7:F248 JMP not_using_ladder
 
ROM7:F249 on_full_tile:
ROM7:F249 LDA #0
ROM7:F24A STA object_tile_offset_whole ; Snap the tile offset to 0.
ROM7:F24B LDY game_mode
ROM7:F24C CPY #GameMode_Normal
ROM7:F24D BNE not_using_ladder_thunk ; Branch if not GameMode_Normal.
ROM7:F24E STA is_in_cellar ; Set to 0.
 
ROM7:F24F aligned_with_tile:
ROM7:F24F LDA game_mode
ROM7:F250 CMP #GameMode_Normal
ROM7:F251 BNE not_using_ladder_thunk ; Skip if not in normal mode.
ROM7:F252 LDA dungeon_idx
ROM7:F253 BNE check_ladder ; Branch if in a dungeon
ROM7:F254 LDA map_location ; We're in the overworld. See if this is any screen where
  ; the ladder can be used.
ROM7:F255 LDY #5
 
ROM7:F256 loop:
ROM7:F256 CMP overworld_ladder_locations,Y
ROM7:F257 BEQ check_ladder ; The ladder can be used in this screen.
ROM7:F258 DEY
ROM7:F259 BPL loop
ROM7:F25A BMI not_using_ladder
 
ROM7:F25B check_ladder: ; The ladder is never used when we're in a door.
ROM7:F25B LDA in_dungeon_door
ROM7:F25C BNE not_using_ladder
ROM7:F25D LDA have_ladder ; Check if we have the ladder.
ROM7:F25E BEQ not_using_ladder
ROM7:F25F LDA walk_state_and_weapon_state
ROM7:F260 AND #$C0
ROM7:F261 CMP #$40
ROM7:F262 BEQ not_using_ladder
ROM7:F263 LDA ladder_object_id
ROM7:F264 BNE not_using_ladder
ROM7:F265 LDX #0
ROM7:F266 LDA object_direction
ROM7:F267 STA var_15 ; Set to Link's facing direction.
ROM7:F268 JSR set_tile_walking_onto_2 ; Get the tile type in the direction Link is facing.
ROM7:F269 LDY dungeon_idx
ROM7:F26A BEQ in_overworld
ROM7:F26B CMP #$F4 ; In dungeon, ladder tiles are 0xF4.
ROM7:F26C BEQ is_ladder_tile
ROM7:F26D BNE not_using_ladder
 
ROM7:F26E in_overworld: ; On the overworld, ladder tiles are 0x8D <= tile < 0x99.
ROM7:F26E CMP #$8D
ROM7:F26F BCC not_using_ladder
ROM7:F270 CMP #$99
ROM7:F271 BCS not_using_ladder
 
ROM7:F272 is_ladder_tile: ; Find an object slot to place the ladder.
ROM7:F272 JSR find_last_available_object_idx
ROM7:F273 BEQ not_using_ladder ; Stop if there are no available slots.
ROM7:F274 LDA walking_directions
ROM7:F275 BEQ not_using_ladder ; Stop if Link isn't facing in any direction?
ROM7:F276 LDX tmp_result
ROM7:F277 CMP object_direction
ROM7:F278 BNE not_using_ladder
ROM7:F279 STX ladder_object_id ; Store the object slot of the ladder.
ROM7:F27A STA object_direction,X ; Point the ladder in the same direction as Link.
ROM7:F27B JSR get_opposite_direction_and_index ; Get the direction index for Link's facing direction.
ROM7:F27C LDA object_x ; Offset the ladder on X from link, depending on which direction he's facing.
ROM7:F27D CLC
ROM7:F27E ADC ladder_x_offsets,Y
ROM7:F27F STA object_x,X
ROM7:F280 LDA object_y ; Offset the ladder on Y from link, depending on which direction he's facing.
ROM7:F281 CLC
ROM7:F282 ADC ladder_y_offsets,Y
ROM7:F283 STA object_y,X
ROM7:F284 LDA #ObjectType_Ladder
ROM7:F285 STA object_type,X ; Set to ObjectType_Ladder.
ROM7:F286 JSR clear_knockback ; Set knockback to 0. This is called by monsters that don't
  ; have knockback after hit.
ROM7:F287 STA invincibility_frames,X ; Set to 0 for ladder.
ROM7:F288 LDA #1
ROM7:F289 STA walk_state_and_weapon_state,X ; Set to 1 for ladder.
 
ROM7:F28A not_using_ladder:
ROM7:F28A LDX #0
ROM7:F28B LDA game_mode
ROM7:F28C CMP #GameMode_Normal
ROM7:F28D BNE not_normal_mode
ROM7:F28E LDA tile_walking_onto ; Load to temporarily save the current value.
ROM7:F28F PHA
ROM7:F290 LDA #5
ROM7:F291 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F292 JSR check_if_stepped_onto_entrance ; Check if Link has stepped onto an entrance tile, like an
  ; overworld cave or dungeon entrance or a dungeon cellar
  ; entrance. If he has, update game_mode.
ROM7:F293 LDX #0
ROM7:F294 PLA
ROM7:F295 STA tile_walking_onto ; Restore the value we pushed above.
 
ROM7:F296 not_normal_mode: ; Update the walking animation frame for Link's walking animation.
ROM7:F296 JSR update_walking_frame_for_link
ROM7:F297 LDA game_mode
ROM7:F298 CMP #GameMode_InDungeonCellar ; Skip the increments below if we're in a dungeon, unless
  ; we're in a dungeon cellar.
ROM7:F299 BEQ move_link_down_2px
ROM7:F29A LDA dungeon_idx
ROM7:F29B BNE in_dungeon
 
ROM7:F29C move_link_down_2px: ; Move Link's sprite down by 2 pixels.
ROM7:F29C INC var_1
ROM7:F29D INC var_1
 
ROM7:F29E in_dungeon:
ROM7:F29E LDA walk_state_and_weapon_state
ROM7:F29F AND #$30
ROM7:F2A0 CMP #$10
ROM7:F2A1 BEQ walk_state_0x10_or_0x20
ROM7:F2A2 CMP #$20
ROM7:F2A3 BNE skip_add_4
 
ROM7:F2A4 walk_state_0x10_or_0x20: ; Add 4 to Y.
ROM7:F2A4 TYA
ROM7:F2A5 CLC
ROM7:F2A6 ADC #4
ROM7:F2A7 TAY
 
ROM7:F2A8 skip_add_4:
ROM7:F2A8 TYA
ROM7:F2A9 LDY #ObjectType_None
ROM7:F2AA JSR update_sprite_for_current_object_type_no_increment
ROM7:F2AB LDA have_magic_shield
ROM7:F2AC BNE has_magic_shield
ROM7:F2AD LDA object_direction
ROM7:F2AE CMP #ControllerBits_Dpad_Down
ROM7:F2AF BNE locret_1F36A
ROM7:F2B0 LDX #1
ROM7:F2B1 LDA sprite_oam_data_48,X
ROM7:F2B2 CMP #$B
ROM7:F2B3 BCS locret_1F36A
ROM7:F2B4 PHA
ROM7:F2B5 CLC
ROM7:F2B6 ADC #$50
ROM7:F2B7 JMP replace_sprite ; Replace sprite index
 
ROM7:F2B8 has_magic_shield: ; Handle Link's sprite replacements for the big shield.
ROM7:F2B8 LDX #1
ROM7:F2B9 LDA object_direction ; PPU data index 1 when facing right
ROM7:F2BA LSR A ; Check ControllerBits_Dpad_Right (0x01)
ROM7:F2BB BCC not_facing_right
ROM7:F2BC LDX #5 ; PPU data index when not facing right
 
ROM7:F2BD not_facing_right:
ROM7:F2BD LDY #4
ROM7:F2BE LDA sprite_oam_data_48,X
ROM7:F2BF PHA
 
ROM7:F2C0 loop2:
ROM7:F2C0 DEY
ROM7:F2C1 BMI sprite_not_found
ROM7:F2C2 CMP sprite_replacement_for_big_shield_from,Y
ROM7:F2C3 BNE loop2
ROM7:F2C4 LDA sprite_replacement_for_big_shield_to,Y
 
ROM7:F2C5 replace_sprite: ; Replace sprite index
ROM7:F2C5 STA sprite_oam_data_48,X
 
ROM7:F2C6 sprite_not_found:
ROM7:F2C6 PLA
ROM7:F2C7 CMP #$A
ROM7:F2C8 BNE locret_1F36A
ROM7:F2C9 LDA sprite_oam_data_49,X
ROM7:F2CA AND #$F
ROM7:F2CB STA sprite_oam_data_49,X
 
ROM7:F36A locret_1F36A:
ROM7:F36A RTS
 
ROM7:F36B beam_explosion_oam_attributes: .BYTE OAMAttributes_FlipHorizontally
ROM7:F36C   .BYTE OAMAttributes_FlipHorizontally|OAMAttributes_FlipVertically
ROM7:F36D   .BYTE OAMAttributes_FlipVertically
ROM7:F36E   .BYTE 0
 
Subroutine check_beam_sword_or_rod
ROM7:F36F check_beam_sword_or_rod:
ROM7:F36F LDA walk_state_and_weapon_state,X ; X = 0x0E
ROM7:F370 BEQ locret_1F36A
ROM7:F371 LSR A
ROM7:F372 BCC beam_travelling ; Jump if 0x01 is unset (the projectile is moving).
ROM7:F373 JMP beam_exploding ; 0x01 is set (the projectile hit something and is exploding).
 
ROM7:F374 beam_travelling:
ROM7:F374 LDA object_tile_offset_whole,X
ROM7:F375 BNE empty_jump ; This doesn't seem to do anything.
 
ROM7:F376 empty_jump:
ROM7:F376 LDA object_direction,X
ROM7:F377 JSR update_projectile_movement
ROM7:F378 LDA var_15
ROM7:F379 BEQ loc_1F3D4
ROM7:F37A LDA object_tile_offset_whole,X
ROM7:F37B AND #7
ROM7:F37C BNE update_lynel_sword_or_unknown
ROM7:F37D STA object_tile_offset_whole,X
 
ROM7:F391 update_lynel_sword_or_unknown: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:F391 JSR set_var_0_to_object_position
ROM7:F392 LDA object_direction,X
ROM7:F393 PHA
ROM7:F394 AND #3
ROM7:F395 BEQ loc_1F3A2
ROM7:F396 LDA var_1
ROM7:F397 CLC
ROM7:F398 ADC #3
ROM7:F399 STA var_1
 
ROM7:F3A2 loc_1F3A2:
ROM7:F3A2 PLA
ROM7:F3A3 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F3A4 LDA frame_counter
ROM7:F3A5 AND #3
ROM7:F3A6 ORA sword_oam_attributes,Y
ROM7:F3A7 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:F3A8 LDA vertical_horizontal_sprite_offsets,Y
ROM7:F3A9 STA var_12
ROM7:F3AA CPY #2
ROM7:F3AB BNE loc_1F3BB
ROM7:F3AC INC var_15
 
ROM7:F3BB loc_1F3BB:
ROM7:F3BB LDY #$22
ROM7:F3BC CPX #AttackType_Sword
ROM7:F3BD BCS is_object ; Skip the following check if this is one of Link's projectiles and not an object.
ROM7:F3BE LDA object_type,X ; Check if ObjectType_Lynel_Sword
ROM7:F3BF CMP #ObjectType_Lynel_Sword
ROM7:F3C0 BEQ is_lynel_sword
ROM7:F3C1 BNE not_lynel_sword ; Link's beam sword
 
ROM7:F3C2 is_object:
ROM7:F3C2 LDA walk_state_and_weapon_state,X
ROM7:F3C3 ASL A
ROM7:F3C4 BCC is_lynel_sword
 
ROM7:F3C5 not_lynel_sword:
ROM7:F3C5 LDY #$23
 
ROM7:F3C6 is_lynel_sword:
ROM7:F3C6 JMP after_setting_some_frame_state
 
ROM7:F3D4 loc_1F3D4:
ROM7:F3D4 LDA walk_state_and_weapon_state,X
ROM7:F3D5 ASL A
ROM7:F3D6 BCC loc_1F416
ROM7:F3D7 LDA have_book
ROM7:F3D8 BEQ loc_1F413
ROM7:F3D9 LDA walk_state_and_weapon_state
ROM7:F3DA PHA
ROM7:F3DB LDA candle_used_in_current_room ; Save value
ROM7:F3DC PHA
ROM7:F3DD LDA #0
ROM7:F3DE STA candle_used_in_current_room ; Set to 0
ROM7:F3DF JSR use_item_candle
ROM7:F3E0 PLA
ROM7:F3E1 STA candle_used_in_current_room ; Restore value
ROM7:F3E2 PLA
ROM7:F3E3 STA walk_state_and_weapon_state
ROM7:F3E4 LDA walk_state_and_weapon_state,X
ROM7:F3E5 CMP #$21
ROM7:F3E6 BNE loc_1F411
ROM7:F3E7 INC walk_state_and_weapon_state,X
ROM7:F3E8 LDY #$E
ROM7:F3E9 LDA object_x,Y
ROM7:F3EA STA object_x,X
ROM7:F3EB LDA object_y,Y
ROM7:F3EC STA object_y,X
ROM7:F3ED LDA object_direction,Y
ROM7:F3EE STA object_direction,X
ROM7:F3EF LDA #$4F
ROM7:F3F0 STA enemy_action_timers,X
 
ROM7:F411 loc_1F411:
ROM7:F411 LDX #$E
 
ROM7:F413 loc_1F413: ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM7:F413 JMP clear_weapon_state
 
ROM7:F416 loc_1F416:
ROM7:F416 INC walk_state_and_weapon_state,X
ROM7:F417 LDA #$FE
ROM7:F418 STA object_direction,X
ROM7:F419 RTS
 
ROM7:F41A beam_exploding:
ROM7:F41A LDA object_direction,X
ROM7:F41B STA var_2
ROM7:F41C STA var_3
ROM7:F41D LDA #0
ROM7:F41E STA var_15
ROM7:F41F LDY #3
 
ROM7:F429 loc_1F429:
ROM7:F429 TYA
ROM7:F42A PHA
ROM7:F42B LDA var_2
ROM7:F42C PHA
ROM7:F42D LDA var_3
ROM7:F42E PHA
ROM7:F42F LDA frame_counter
ROM7:F430 AND #3
ROM7:F431 ORA beam_explosion_oam_attributes,Y
ROM7:F432 JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:F433 LDA object_x,X
ROM7:F434 CLC
ROM7:F435 ADC var_2
ROM7:F436 STA var_0
ROM7:F437 CMP object_x,X
ROM7:F438 BCC loc_1F450
ROM7:F439 CMP #$FC
ROM7:F43A BCS loc_1F475
ROM7:F43B SEC
ROM7:F43C SBC object_x,X
ROM7:F43D JMP loc_1F455
 
ROM7:F450 loc_1F450:
ROM7:F450 LDA object_x,X
ROM7:F451 SEC
ROM7:F452 SBC var_0
 
ROM7:F455 loc_1F455:
ROM7:F455 CMP #$20
ROM7:F456 BCS loc_1F475
ROM7:F457 LDA object_y,X
ROM7:F458 CLC
ROM7:F459 ADC var_3
ROM7:F45A STA var_1
ROM7:F45B LDY dungeon_idx
ROM7:F45C BEQ loc_1F46C
ROM7:F45D CMP #$3E
ROM7:F45E BCC loc_1F475
ROM7:F45F CMP #$E8
ROM7:F460 BCS loc_1F475
 
ROM7:F46C loc_1F46C:
ROM7:F46C LDA #2
ROM7:F46D STA var_12
ROM7:F46E LDY #$23
ROM7:F46F JSR after_setting_some_frame_state
 
ROM7:F475 loc_1F475:
ROM7:F475 PLA
ROM7:F476 STA var_3
ROM7:F477 PLA
ROM7:F478 STA var_2
ROM7:F479 PLA
ROM7:F47A PHA
ROM7:F47B TAY
ROM7:F47C CPY #1
ROM7:F47D BNE loc_1F484
ROM7:F47E LDY #3
 
ROM7:F484 loc_1F484:
ROM7:F484 LDA 0,Y
ROM7:F485 EOR #$FF
ROM7:F486 CLC
ROM7:F487 ADC #1
ROM7:F488 STA 0,Y
ROM7:F489 PLA
ROM7:F48A TAY
ROM7:F48B DEY
ROM7:F48C BPL loc_1F429
ROM7:F48D DEC object_direction,X
ROM7:F48E LDA object_direction,X
ROM7:F48F CMP #$E8
ROM7:F490 BNE locret_1F49F
ROM7:F491 JMP loc_1F411
 
ROM7:F49F locret_1F49F:
ROM7:F49F RTS
 
Subroutine update_boomerang_or_meat
ROM7:F4A0 update_boomerang_or_meat:
ROM7:F4A0 LDA walk_state_and_weapon_state,X
ROM7:F4A1 BEQ locret_1F49F ; Stop if not active.
ROM7:F4A2 ASL A
ROM7:F4A3 BCC update_projectile ; Branch if 0x80 was unset
ROM7:F4A4 LDA enemy_action_timers,X ; 0x80 is set, so this is meat. The low 4 bits are a timer loop: we run the npc_action_timer
  ; for this object three times before despawning it.
 
  ; Check if the timer is already active.
ROM7:F4A5 BNE timer_running
ROM7:F4A6 INC walk_state_and_weapon_state,X ; Increment the loop counter.
ROM7:F4A7 LDA walk_state_and_weapon_state,X
ROM7:F4A8 AND #$F ; Read the low 4 bits (bit 7 is always set).
ROM7:F4A9 CMP #3 ; If we've looped the 255-frame action timer three times,
  ; we're done.
ROM7:F4AA BEQ jmp_to_zero_walk_state
ROM7:F4AB LDA #$FF ; Reset the action timer and run it again.
ROM7:F4AC STA enemy_action_timers,X
 
ROM7:F4AD timer_running: ; The first object type on the screen at screen load time. This is only set in dungeons.
ROM7:F4AD LDA first_object_type
ROM7:F4AE CMP #ObjectType_BlueMoblin
ROM7:F4AF BCC wrong_monster_type ; if first_object_type < ObjectType_BlueMoblin
ROM7:F4B0 CMP #ObjectType_RedDarknut
ROM7:F4B1 BCC seek_monsters_towards_meat ; if ObjectType_BlueMoblin <= first_object_type < ObjectType_RedDarknut
  ; (Moblin, Goriya, Octorok)
ROM7:F4B2 CMP #ObjectType_Vire
ROM7:F4B3 BEQ seek_monsters_towards_meat ; if ObjectType_Vire
ROM7:F4B4 CMP #ObjectType_BlueKeese
ROM7:F4B5 BEQ seek_monsters_towards_meat ; if ObjectType_BlueKeese
ROM7:F4B6 CMP #ObjectType_RedKeese
ROM7:F4B7 BNE wrong_monster_type ; if ObjectType_RedKeese
 
ROM7:F4B8 seek_monsters_towards_meat: ; Meat affects Moblin, Goriya, Octorok, Vire and Keese.
ROM7:F4B8 LDA object_x,X ; Instead of seeking towards Link, seek towards the meat.
 
  ; Note that this will disable the second seek mode for all
  ; enemies on the screen, if these enemies are ever mixed
  ; with others.
ROM7:F4B9 STA enemy_behavior_seek_x ; Set to object_x for specific enemies
ROM7:F4BA LDA object_y,X
ROM7:F4BB STA enemy_behavior_seek_y ; Set to object_y for specific enemies
 
ROM7:F4BC wrong_monster_type: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:F4BC JSR set_var_0_to_object_position
ROM7:F4BD LDA #OAMAttributes_Palette_2
ROM7:F4BE LDY #6
ROM7:F4BF JMP sub_10790C
 
ROM7:F4C0 jmp_to_zero_walk_state: ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM7:F4C0 JMP clear_weapon_state
 
ROM7:F4E5 byte_1F4E5: .BYTE 0
ROM7:F4E6   .BYTE 1
ROM7:F4E7   .BYTE 2
ROM7:F4E8   .BYTE 1
ROM7:F4E9   .BYTE 0
ROM7:F4EA   .BYTE 1
ROM7:F4EB   .BYTE 2
ROM7:F4EC   .BYTE 1
ROM7:F4ED   .BYTE 3
ROM7:F4EE byte_1F4EE: .BYTE 0
ROM7:F4EF   .BYTE 0
ROM7:F4F0   .BYTE 0
ROM7:F4F1   .BYTE $40
ROM7:F4F2   .BYTE $40
ROM7:F4F3   .BYTE $C0
ROM7:F4F4   .BYTE $80
ROM7:F4F5   .BYTE $80
ROM7:F4F6   .BYTE 1
ROM7:F4F7 byte_1F4F7: .BYTE 0
ROM7:F4F8   .BYTE $20
ROM7:F4F9   .BYTE $36
ROM7:F4FA   .BYTE $4C
ROM7:F4FB   .BYTE $60
ROM7:F4FC   .BYTE $68
ROM7:F4FD   .BYTE $70
ROM7:F4FE   .BYTE $78
ROM7:F4FF   .BYTE $80
ROM7:F500 byte_1F500: .BYTE $80
ROM7:F501   .BYTE $78
ROM7:F502   .BYTE $70
ROM7:F503   .BYTE $68
ROM7:F504   .BYTE $60
ROM7:F505   .BYTE $4C
ROM7:F506   .BYTE $36
ROM7:F507   .BYTE $20
ROM7:F508   .BYTE 0
ROM7:F509 vertical_horizontal_sprite_offsets: .BYTE 0
ROM7:F50A   .BYTE 0
ROM7:F50B   .BYTE 1
ROM7:F50C   .BYTE 1
ROM7:F50D sword_oam_attributes: .BYTE 0
ROM7:F50E   .BYTE OAMAttributes_FlipVertically
ROM7:F50F   .BYTE 0
ROM7:F510   .BYTE 0
ROM7:F511 byte_1F511: .BYTE $FC
ROM7:F512   .BYTE $FC
ROM7:F513   .BYTE 0
ROM7:F514   .BYTE 0
ROM7:F515 byte_1F515: .BYTE 0
ROM7:F516   .BYTE 0
ROM7:F517   .BYTE 3
ROM7:F518   .BYTE 3
 
Subroutine update_projectile
; Wrong name
ROM7:F519 update_projectile:
ROM7:F519 LDA walk_state_and_weapon_state,X ; (The above says "wrong name", which is an old comment that IDA Pro refuses to let me remove.)
 
  ; Stop if not active.
ROM7:F51A BEQ locret_1F49F
ROM7:F51B LDA #0
ROM7:F51C STA var_0 ; Set to 0
ROM7:F51D LDA walk_state_and_weapon_state,X
ROM7:F51E AND #$F0
ROM7:F51F CMP #$10
ROM7:F520 BEQ state_1
ROM7:F521 JMP check_state_2
 
ROM7:F522 state_1:
ROM7:F522 LDA #0
ROM7:F523 STA var_14 ; Set to 0 for update_projectile_movement
ROM7:F524 LDA object_direction,X
ROM7:F525 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM7:F526 BEQ not_horizontal
ROM7:F527 JSR update_projectile_movement
ROM7:F528 INC var_14 ; Set to 1 for update_projectile_movement
 
ROM7:F529 not_horizontal:
ROM7:F529 LDA var_14
ROM7:F52A ASL A
ROM7:F52B BCS loc_1F575 ; Branch if update_projectile_movement set var_14 to 0x80
ROM7:F52C LDA object_direction,X
ROM7:F52D AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:F52E BEQ not_vertical
ROM7:F52F JSR update_projectile_movement
 
ROM7:F530 not_vertical:
ROM7:F530 LDA var_14
ROM7:F531 ASL A
ROM7:F532 BCS loc_1F575 ; Branch if update_projectile_movement set var_14 to 0x80
ROM7:F533 CPX #AttackType_Sword ; Branch if X is one of Link's weapons (skip the object
  ; type check, since X isn't a valid object ID).
ROM7:F534 BCS is_link_weapon
ROM7:F535 LDA object_type,X ; Check if ObjectType_Moblin_Arrow
ROM7:F536 CMP #ObjectType_Moblin_Arrow
ROM7:F537 BEQ update_arrow ; Branch if ObjectType_Moblin_Arrow.
 
ROM7:F538 is_link_weapon: ; An arrow in the air, or the melee part of the rod attack.
ROM7:F538 CPX #AttackType_ArrowOrMeleeRod
ROM7:F539 BEQ update_arrow ; Branch if AttackType_ArrowOrMeleeRod.
ROM7:F53A LDA object_tile_offset_whole,X
ROM7:F53B BPL loc_1F567
ROM7:F53C EOR #$FF
ROM7:F53D CLC
ROM7:F53E ADC #1
 
ROM7:F567 loc_1F567:
ROM7:F567 CMP enemy_state_11,X
ROM7:F568 BCC loc_1F578
ROM7:F569 LDA #$10
ROM7:F56A STA enemy_state_11,X
ROM7:F56B LDA #$20
ROM7:F56C STA walk_state_and_weapon_state,X
 
ROM7:F575 loc_1F575:
ROM7:F575 JMP loc_1F5E1
 
ROM7:F578 loc_1F578:
ROM7:F578 JMP loc_1F6B8
 
ROM7:F57B update_arrow: ; This is called from each other projectile update.
ROM7:F57B LDA #0
ROM7:F57C STA var_15
ROM7:F57D LDA object_direction,X
ROM7:F57E CMP #ControllerBits_Dpad_Left
ROM7:F57F BNE not_left
ROM7:F580 INC var_15
 
ROM7:F581 not_left: ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F581 JSR get_opposite_direction_and_index
ROM7:F582 LDA vertical_horizontal_sprite_offsets,Y
ROM7:F583 STA var_12
ROM7:F584 LDA sword_oam_attributes,Y
 
ROM7:F592 loc_1F592: ; A = 0 from this branch, or the value loaded above.
ROM7:F592 STA var_4
ROM7:F593 CPX #$D
ROM7:F594 BCS loc_1F5A6
ROM7:F595 LDA object_type,X ; if ObjectType_Moblin_Arrow
 
  ; Setting the projectile sprite direction?
ROM7:F596 CMP #ObjectType_Moblin_Arrow
ROM7:F597 BNE loc_1F5A6
ROM7:F598 LDA var_4
ROM7:F599 CLC
ROM7:F59A ADC #2
ROM7:F59B BNE loc_1F5AD
 
ROM7:F5A6 loc_1F5A6:
ROM7:F5A6 CLC
ROM7:F5A7 ADC have_arrow_type
ROM7:F5A8 SEC
ROM7:F5A9 SBC #1
 
ROM7:F5AD loc_1F5AD:
ROM7:F5AD STA var_4
ROM7:F5AE LDA var_4
ROM7:F5AF STA var_5
ROM7:F5B0 JMP loc_1F714
 
ROM7:F5B1 check_state_2: ; Check if state 2
ROM7:F5B1 CMP #$20
ROM7:F5B2 BNE check_state_3
ROM7:F5B3 LDA #$28 ; State 2.
ROM7:F5B4 STA walk_state_and_weapon_state,X
ROM7:F5B5 DEC object_animation_frame_timer,X
ROM7:F5B6 BNE loc_1F5ED
ROM7:F5B7 LDA #$40
ROM7:F5B8 STA walk_state_and_weapon_state,X
ROM7:F5B9 CPX #$D
ROM7:F5BA BCS loc_1F5D2
ROM7:F5BB LDA object_type,X ; check if ObjectType_Moblin_Arrow
ROM7:F5BC CMP #ObjectType_Moblin_Arrow
ROM7:F5BD BEQ loc_1F5D6
 
ROM7:F5D2 loc_1F5D2:
ROM7:F5D2 CPX #$12
ROM7:F5D3 BNE loc_1F5E1
 
ROM7:F5D6 loc_1F5D6: ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM7:F5D6 JSR clear_weapon_state
ROM7:F5D7 CPX #$D
ROM7:F5D8 BCS locret_1F5E0
ROM7:F5D9 JSR loc_14346
 
ROM7:F5E0 locret_1F5E0:
ROM7:F5E0 RTS
 
ROM7:F5E1 loc_1F5E1:
ROM7:F5E1 LDA #3
ROM7:F5E2 STA object_animation_frame_timer,X
ROM7:F5E3 LDA walk_state_and_weapon_state,X
ROM7:F5E4 CLC
ROM7:F5E5 ADC #$10
ROM7:F5E6 STA walk_state_and_weapon_state,X
 
ROM7:F5ED loc_1F5ED:
ROM7:F5ED CPX #$D
ROM7:F5EE BCS loc_1F5F8
ROM7:F5EF LDA object_type,X ; check if ObjectType_Moblin_Arrow
ROM7:F5F0 CMP #ObjectType_Moblin_Arrow
ROM7:F5F1 BEQ loc_1F5FF
 
ROM7:F5F8 loc_1F5F8:
ROM7:F5F8 CPX #$12
ROM7:F5F9 BEQ loc_1F5FF
ROM7:F5FA JMP loc_1F6D3
 
ROM7:F5FF loc_1F5FF:
ROM7:F5FF LDA #2
ROM7:F600 STA var_12
ROM7:F601 LDA #0
ROM7:F602 STA var_15
ROM7:F603 LDA object_direction,X
ROM7:F604 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F605 LDA #0
ROM7:F606 JMP loc_1F592
 
ROM7:F607 check_state_3: ; Check if state 3.
ROM7:F607 CMP #$30
ROM7:F608 BNE state_4
ROM7:F609 LDA #0 ; State 3.
ROM7:F60A STA object_tile_offset_whole,X
ROM7:F60B LDA #$40
ROM7:F60C STA object_walk_speed,X
ROM7:F60D LDA object_direction,X
ROM7:F60E STA var_15
ROM7:F60F AND #2
ROM7:F610 BEQ loc_1F62D
ROM7:F611 LDA object_x,X
ROM7:F612 CMP #2
ROM7:F613 BCC loc_1F635
 
ROM7:F62D loc_1F62D:
ROM7:F62D JSR process_movement
ROM7:F62E DEC enemy_state_11,X
ROM7:F62F BNE loc_1F63E
 
ROM7:F635 loc_1F635:
ROM7:F635 LDA #$20
ROM7:F636 STA enemy_state_11,X
ROM7:F637 LDA #$40
ROM7:F638 STA walk_state_and_weapon_state,X
 
ROM7:F63E loc_1F63E:
ROM7:F63E JMP loc_1F6B8
 
ROM7:F63F state_4:
ROM7:F63F LDA #0
ROM7:F640 STA object_tile_offset_whole,X
ROM7:F641 CPX #$D
ROM7:F642 BCS loc_1F64D
ROM7:F643 LDA enemy_state_4,X
 
ROM7:F64D loc_1F64D: ; This is related to boomerang updates. It's called while
ROM7:F64D JSR sub_10704A ; the boomerang is returning.
ROM7:F64E LDA var_0
ROM7:F64F CMP #2
ROM7:F650 BNE loc_1F691
ROM7:F651 LDA #0
ROM7:F652 STA enemy_state_11,X
ROM7:F653 CPX #$D
ROM7:F654 BCC loc_1F672
ROM7:F655 LDA walk_state_and_weapon_state
ROM7:F656 ORA #$20
ROM7:F657 STA walk_state_and_weapon_state
ROM7:F658 LDA #1
ROM7:F659 STA object_animation_frame_timer
ROM7:F65A LDY #$F
ROM7:F65B LDA #0
ROM7:F65C STA walk_state_and_weapon_state,Y
ROM7:F65D RTS
 
ROM7:F672 loc_1F672:
ROM7:F672 LDY #$30
ROM7:F673 LDA prng_0,X
ROM7:F674 CMP #$30
ROM7:F675 BCC loc_1F682
ROM7:F676 LDY #$50
ROM7:F677 CMP #$70
ROM7:F678 BCC loc_1F682
ROM7:F679 LDY #$70
 
ROM7:F682 loc_1F682:
ROM7:F682 TYA
ROM7:F683 LDY enemy_state_4,X
ROM7:F684 STA enemy_action_timers,Y
ROM7:F685 LDA #0
ROM7:F686 STA walk_state_and_weapon_state,Y
ROM7:F687 JMP loc_14346
 
ROM7:F691 loc_1F691:
ROM7:F691 LDY #4
ROM7:F692 JSR sub_10706F ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
ROM7:F693 LDA byte_1F4F7,Y
ROM7:F694 JSR sub_1070AB ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
ROM7:F695 LDA var_10
ROM7:F696 STA var_15
ROM7:F697 STA object_direction,X
ROM7:F698 TYA
ROM7:F699 PHA
ROM7:F69A JSR process_movement
ROM7:F69B PLA
ROM7:F69C TAY
ROM7:F69D LDA byte_1F500,Y
ROM7:F69E JSR sub_1070AB ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
ROM7:F69F LDA var_11
ROM7:F6A0 STA var_15
ROM7:F6A1 STA object_direction,X
ROM7:F6A2 JSR process_movement
 
ROM7:F6B8 loc_1F6B8:
ROM7:F6B8 DEC object_animation_frame_timer,X
ROM7:F6B9 BNE loc_1F6D3
ROM7:F6BA LDA #2
ROM7:F6BB STA object_animation_frame_timer,X
ROM7:F6BC INC walk_state_and_weapon_state,X
ROM7:F6BD LDA walk_state_and_weapon_state,X
ROM7:F6BE AND #$77
ROM7:F6BF STA walk_state_and_weapon_state,X
ROM7:F6C0 CPX #$D
ROM7:F6C1 BCC loc_1F6E8
ROM7:F6C2 LDY #Sound2_FireArrow
ROM7:F6C3 JSR check_boomerang_sound ; If boomerang_sound_timer has expired, play the boomerang sound.
 
ROM7:F6D3 loc_1F6D3:
ROM7:F6D3 CPX #$D
ROM7:F6D4 BCS loc_1F6E8
ROM7:F6D5 JSR check_link_hit_by_enemy ; Check if Link was hit by an enemy. X is the enemy we're
  ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
ROM7:F6D6 LDA projectile_hit_link ; This is set to 1 by check_link_hit_by_enemy if a projectile
  ; hits Link even if it's deflected by the shield, so it can
  ; be despawned.
ROM7:F6D7 BEQ loc_1F6E8
ROM7:F6D8 LDA #3
ROM7:F6D9 STA object_animation_frame_timer,X
ROM7:F6DA LDA #$20
ROM7:F6DB STA walk_state_and_weapon_state,X
 
ROM7:F6E8 loc_1F6E8:
ROM7:F6E8 LDA #0
ROM7:F6E9 STA var_0
ROM7:F6EA LDA walk_state_and_weapon_state,X
ROM7:F6EB AND #$F
ROM7:F6EC TAY
ROM7:F6ED LDA #0
ROM7:F6EE STA var_1
ROM7:F6EF LDA byte_1F4E5,Y
ROM7:F6F0 STA var_12
ROM7:F6F1 TYA
ROM7:F6F2 LDA byte_1F4EE,Y
ROM7:F6F3 STA var_4
ROM7:F6F4 LDY #0
ROM7:F6F5 CMP #8
ROM7:F6F6 BEQ loc_1F709
ROM7:F6F7 LDY have_magic_boomerang
 
ROM7:F709 loc_1F709:
ROM7:F709 TYA
ROM7:F70A CLC
ROM7:F70B ADC var_4
ROM7:F70C STA var_4
ROM7:F70D LDY #$1D
ROM7:F70E JMP loc_1F720
 
ROM7:F714 loc_1F714:
ROM7:F714 LDA byte_1F511,Y
ROM7:F715 STA var_0
ROM7:F716 LDA byte_1F515,Y
ROM7:F717 STA var_1
ROM7:F718 LDY #2
 
ROM7:F720 loc_1F720:
ROM7:F720 LDA object_x,X
ROM7:F721 CLC
ROM7:F722 ADC var_0
ROM7:F723 STA var_0
ROM7:F724 LDA object_y,X
ROM7:F725 CLC
ROM7:F726 ADC var_1
ROM7:F727 STA var_1
ROM7:F728 LDA walk_state_and_weapon_state,X
ROM7:F729 AND #$F0
ROM7:F72A CMP #$20
ROM7:F72B BNE loc_1F73B
ROM7:F72C LDA #OAMAttributes_Palette_1
ROM7:F72D JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
 
ROM7:F73B loc_1F73B:
ROM7:F73B JMP after_setting_some_frame_state
 
Subroutine update_arrow_or_melee_rod
ROM7:F73E update_arrow_or_melee_rod:
ROM7:F73E LDA walk_state_and_weapon_state,X ; Check the arrow_or_melee_rod_state weapon state to see
  ; if the rod melee part is active.
ROM7:F73F AND #$F0
ROM7:F740 CMP #$30
ROM7:F741 BCS update_sword_or_rod_melee ; If the rod melee is active, update like a sword.
ROM7:F742 JMP update_projectile ; Otherwise, update the arrow.
 
ROM7:F749 sword_or_melee_x_offsets: .BYTE $FF ; State 0 facing up
ROM7:F74A   .BYTE 1 ; State 0 facing down
ROM7:F74B   .BYTE 0 ; State 0 facing left
ROM7:F74C   .BYTE $F8 ; State 0 facing right
ROM7:F74D   .BYTE $FF ; State 1 facing up
ROM7:F74E   .BYTE 1 ; State 1 facing down
ROM7:F74F   .BYTE $F5 ; State 1 facing left
ROM7:F750   .BYTE $B ; State 1 facing right
ROM7:F751   .BYTE $FF ; State 2 facing up
ROM7:F752   .BYTE 1 ; State 2 facing down
ROM7:F753   .BYTE $F9 ; State 2 facing left
ROM7:F754   .BYTE 7 ; State 2 facing right
ROM7:F755   .BYTE $FF ; State 3 facing up
ROM7:F756   .BYTE 1 ; State 3 facing down
ROM7:F757   .BYTE $FD ; State 3 facing left
ROM7:F758   .BYTE 3 ; State 3 facing right
ROM7:F759 sword_or_melee_y_offsets: .BYTE $F7 ; State 0 facing up
ROM7:F75A   .BYTE $F2 ; State 0 facing down
ROM7:F75B   .BYTE $F5 ; State 0 facing left
ROM7:F75C   .BYTE $F5 ; State 0 facing right
ROM7:F75D   .BYTE $F6 ; State 1 facing up
ROM7:F75E   .BYTE $D ; State 1 facing down
ROM7:F75F   .BYTE 3 ; State 1 facing left
ROM7:F760   .BYTE 3 ; State 1 facing right
ROM7:F761   .BYTE $F7 ; State 2 facing up
ROM7:F762   .BYTE 9 ; State 2 facing down
ROM7:F763   .BYTE 3 ; State 2 facing left
ROM7:F764   .BYTE 3 ; State 2 facing right
ROM7:F765   .BYTE $FF ; State 3 facing up
ROM7:F766   .BYTE 5 ; State 3 facing down
ROM7:F767   .BYTE 3 ; State 3 facing left
ROM7:F768   .BYTE 3 ; State 3 facing right
 
Subroutine update_sword_or_rod_melee
; Update either the sword or the melee portion of the rod attack.
ROM7:F769 update_sword_or_rod_melee:
 
ROM7:F769 LDA walk_state_and_weapon_state,X
ROM7:F76A AND #$F ; Skip if inactive.
ROM7:F76B BEQ ret
ROM7:F76C DEC object_animation_frame_timer,X
ROM7:F76D BNE continue_update ; Skip advancing the weapon state if the weapon timer hasn't elapsed.
ROM7:F76E LDA walk_state_and_weapon_state,X ; Get the animation state of the weapon.
ROM7:F76F AND #$F
ROM7:F770 TAY
ROM7:F771 LDA #8 ; Timer value when weapon state == 1
ROM7:F772 DEY
ROM7:F773 BEQ skip ; Branch if the weapon state was 1.
ROM7:F774 LDA #1 ; Timer value when weapon state >= 2
 
ROM7:F775 skip: ; Set both Link's animation timer and the weapon's to A.
ROM7:F775 STA object_animation_frame_timer
ROM7:F776 STA object_animation_frame_timer,X
ROM7:F777 INC walk_state_and_weapon_state,X ; Increase the weapon's state.
ROM7:F778 LDA walk_state_and_weapon_state,X
ROM7:F779 AND #$F
ROM7:F77A CMP #6
ROM7:F77B BCC continue_update ; Branch if the weapon's state hasn't reached 6.
ROM7:F77C JSR clear_weapon_state ; Otherwise, we're finished. Clear the weapon state.
 
ROM7:F77D ret:
ROM7:F77D RTS
 
ROM7:F77E continue_update:
ROM7:F77E LDA #0
ROM7:F77F STA var_15
ROM7:F780 LDA walk_state_and_weapon_state,X
ROM7:F781 AND #$F
ROM7:F782 TAY
ROM7:F783 LDA #$FC ; The branch below loops one extra time, so this just compensates
  ; for that.
ROM7:F784 CPY #5
ROM7:F785 BEQ ret ; Branch if we're in weapon state 5.
 
ROM7:F786 loop: ; Y is the weapon state.
ROM7:F786 CLC ; Set A = 0xFC + (Y+1)*4, which is actually just Y*4.
ROM7:F787 ADC #4
ROM7:F788 DEY
ROM7:F789 BNE loop
ROM7:F78A STA var_0 ; Store A = weapon state * 4
ROM7:F78B LDA object_direction ; Store Link's direction as the weapon direction.
ROM7:F78C STA object_direction,X
ROM7:F78D JSR get_opposite_direction_and_index ; Get the 0-3 index for Link's direction and put it in Y.
ROM7:F78E TYA
ROM7:F78F CLC
ROM7:F790 ADC var_0 ; Add Link's 0-3 direction.
ROM7:F791 TAY
ROM7:F792 LDA object_x
ROM7:F793 CLC
ROM7:F794 ADC sword_or_melee_x_offsets,Y ; Set the melee object's position based on Link's position,
  ; the attack state and the facing direction.
ROM7:F795 STA object_x,X
ROM7:F796 STA var_0
ROM7:F797 LDA object_y
ROM7:F798 CLC
ROM7:F799 ADC sword_or_melee_y_offsets,Y
ROM7:F79A STA object_y,X
ROM7:F79B STA var_1
ROM7:F79C LDA walk_state_and_weapon_state,X
ROM7:F79D AND #$F
ROM7:F79E TAY
ROM7:F79F LDA #ControllerBits_Dpad_Up
ROM7:F7A0 DEY
ROM7:F7A1 BEQ in_state_1 ; Branch if in state 1
ROM7:F7A2 LDA object_direction,X
 
ROM7:F7A3 in_state_1: ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
ROM7:F7A3 JSR get_opposite_direction_and_index
ROM7:F7A4 LDA vertical_horizontal_sprite_offsets,Y
ROM7:F7A5 STA var_12
ROM7:F7A6 LDA sword_oam_attributes,Y
ROM7:F7A7 CPX #AttackType_Sword
ROM7:F7A8 BEQ is_sword
ROM7:F7A9 ORA #OAMAttributes_Palette_1
ROM7:F7AA JMP not_sword
 
ROM7:F7AB is_sword: ; Adjust the sword sprite to the sword the player has
ROM7:F7AB CLC
ROM7:F7AC ADC sword_type
ROM7:F7AD SEC
ROM7:F7AE SBC #1
 
ROM7:F7AF not_sword: ; Store A in var_4 and var_5.
ROM7:F7AF JSR store_A_in_tile_attributes
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:F7B0 CPY #2 ; Y was decremented from the weapon state above, so this is
  ; testing against state 3 rather than 2.
ROM7:F7B1 BNE not_in_state_3
ROM7:F7B2 INC var_15
 
ROM7:F7B3 not_in_state_3:
ROM7:F7B3 LDA walk_state_and_weapon_state,X
ROM7:F7B4 AND #$F
ROM7:F7B5 CMP #1
ROM7:F7B6 BEQ ret2
ROM7:F7B7 LDY #0
ROM7:F7B8 CPX #AttackType_Sword
ROM7:F7B9 BEQ is_sword2
ROM7:F7BA LDY #8
 
ROM7:F7BB is_sword2:
ROM7:F7BB JSR after_setting_some_frame_state
ROM7:F7BC LDA walk_state_and_weapon_state,X
ROM7:F7BD AND #$F
ROM7:F7BE CMP #3
ROM7:F7BF BNE ret2
ROM7:F7C0 CPX #AttackType_ArrowOrMeleeRod ; See if it's the sword or the rod melee that we're updating.
ROM7:F7C1 BNE update_sword
ROM7:F7C2 LDX #AttackType_SwordBeamOrRodBeam ; We're updating the rod melee.
ROM7:F7C3 LDA walk_state_and_weapon_state,X ; Check if 0x80 is set on sword_rod_beam_state. This indicates
  ; that we've already started the rod beam and can stop.
ROM7:F7C4 BEQ beam_not_already_firing
ROM7:F7C5 ASL A
ROM7:F7C6 BCS ret2 ; Branch if the beam has already been started.
 
ROM7:F7C7 beam_not_already_firing:
ROM7:F7C7 LDA #Sound3_WizzrobeBeam
ROM7:F7C8 STA play_sound_3 ; Play Sound3_WizzrobeBeam when the player fires the rod
ROM7:F7C9 LDA #BeamSwordOrRodState_Type_Rod ; Set to 0x80 to activate the rod beam.
 
ROM7:F7CA setup_beam_sword: ; update_sword_or_rod_melee branches here to continue setting
ROM7:F7CA STA walk_state_and_weapon_state,X ; up the beam sword, which is similar to the rod beam. In
  ; that case, A = 0x10.
ROM7:F7CB LDA #$10
ROM7:F7CC JSR loc_10711F
ROM7:F7CD LDA object_direction,X
ROM7:F7CE AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
ROM7:F7CF BEQ vertical
ROM7:F7D0 LDA object_x,X ; Check if the X position is too far out. This can't happen
  ; for Link since we can't fire in the first place. Is this
  ; check for Wizzrobes?
ROM7:F7D1 CMP #20
ROM7:F7D2 BCC clear_weapon_state ; X < 20
ROM7:F7D3 CMP #236
ROM7:F7D4 BCS clear_weapon_state ; X >= 236
 
ROM7:F7D5 vertical: ; Projectile speed if bit 0x80 isn't set in the weapon state
ROM7:F7D5 LDY #$C0
ROM7:F7D6 LDA walk_state_and_weapon_state,X
ROM7:F7D7 ASL A
ROM7:F7D8 BCC skip_set_lower_projectile_speed
ROM7:F7D9 LDY #$A0 ; Projectile speed if bit 0x80 is set in the weapon state
 
ROM7:F7DA skip_set_lower_projectile_speed:
ROM7:F7DA TYA
ROM7:F7DB STA object_walk_speed,X ; Set the projectile's speed
ROM7:F7DC LDA object_tile_offset_whole ; Set the projectile's tile offset to match Link's
ROM7:F7DD STA object_tile_offset_whole,X
 
ROM7:F7DE ret2:
ROM7:F7DE RTS
 
Subroutine clear_weapon_state
; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM7:F855 clear_weapon_state:
ROM7:F855 LDA #0
ROM7:F856 STA walk_state_and_weapon_state,X ; Set to 0
ROM7:F857 RTS
 
Function chunk for update_sword_or_rod_melee
ROM7:F858 update_sword: ; The beam of either the beam sword or the rod.
ROM7:F858 LDX #AttackType_SwordBeamOrRodBeam
ROM7:F859 LDA walk_state_and_weapon_state,X
ROM7:F85A BNE ret2
ROM7:F85B LDA force_beam_sword ; If this is set, skip the health check and always fire the
  ; beam. I'm not sure where this is used.
ROM7:F85C BNE fire_beam_sword
ROM7:F85D LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
ROM7:F85E PHA ; Push hearts
ROM7:F85F AND #$F ; Mask out current hearts
ROM7:F860 STA var_0
ROM7:F861 PLA ; Restore hearts
ROM7:F862 LSR A ; Shift out max hearts
ROM7:F863 LSR A
ROM7:F864 LSR A
ROM7:F865 LSR A
ROM7:F866 CMP var_0 ; Check if current hearts == max hearts
ROM7:F867 BNE ret2 ; Stop if we don't have full health.
ROM7:F868 LDA partial_heart ; Check if we've lost a partial heart.
ROM7:F869 CMP #BeamSwordOrRodState_Type_Rod
ROM7:F86A BCC ret2 ; Stop if we don't have full health.
 
ROM7:F86B fire_beam_sword: ; We have full health, so fire the beam sword.
ROM7:F86B LDA #Sound0_BeamSword
ROM7:F86C JSR add_mask_to_play_sound_0 ; Play the beam sword sound.
ROM7:F86D LDA #BeamSwordOrRodState_Type_Sword_Beam ; The new value for sword_rod_beam_state for the beam sword being
  ; in the air.
ROM7:F86E BNE setup_beam_sword ; Always branch. The rest of the beam update is shared with
  ; the rod beam.
 
Subroutine update_candle_fire
ROM7:F886 update_candle_fire:
ROM7:F886 LDA walk_state_and_weapon_state,X
ROM7:F887 CMP #BombOrFireState_Fire_Moving|BombOrFireState_Type_Fire
ROM7:F888 BNE stationary_fire
ROM7:F889 LDA object_tile_offset_whole,X
ROM7:F88A PHA ; Push the tile offset
ROM7:F88B LDA #0
ROM7:F88C STA object_tile_offset_whole,X
ROM7:F88D LDA object_direction,X
ROM7:F88E STA var_15
ROM7:F88F JSR process_movement ; Move the fire
ROM7:F890 PLA ; Restore the tile offset
ROM7:F891 CLC
ROM7:F892 ADC object_tile_offset_whole,X
ROM7:F893 STA object_tile_offset_whole,X
ROM7:F894 JSR absolute_value ; A = abs(A)
ROM7:F895 CMP #16
ROM7:F896 BNE update_fire_sprite ; The fire keeps moving for 16 pixels.
ROM7:F897 LDA #$3F
ROM7:F898 STA enemy_action_timers,X
ROM7:F899 INC walk_state_and_weapon_state,X ; Advance to stationary.
 
ROM7:F89A stationary_fire:
ROM7:F89A LDA enemy_action_timers,X
ROM7:F89B BEQ clear_weapon_state ; Set walk_state_and_weapon_state[X] = 0 and A = 0
ROM7:F89C LDA dungeon_idx
ROM7:F89D BEQ update_fire_sprite ; Branch if we're on the overworld.
ROM7:F89E TXA ; Save X.
ROM7:F89F PHA
ROM7:F8A0 LDA #4
ROM7:F8A1 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F8A2 JSR update_lighting_room
ROM7:F8A3 PLA ; Restore X.
ROM7:F8A4 TAX
 
ROM7:F8A5 update_fire_sprite: ; Update the sprite of the fire.
ROM7:F8A5 LDA #4
ROM7:F8A6 JSR update_object_animation_frame
ROM7:F8A7 JSR store_animation_frame
ROM7:F8A8 JSR store_palette_2_in_tile_attributes ; Store 0x2 in var_4 and var_5, and set A to 2.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:F8A9 LDA #0
ROM7:F8AA STA var_12 ; Set to 0, so update_sprite_for_current_object_type is in horizontal mode.
ROM7:F8AB LDY #ObjectType_Flame_Unkillable ; Set the object type for update_sprite_for_current_object_type.
ROM7:F8AC JSR update_sprite_for_current_object_type ; Like update_object_sprite, but the object type is already
  ; set in Y and var_12 is already set to 0 (horizontal) or
  ; 1 (vertical).
ROM7:F8AD LDA invincibility_frames ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM7:F8AE BNE locret_1F91D
ROM7:F8AF STX var_0 ; Set var_0 to the object ID of the fire.
ROM7:F8B0 LDX #0 ; var_3 = object_x + 8
  ; var_4 = object_y + 8
ROM7:F8B1 LDY #2
ROM7:F8B2 JSR sub_1F90D ; var_2[Y] = object_x[X] + 8
  ; var_3[Y] = object_y[X] + 8
ROM7:F8B3 LDX var_0 ; var_2 = fire X + 8
  ; var_3 = fire Y + 8
ROM7:F8B4 LDY #0
ROM7:F8B5 JSR sub_1F90D ; var_2[Y] = object_x[X] + 8
  ; var_3[Y] = object_y[X] + 8
ROM7:F8B6 LDY var_0
ROM7:F8B7 LDX #0
ROM7:F8B8 LDA #14 ; Hitbox size: 14
ROM7:F8B9 JSR check_hitbox ; Check if the fire hit Link.
ROM7:F8BA BEQ locret_1F91D ; Stop if the fire didn't hit Link.
ROM7:F8BB LDX var_0 ; Restore the fire's object ID.
ROM7:F8BC LDY #0
ROM7:F8BD STY var_0 ; var_0 = 0
ROM7:F8BE JSR apply_knockback ; Apply knockback after a hit.
 
  ; X is the object ID of the enemy. This is either the enemy being hit, or the enemy hitting Link.
  ; Y = 0 if we're applying knockback to Link being hit by an enemy.
  ; Y is an AttackType if we're applying knockback to the enemy ID in X being hit by one of Link's weapons.
 
  ; var_9 is the current DamageType.
 
ROM7:F8BF LDA #0
ROM7:F8C0 STA var_13 ; Set to 0.
ROM7:F8C1 LDA #$80
ROM7:F8C2 STA var_14 ; Set to 0x80.
ROM7:F8C3 JMP apply_damage_from_own_fire
 
Subroutine sub_1F90D
; var_2[Y] = object_x[X] + 8 ; var_3[Y] = object_y[X] + 8
ROM7:F90D sub_1F90D:
ROM7:F90D LDA object_x,X
ROM7:F90E CLC
ROM7:F90F ADC #8
ROM7:F910 STA var_2,Y
ROM7:F911 LDA object_y,X
ROM7:F912 CLC
ROM7:F913 ADC #8
ROM7:F914 STA var_3,Y
 
ROM7:F91D locret_1F91D:
ROM7:F91D RTS
 
ROM7:F91E   .BYTE $30 ; The delay between each bomb frame.
ROM7:F91F   .BYTE $18
ROM7:F920   .BYTE $C
ROM7:F921   .BYTE 6
ROM7:F922 bombable_dungeon_positions_x: .BYTE $78
ROM7:F923   .BYTE $78
ROM7:F924   .BYTE $20
ROM7:F925   .BYTE $D0
ROM7:F926 bombable_dungeon_positions_y: .BYTE $5D
ROM7:F927   .BYTE $BD
ROM7:F928   .BYTE $8D
ROM7:F929   .BYTE $8D
 
Subroutine update_bomb_or_fire
ROM7:F92A update_bomb_or_fire:
 
ROM7:F92A LDA walk_state_and_weapon_state,X
ROM7:F92B BEQ ret
ROM7:F92C AND #$F0
ROM7:F92D CMP #BombOrFireState_Type_Bomb
ROM7:F92E BEQ is_bomb
ROM7:F92F JMP update_candle_fire
 
ROM7:F930 is_bomb: ; Stop if it's not time to advance the bomb animation.
ROM7:F930 LDA enemy_action_timers,X
ROM7:F931 BNE not_bombable
ROM7:F932 LDA walk_state_and_weapon_state,X
ROM7:F933 AND #$F ; Mask out the bomb state.
ROM7:F934 TAY
ROM7:F935 LDA locret_1F91D,Y ; Get the delay to the next bomb frame and set the timer
  ; to the next frame.
ROM7:F936 STA enemy_action_timers,X
ROM7:F937 INC walk_state_and_weapon_state,X ; Increase the bomb frame.
ROM7:F938 LDA walk_state_and_weapon_state,X
ROM7:F939 AND #$F
ROM7:F93A PHA ; Save state & 0xF
ROM7:F93B CMP #3 ; Play the bomb explosion sound in state 3.
ROM7:F93C BNE skip_explosion
ROM7:F93D LDA #Sound2_BombExplosion
ROM7:F93E JSR add_play_sound_2 ; Play Sound2_BombExplosion
 
ROM7:F93F skip_explosion: ; Restore state & 0xF
ROM7:F93F PLA
ROM7:F940 CMP #5 ; Branch if we're not in state 5.
ROM7:F941 BNE not_state_5
ROM7:F942 JSR clear_weapon_state ; In state 5, remove the bomb.
ROM7:F943 STA enemy_action_timers,X ; Set to 0
 
ROM7:F944 ret:
ROM7:F944 RTS
 
ROM7:F945 not_state_5:
ROM7:F945 CMP #4
ROM7:F946 BNE not_bombable
ROM7:F947 LDA dungeon_idx ; We're in bomb state 4.
ROM7:F948 BEQ not_bombable ; Skip on the overworld.
ROM7:F949 LDA game_mode
ROM7:F94A CMP #GameMode_InDungeonCellar ; Skip in dungeon cellars.
ROM7:F94B BEQ not_bombable
ROM7:F94C LDY #4 ; Loop Y = 3 through 0
 
ROM7:F94D check_bombable_dungeon_positions: ; See if the bomb is close enough to the door bomb region.
ROM7:F94D DEY
ROM7:F94E BMI not_bombable
ROM7:F94F LDA bombable_dungeon_positions_x,Y
ROM7:F950 SEC
ROM7:F951 SBC object_x,X
ROM7:F952 JSR absolute_value ; A = abs(A)
ROM7:F953 CMP #24
ROM7:F954 BCS check_bombable_dungeon_positions ; Move to next if we're too far away on X
ROM7:F955 LDA bombable_dungeon_positions_y,Y
ROM7:F956 SEC
ROM7:F957 SBC object_y,X
ROM7:F958 JSR absolute_value ; A = abs(A)
ROM7:F959 CMP #24
ROM7:F95A BCS check_bombable_dungeon_positions ; Move to next if we're too far away on Y
ROM7:F95B LDA walking_bits_2,Y ; The bomb is close enough to this bomb position.
ROM7:F95C STA var_2 ; Store the direction bit for the direction we found.
  ; This is used by get_dungeon_door_type.
ROM7:F95D AND unlocked_door_directions ; This is a direction mask of the locked and bomb doors
  ; that are open in the current room. This doesn't include
  ; regular doors that don't close.
ROM7:F95E BNE not_bombable
ROM7:F95F LDA byte_54 ; Load to skip if already set
ROM7:F960 BNE not_bombable
ROM7:F961 LDA #5
ROM7:F962 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:F963 JSR get_dungeon_door_type ; See if this is a bombable wall.
ROM7:F964 CMP #DungeonDoor_BombWall
ROM7:F965 BNE not_bombable
ROM7:F966 LDA #6
ROM7:F967 STA byte_54 ; Set to 6
ROM7:F968 LDA var_2
ROM7:F969 STA bombing_or_unlocking_door_direction
 
ROM7:F96A not_bombable: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:F96A JSR set_var_0_to_object_position
ROM7:F96B JSR handle_bomb_greyscale_flash_thunk
ROM7:F96C LDA walk_state_and_weapon_state,X
ROM7:F96D AND #$F
ROM7:F96E CMP #2
ROM7:F96F BEQ ret
ROM7:F970 JMP update_bomb_cloud ; Handle updating the flickering bomb cloud.
 
Subroutine handle_bomb_greyscale_flash_thunk
ROM7:F9BF handle_bomb_greyscale_flash_thunk:
ROM7:F9BF JSR handle_bomb_greyscale_flash ; Handle the screen flashing to greyscale during bomb explosions.
 
Subroutine update_bomb_cloud_sprite
ROM7:F9C2 update_bomb_cloud_sprite:
ROM7:F9C2 LDA walk_state_and_weapon_state,X
ROM7:F9C3 AND #$F
ROM7:F9C4 SEC
ROM7:F9C5 SBC #2
 
ROM7:F9C9 update_spawn_cloud_sprite:
ROM7:F9C9 STA var_12
ROM7:F9CA LDY #0
ROM7:F9CB STY var_15
ROM7:F9CC INY
ROM7:F9CD STY var_4
ROM7:F9CE STY var_5
ROM7:F9CF LDY #1
ROM7:F9D0 JMP after_setting_some_frame_state
 
ROM7:F9D9 bomb_cloud_offsets_1: .BYTE $F3
ROM7:F9DA   .BYTE 0
ROM7:F9DB   .BYTE $E
ROM7:F9DC bomb_cloud_offsets_2: .BYTE $F9
ROM7:F9DD   .BYTE $E
ROM7:F9DE   .BYTE 7
ROM7:F9DF   .BYTE $F3
ROM7:F9E0   .BYTE 0
ROM7:F9E1   .BYTE $E
ROM7:F9E2   .BYTE 7
ROM7:F9E3   .BYTE $F3
ROM7:F9E4   .BYTE $F9
 
Function chunk for update_bomb_or_fire
ROM7:F9E5 update_bomb_cloud: ; Loop for Y = 2 and 1.
ROM7:F9E5 LDY #2
 
ROM7:F9E6 loop: ; Save Y.
ROM7:F9E6 TYA
ROM7:F9E7 PHA
ROM7:F9E8 LDA frame_counter
ROM7:F9E9 LSR A
ROM7:F9EA BCC even_frame
ROM7:F9EB TYA
ROM7:F9EC CLC
ROM7:F9ED ADC #6
ROM7:F9EE TAY
 
ROM7:F9EF even_frame:
ROM7:F9EF LDA object_y,X
ROM7:F9F0 CLC
ROM7:F9F1 ADC bomb_cloud_offsets_1,Y
ROM7:F9F2 STA var_1
ROM7:F9F3 LDA object_x,X
ROM7:F9F4 CLC
ROM7:F9F5 ADC bomb_cloud_offsets_2,Y
ROM7:F9F6 STA var_0
ROM7:F9F7 JSR update_bomb_cloud_sprite
ROM7:F9F8 PLA ; Restore Y.
ROM7:F9F9 TAY
ROM7:F9FA DEY
ROM7:F9FB BPL loop
ROM7:F9FC RTS
 
Subroutine update_spawn_cloud
; This is related to the enemy spawn cloud.
ROM7:FA0C update_spawn_cloud:
ROM7:FA0C JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:FA0D LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:FA0E CMP #$10
ROM7:FA0F BCS loc_1FA27 ; enemy_spawn_state >= 0x10
ROM7:FA10 AND #$F
ROM7:FA11 JSR update_spawn_cloud_sprite
 
ROM7:FA1B loc_1FA1B:
ROM7:FA1B LDA enemy_action_timers,X
ROM7:FA1C BNE ret
 
ROM7:FA1D increase_enemy_spawn_state:
ROM7:FA1D LDA #6
ROM7:FA1E STA enemy_action_timers,X
ROM7:FA1F INC enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
 
ROM7:FA20 ret:
ROM7:FA20 RTS
 
ROM7:FA27 loc_1FA27:
ROM7:FA27 AND #$F
ROM7:FA28 BEQ increase_enemy_spawn_state
ROM7:FA29 AND #1
ROM7:FA2A STA var_12
ROM7:FA2B LDA #OAMAttributes_Palette_1
ROM7:FA2C JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
ROM7:FA2D LDY #$24
ROM7:FA2E JSR after_setting_some_frame_state
ROM7:FA2F JMP loc_1FA1B
 
Subroutine update_walking_frame_for_link
; Update the walking animation frame for Link's walking animation.
ROM7:FA3C update_walking_frame_for_link:
ROM7:FA3C LDA walk_state_and_weapon_state
ROM7:FA3D BNE update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
ROM7:FA3E LDA game_mode ; If we're in FinishScroll or EnteringStairs, run Link's walking animation even though we're
  ; not walking.
ROM7:FA3F CMP #GameMode_FinishScroll
ROM7:FA40 BEQ update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
ROM7:FA41 CMP #GameMode_EnteringDoor
ROM7:FA42 BEQ update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
ROM7:FA43 LDA walking_directions ; Skip this when not walking, except when in these states.
ROM7:FA44 BEQ skip_toggle_animation_frame
 
ROM7:FA4F update_walking_frame_for_object: ; Update the walking animation frame for objects that cycle every 6 frames.
ROM7:FA4F DEC object_animation_frame_timer,X
ROM7:FA50 BNE skip_toggle_animation_frame ; Wait until the animation timer expires.
ROM7:FA51 CPX #0
ROM7:FA52 BNE not_link ; Only call adjust_walk_state for Link.
ROM7:FA53 JSR adjust_walk_state
 
ROM7:FA54 not_link: ; When the animation timer expires, set it back to 6 and
ROM7:FA54 LDA #6 ; toggle the animation frame.
ROM7:FA55 STA var_0
ROM7:FA56 JSR toggle_object_animation_frame_and_set_timer ; Set object_animation_frame_timer to var_0 and toggle object_animation_frame.
 
ROM7:FA57 skip_toggle_animation_frame: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:FA57 JSR set_var_0_to_object_position
ROM7:FA58 LDA object_direction,X
ROM7:FA59 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
ROM7:FA5A BEQ horizontal
ROM7:FA5B LDY #3
ROM7:FA5C AND #ControllerBits_Dpad_Up
ROM7:FA5D BNE store_animation_frame
ROM7:FA5E DEY
 
ROM7:FA72 store_animation_frame:
ROM7:FA72 LDA object_animation_frame,X
ROM7:FA73 STA var_15
ROM7:FA74 RTS
 
ROM7:FA75 horizontal:
ROM7:FA75 LDY #0
ROM7:FA76 LDA object_animation_frame,X
ROM7:FA77 BEQ loc_1FA80
ROM7:FA78 INY
 
ROM7:FA80 loc_1FA80:
ROM7:FA80 LDA object_direction,X
ROM7:FA81 AND #1
ROM7:FA82 BNE locret_1FA88
ROM7:FA83 INC var_15
 
ROM7:FA88 locret_1FA88:
ROM7:FA88 RTS
 
Subroutine update_object_animation_frame
ROM7:FA89 update_object_animation_frame:
ROM7:FA89 STA var_0
ROM7:FA8A DEC object_animation_frame_timer,X
ROM7:FA8B BNE set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:FA8C JSR toggle_object_animation_frame_and_set_timer ; Toggle the animation frame when the timer expires.
 
ROM7:FA93 set_var_0_to_object_position: ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
ROM7:FA93 LDA object_x,X
ROM7:FA94 STA var_0
ROM7:FA95 LDA object_y,X
ROM7:FA96 STA var_1
ROM7:FA97 LDA #0
ROM7:FA98 STA var_15 ; Set to 0
ROM7:FA99 RTS
 
Subroutine toggle_object_animation_frame_and_set_timer
; Set object_animation_frame_timer to var_0 and toggle object_animation_frame.
ROM7:FAA0 toggle_object_animation_frame_and_set_timer:
ROM7:FAA0 LDA var_0
ROM7:FAA1 STA object_animation_frame_timer,X
ROM7:FAA2 LDA object_animation_frame,X
ROM7:FAA3 EOR #1
ROM7:FAA4 STA object_animation_frame,X
ROM7:FAA5 RTS
 
Subroutine adjust_walk_state
ROM7:FAAE adjust_walk_state:
 
ROM7:FAAE LDA walk_state_and_weapon_state
ROM7:FAAF AND #WalkState_Unknown2_30
ROM7:FAB0 CMP #WalkState_Unknown2_10
ROM7:FAB1 BNE check_state_0x20
ROM7:FAB2 LDA walk_state_and_weapon_state ; (state & 0x30) == 0x10
ROM7:FAB3 AND #$F
ROM7:FAB4 BNE bits_0x0F_set
ROM7:FAB5 BEQ bits_0x0F_not_set
 
ROM7:FAB6 check_state_0x20:
ROM7:FAB6 CMP #WalkState_Unknown2_20
ROM7:FAB7 BNE check_state_0x30
ROM7:FAB8 LDA walk_state_and_weapon_state ; (state & 0x30) == 0x20
ROM7:FAB9 AND #$F
ROM7:FABA BNE bits_0x0F_set
 
ROM7:FABB bits_0x0F_not_set: ; In state 0x10 or 0x20 and 0x0F is zero. Set 0x01.
ROM7:FABB INC walk_state_and_weapon_state
ROM7:FABC JMP loc_1FAD3
 
ROM7:FABD bits_0x0F_set: ; In state 0x10 or 0x20 and 0x0F is nonzero. Switch to state 0x30.
ROM7:FABD LDA walk_state_and_weapon_state
ROM7:FABE ORA #$30
ROM7:FABF STA walk_state_and_weapon_state
 
ROM7:FAD3 loc_1FAD3:
ROM7:FAD3 LDA #1
ROM7:FAD4 STA object_animation_frame
ROM7:FAD5 RTS
 
ROM7:FAD6 check_state_0x30:
ROM7:FAD6 CMP #WalkState_Unknown2_30
ROM7:FAD7 BNE state_0
ROM7:FAD8 LDA walk_state_and_weapon_state ; (state & 0x30) == 0x30
ROM7:FAD9 AND #$C0
ROM7:FADA STA walk_state_and_weapon_state ; state &= 0xC0: set state 0 and clear 0x0F
 
ROM7:FADB state_0:
ROM7:FADB RTS
 
ROM7:FADC   .BYTE $FF
ROM7:FADD   .BYTE $FF
ROM7:FADE   .BYTE $FF
ROM7:FADF   .BYTE $FF
ROM7:FAE0   .BYTE $FF
ROM7:FAE1   .BYTE $FF
ROM7:FAE2   .BYTE $FF
ROM7:FAE3   .BYTE $FF
ROM7:FAE4   .BYTE $FF
ROM7:FAE5   .BYTE $FF
ROM7:FAE6   .BYTE $FF
ROM7:FAEF default_enemy_properties: .BYTE $FF ; ObjectType_None
ROM7:FAF0   .BYTE 0 ; ObjectType_BlueLynel
ROM7:FAF1   .BYTE 0 ; ObjectType_RedLynel
ROM7:FAF2   .BYTE 0 ; ObjectType_BlueMoblin
ROM7:FAF3   .BYTE 0 ; ObjectType_RedMoblin
ROM7:FAF4   .BYTE 0 ; ObjectType_BlueGoriya
ROM7:FAF5   .BYTE 0 ; ObjectType_RedGoriya
ROM7:FAF6   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_SkipAutomaticSpriteUpdate ; ObjectType_RedOctorok
ROM7:FAF7   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_SkipAutomaticSpriteUpdate ; ObjectType_RedOctorokFast
ROM7:FAF8   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_SkipAutomaticSpriteUpdate ; ObjectType_BlueOctorok
ROM7:FAF9   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_SkipAutomaticSpriteUpdate ; ObjectType_BlueOctorokFast
ROM7:FAFA   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedDarknut
ROM7:FAFB   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueDarknut
ROM7:FAFC   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueTektite
ROM7:FAFD   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedTektite
ROM7:FAFE   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_BlueLeever
ROM7:FAFF   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_RedLeever (0x10)
ROM7:FB00   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Zola
ROM7:FB01   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_Vire
ROM7:FB02   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_Zol
ROM7:FB03   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_MoveHitboxRight4Pixels ; ObjectType_Gel1
ROM7:FB04   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_MoveHitboxRight4Pixels ; ObjectType_Gel2
ROM7:FB05   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_PolsVoice
ROM7:FB06   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_LikeLike
ROM7:FB07   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Digdogger_Spawn
ROM7:FB08   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Smoke
ROM7:FB09   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_Peahat
ROM7:FB0A   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueKeese
ROM7:FB0B   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedKeese
ROM7:FB0C   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_DarkKeese
ROM7:FB0D   .BYTE EnemyProperties_SkipAutomaticUpdate ; ObjectType_Armos
ROM7:FB0E   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_FallingRocks_Daemon
ROM7:FB0F   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_FallingRock (0x20)
ROM7:FB10   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Ghini
ROM7:FB11   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_GhiniFromTombs
ROM7:FB12   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueWizzrobe
ROM7:FB13   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedWizzrobe
ROM7:FB14   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Unknown_25
ROM7:FB15   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Unknown_26
ROM7:FB16   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_WallMaster
ROM7:FB17   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Rope
ROM7:FB18   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Unknown_29
ROM7:FB19   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Stalfos
ROM7:FB1A   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Bubble
ROM7:FB1B   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueBubble
ROM7:FB1C   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedBubble
ROM7:FB1D   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Whirlwind
ROM7:FB1E   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Fairy
ROM7:FB1F   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gibdo (0x30)
ROM7:FB20   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_DodongoMiniboss
ROM7:FB21   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_DodongoBoss
ROM7:FB22   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_BlueGohma
ROM7:FB23   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RedGohma
ROM7:FB24   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_TenRupees
ROM7:FB25   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_HungryGoriya
ROM7:FB26   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Zelda
ROM7:FB27   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_Invincible|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Digdogger_3
ROM7:FB28   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_Invincible|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Digdogger_1
ROM7:FB29   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels ; ObjectType_RedLanmola
ROM7:FB2A   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels ; ObjectType_BlueLanmola
ROM7:FB2B   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Manhandla
ROM7:FB2C   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_FlipHorizontal_MirrorVertical|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Aquamentus
ROM7:FB2D   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Ganon
ROM7:FB2E   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Flame
ROM7:FB2F   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Flame_Unkillable (0x40)
ROM7:FB30   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Moldorm
ROM7:FB31   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gleeok_1_Head
ROM7:FB32   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gleeok_2_Heads
ROM7:FB33   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gleeok_3_Heads
ROM7:FB34   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gleeok_4_Heads
ROM7:FB35   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Gleeok_Flying_Head
ROM7:FB36   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Patra_1
ROM7:FB37   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Patra_2
ROM7:FB38   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_WallTrap_Vert
ROM7:FB39   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_WallTrap_Horiz
ROM7:FB3A   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_0
ROM7:FB3B   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_1
ROM7:FB3C   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_2
ROM7:FB3D   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_3
ROM7:FB3E   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldManItem_1
ROM7:FB3F   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_5 (0x50)
ROM7:FB40   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_Mugger
ROM7:FB41   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_OldMan_7
ROM7:FB42   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Octorok_Projectile
ROM7:FB43   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FB44   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Homing_Fireball_1
ROM7:FB45   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Homing_Fireball_2
ROM7:FB46   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_DrawHalfTile|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Lynel_Sword
ROM7:FB47   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FB48   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FB49   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FB4A   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Moblin_Arrow
ROM7:FB4B   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_Invincible|EnemyProperties_MoveHitboxRight4Pixels|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_Goriya_Boomerang
ROM7:FB4C   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_EnemyDeath
ROM7:FB4D   .BYTE EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink ; ObjectType_RecorderPondDaemon
ROM7:FB4E enemy_health_table: .BYTE 6 ; Two enemy health values are packed into eachbyte.
ROM7:FB4F   .BYTE $43 ; ObjectType_RedLynel, ObjectType_BlueMoblin
ROM7:FB50   .BYTE $25 ; ObjectType_RedMoblin, ObjectType_BlueGoriya
ROM7:FB51   .BYTE $31 ; ObjectType_RedGoriya, ObjectType_RedOctorok
ROM7:FB52   .BYTE $12 ; ObjectType_RedOctorokFast, ObjectType_BlueOctorok
ROM7:FB53   .BYTE $24 ; ObjectType_BlueOctorokFast, ObjectType_RedDarknut
ROM7:FB54   .BYTE $81 ; ObjectType_BlueDarknut, ObjectType_BlueTektite
ROM7:FB55   .BYTE $14 ; ObjectType_RedTektite, ObjectType_BlueLeever
ROM7:FB56   .BYTE $22 ; ObjectType_RedLeever, ObjectType_Zola
ROM7:FB57   .BYTE $42 ; ObjectType_Vire, ObjectType_Zol
ROM7:FB58   .BYTE 0 ; ObjectType_Gel1, ObjectType_Gel2
ROM7:FB59   .BYTE $A9 ; ObjectType_PolsVoice, ObjectType_LikeLike
ROM7:FB5A   .BYTE $8F ; ObjectType_Digdogger_Spawn, ObjectType_Smoke
ROM7:FB5B   .BYTE $20 ; ObjectType_Peahat, ObjectType_BlueKeese
ROM7:FB5C   .BYTE 0 ; ObjectType_RedKeese, ObjectType_DarkKeese
ROM7:FB5D   .BYTE $3F ; ObjectType_Armos, ObjectType_FallingRocks_Daemon
ROM7:FB5E   .BYTE $F9 ; ObjectType_FallingRock, ObjectType_Ghini (0x10)
ROM7:FB5F   .BYTE $FA ; ObjectType_GhiniFromTombs, ObjectType_BlueWizzrobe
ROM7:FB60   .BYTE $46 ; ObjectType_RedWizzrobe, ObjectType_Unknown_25
ROM7:FB61   .BYTE $62 ; ObjectType_Unknown_26, ObjectType_WallMaster
ROM7:FB62   .BYTE $11 ; ObjectType_Rope, ObjectType_Unknown_29
ROM7:FB63   .BYTE $2F ; ObjectType_Stalfos, ObjectType_Bubble
ROM7:FB64   .BYTE $FF ; ObjectType_BlueBubble, ObjectType_RedBubble
ROM7:FB65   .BYTE $FF ; ObjectType_Whirlwind, ObjectType_Fairy
ROM7:FB66   .BYTE $7F ; ObjectType_Gibdo, ObjectType_DodongoMiniboss
ROM7:FB67   .BYTE $F6 ; ObjectType_DodongoBoss, ObjectType_BlueGohma
ROM7:FB68   .BYTE $2F ; ObjectType_RedGohma, ObjectType_TenRupees
ROM7:FB69   .BYTE $FF ; ObjectType_HungryGoriya, ObjectType_Zelda
ROM7:FB6A   .BYTE $FF ; ObjectType_Digdogger_3, ObjectType_Digdogger_1
ROM7:FB6B   .BYTE $22 ; ObjectType_RedLanmola, ObjectType_BlueLanmola
ROM7:FB6C   .BYTE $46 ; ObjectType_Manhandla, ObjectType_Aquamentus
ROM7:FB6D   .BYTE $F1 ; ObjectType_Ganon, ObjectType_Flame
ROM7:FB6E   .BYTE $F2 ; ObjectType_Flame_Unkillable, ObjectType_Moldorm (0x20)
ROM7:FB6F   .BYTE $AA ; ObjectType_Gleeok_1_Head, ObjectType_Gleeok_2_Heads
ROM7:FB70   .BYTE $AA ; ObjectType_Gleeok_3_Heads, ObjectType_Gleeok_4_Heads
ROM7:FB71   .BYTE $FB ; ObjectType_Gleeok_Flying_Head, ObjectType_Patra_1
ROM7:FB72   .BYTE $BF ; ObjectType_Patra_2, ObjectType_WallTrap_Vert
ROM7:FB73   .BYTE $F0
 
Subroutine update_monster
; X is the object to update. ; ; processing_object_index is also set to X.
ROM7:FB74 update_monster:
 
ROM7:FB74 PHA
ROM7:FB75 LDA #4
ROM7:FB76 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FB77 PLA
ROM7:FB78 LDY object_slot_in_use,X
ROM7:FB79 STY var_15
ROM7:FB7A BEQ enemy_already_spawned
ROM7:FB7B LDA object_type,X ; check if ObjectType_Armos, ObjectType_GhiniFromTombs or ObjectType_Octorok_Projectile
ROM7:FB7C CMP #ObjectType_Armos ; If object type == ObjectType_Armos (0x1E)
ROM7:FB7D BEQ enemy_needs_spawning
ROM7:FB7E CMP #ObjectType_GhiniFromTombs ; If object type == ObjectType_GhiniFromTombs (0x22)
ROM7:FB7F BEQ enemy_needs_spawning
ROM7:FB80 CMP #ObjectType_Octorok_Projectile
ROM7:FB81 BCS enemy_needs_spawning ; If object type >= ObjectType_Octorok_Projectile (0x53)
ROM7:FB82 LDA #7 ; Set the enemy timer to 7 frames for other object types.
ROM7:FB83 STA enemy_action_timers,X
 
ROM7:FB84 enemy_needs_spawning:
ROM7:FB84 LDA #0
ROM7:FB85 STA object_slot_in_use,X ; Set to 0 (mark that this enemy has been spawned)
ROM7:FB86 JMP spawn_monster_main
 
ROM7:FB87 enemy_already_spawned: ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:FB87 LDY enemy_spawn_state,X
ROM7:FB88 BEQ enemy_not_in_spawn_cloud
ROM7:FB89 JMP enemy_in_spawn_cloud
 
ROM7:FB8A enemy_not_in_spawn_cloud:
ROM7:FB8A CMP #$6A
ROM7:FB8B BCC call_object_update ; Object IDs < 0x6A are handled by the jump table below.
ROM7:FB8C LDA #1
ROM7:FB8D JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FB8E JMP do_update_monster_over_0x6A ; Other object IDs are uncommon ones, like shops.
 
ROM7:FB8F call_object_update:
ROM7:FB8F JSR call_jump_table
 
ROM7:FB90   .WORD no_spawn
ROM7:FB92   .WORD update_monster_lynel ; Blue Lynel
ROM7:FB94   .WORD update_monster_lynel ; Red Lynel
ROM7:FB96   .WORD update_monster_moblin ; Blue Moblin
ROM7:FB98   .WORD update_monster_moblin ; Red Moblin
ROM7:FB9A   .WORD update_monster_goriya ; Blue Goriya
ROM7:FB9C   .WORD update_monster_goriya ; Red Goriya
ROM7:FB9E   .WORD update_monster_octorok ; Red Octorok
ROM7:FBA0   .WORD update_monster_octorok ; Red Octorok (fast)
ROM7:FBA2   .WORD update_monster_octorok ; Blue Octorok
ROM7:FBA4   .WORD update_monster_octorok ; Blue Octorok (fast)
ROM7:FBA6   .WORD update_monster_darknut ; Red Darknut
ROM7:FBA8   .WORD update_monster_darknut ; Blue Darknut
ROM7:FBAA   .WORD update_monster_tektite_or_falling_rock ; Blue Tektite
ROM7:FBAC   .WORD update_monster_tektite_or_falling_rock ; Red Tektite
ROM7:FBAE   .WORD update_monster_leever_blue ; Blue Leever
ROM7:FBB0   .WORD update_monster_leever_red ; 0x10 Red Leever
ROM7:FBB2   .WORD update_monster_zola ; Zola
ROM7:FBB4   .WORD update_monster_vire ; Vire
ROM7:FBB6   .WORD update_monster_zol ; Zol
ROM7:FBB8   .WORD update_monster_gel ; Gel
ROM7:FBBA   .WORD update_monster_gel ; Gel
ROM7:FBBC   .WORD update_monster_pols_voice ; Pols Voice
ROM7:FBBE   .WORD update_monster_like_like ; Like Like
ROM7:FBC0   .WORD update_monster_digdogger
ROM7:FBC2   .WORD no_spawn
ROM7:FBC4   .WORD update_monster_peahat ; Peahat
ROM7:FBC6   .WORD update_monster_keese ; Blue Keese
ROM7:FBC8   .WORD update_monster_keese ; Red Keese
ROM7:FBCA   .WORD update_monster_keese ; Dark Keese
ROM7:FBCC   .WORD update_monster_armos ; Armos
ROM7:FBCE   .WORD update_monster_falling_rock_daemon ; ObjectType_FallingRocks_Daemon
ROM7:FBD0   .WORD update_monster_tektite_or_falling_rock ; ObjectType_FallingRock (0x20)
ROM7:FBD2   .WORD update_monster_ghini ; ObjectType_Ghini
ROM7:FBD4   .WORD update_monster_ghini_from_tombs ; ObjectType_GhiniFromTombs
ROM7:FBD6   .WORD update_monster_wizzrobe_blue ; Blue Wizzrobe
ROM7:FBD8   .WORD update_monster_wizzrobe_red ; Red Wizzrobe
ROM7:FBDA   .WORD update_monster_patra_eye ; ObjectType_Patra_Eye_1
ROM7:FBDC   .WORD update_monster_patra_eye ; ObjectType_Patra_Eye_2
ROM7:FBDE   .WORD update_monster_wall_master ; Wall Master
ROM7:FBE0   .WORD update_monster_rope ; Rope
ROM7:FBE2   .WORD no_spawn ; ObjectType_Unknown_29
ROM7:FBE4   .WORD update_monster_stalfos ; Stalfos
ROM7:FBE6   .WORD update_monster_bubble ; Bubble
ROM7:FBE8   .WORD update_monster_bubble ; Blue Bubble
ROM7:FBEA   .WORD update_monster_bubble ; Red Bubble
ROM7:FBEC   .WORD update_monster_whirlwind ; Whirlwind
ROM7:FBEE   .WORD update_monster_fairy ; Fairy (stationary)
ROM7:FBF0   .WORD update_monster_gibdo ; Gibdo (0x30)
ROM7:FBF2   .WORD update_monster_dodongo ; Dodongo (miniboss)
ROM7:FBF4   .WORD update_monster_dodongo ; Dodongo (boss)
ROM7:FBF6   .WORD update_monster_gohma ; Blue Gohma
ROM7:FBF8   .WORD update_monster_gohma ; Red Gohma
ROM7:FBFA   .WORD update_monster_10_rupee ; 10 rupee
ROM7:FBFC   .WORD update_monster_hungry_goriya ; Hungry Goriya
ROM7:FBFE   .WORD update_monster_zelda ; Zelda
ROM7:FC00   .WORD update_monster_digdogger ; Digdogger (3)
ROM7:FC02   .WORD update_monster_digdogger ; Digdogger (1)
ROM7:FC04   .WORD update_monster_lanmola ; Red Lanmola
ROM7:FC06   .WORD update_monster_lanmola ; Blue Lanmola
ROM7:FC08   .WORD update_monster_manhandla ; Manhandla
ROM7:FC0A   .WORD update_monster_aquamentus ; Aquamentus
ROM7:FC0C   .WORD update_monster_ganon ; Ganon
ROM7:FC0E   .WORD update_monster_flame ; Flame
ROM7:FC10   .WORD update_monster_flame_unkillable ; ObjectType_Flame_Unkillable (0x40)
ROM7:FC12   .WORD update_monster_moldorm ; ObjectType_Moldorm
ROM7:FC14   .WORD update_monster_gleeok ; ObjectType_Gleeok_1_Head
ROM7:FC16   .WORD update_monster_gleeok ; ObjectType_Gleeok_2_Heads
ROM7:FC18   .WORD update_monster_gleeok ; ObjectType_Gleeok_3_Heads
ROM7:FC1A   .WORD update_monster_gleeok ; ObjectType_Gleeok_4_Heads
ROM7:FC1C   .WORD update_monster_gleeok_flying_head ; ObjectType_Gleeok_Flying_Head
ROM7:FC1E   .WORD update_monster_patra ; ObjectType_Patra_1
ROM7:FC20   .WORD update_monster_patra ; ObjectType_Patra_2
ROM7:FC22   .WORD update_monster_wall_trap ; Wall trap (vertical)
ROM7:FC24   .WORD update_monster_wall_trap ; Wall trap (horizontal)
ROM7:FC26   .WORD update_monster_old_man
ROM7:FC28   .WORD update_monster_old_man
ROM7:FC2A   .WORD update_monster_old_man
ROM7:FC2C   .WORD update_monster_old_man
ROM7:FC2E   .WORD update_monster_old_man
ROM7:FC30   .WORD update_monster_old_man ; Old man (0x50)
ROM7:FC32   .WORD update_monster_event_1 ; "Master having it", "money or your life", etc
ROM7:FC34   .WORD update_monster_old_man
ROM7:FC36   .WORD update_monster_projectile ; ObjectType_Octorok_Projectile (0x53)
ROM7:FC38   .WORD update_monster_projectile
ROM7:FC3A   .WORD update_monster_homing_fireball ; ObjectType_Homing_Fireball_1
ROM7:FC3C   .WORD update_monster_homing_fireball ; ObjectType_Homing_Fireball_2
ROM7:FC3E   .WORD update_monster_projectile ; ObjectType_Lynel_Sword
ROM7:FC40   .WORD update_monster_projectile ; Wizzrobe beam?
ROM7:FC42   .WORD update_monster_projectile
ROM7:FC44   .WORD update_monster_projectile
ROM7:FC46   .WORD update_monster_moblin_arrow ; ObjectType_Moblin_Arrow
ROM7:FC48   .WORD update_projectile ; ObjectType_Goriya_Boomerang
ROM7:FC4A   .WORD set_enemy_killed ; ObjectType_EnemyDeath
ROM7:FC4C   .WORD update_recorder_pond_daemon ; ObjectType_RecorderPondDaemon
ROM7:FC4E   .WORD no_spawn ; ObjectType_Ladder
ROM7:FC50   .WORD update_monster_floor_pickup ; ObjectType_FloorPickup (0x60)
ROM7:FC52   .WORD update_monster_overworld_secret_raft ; ObjectType_OverworldSecret_Raft
ROM7:FC54   .WORD update_monster_overworld_secret_push_block ; ObjectType_OverworldSecret_Push_Rock
ROM7:FC56   .WORD update_monster_overworld_secret_bomb ; ObjectType_OverworldSecret_Bomb
ROM7:FC58   .WORD update_monster_overworld_secret_candle ; ObjectType_OverworldSecret_Candle
ROM7:FC5A   .WORD update_monster_overworld_secret_push_block ; ObjectType_OverworldSecret_Push_Tomb
ROM7:FC5C   .WORD update_monster_overworld_secret_push_block ; ObjectType_OverworldSecret_Push_Armos
ROM7:FC5E   .WORD update_monster_overworld_secret_bomb ; ObjectType_OverworldSecret_Bomb_2
ROM7:FC60   .WORD update_monster_dungeon_secret_push_block ; ObjectType_DungeonSecret_Push_Block
ROM7:FC62   .WORD no_spawn
 
ROM7:FC64 enemy_in_spawn_cloud: ; This is related to the enemy spawn cloud.
ROM7:FC64 JSR update_spawn_cloud
ROM7:FC65 LDA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:FC66 AND #$F
ROM7:FC67 CMP #4
ROM7:FC68 BCS spawn_cloud_finished ; A >= 4: the cloud animation is finished and we're ready
  ; to create the enemy
 
ROM7:FC69 no_spawn:
ROM7:FC69 RTS
 
ROM7:FC6A spawn_cloud_finished: ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:FC6A LDA enemy_spawn_state,X
ROM7:FC6B AND #$10
ROM7:FC6C BEQ set_no_spawn_cloud_thunk ; We've finished animating the spawn cloud. If 0x10 isn't set, clear the spawn cloud so the enemy will spawn normally.
ROM7:FC6D LDA object_type,X ; check if ObjectType_LinkDead, ObjectType_Gel1 or ObjectType_RedKeese
ROM7:FC6E STA enemy_state_0,X
ROM7:FC6F CMP #ObjectType_EnemyDeath
ROM7:FC70 BEQ skip
ROM7:FC71 CMP #ObjectType_Gel1
ROM7:FC72 BEQ skip
ROM7:FC73 CMP #ObjectType_RedKeese
ROM7:FC74 BEQ skip
ROM7:FC75 LDA drop_counter
ROM7:FC76 CLC
ROM7:FC77 ADC #1
ROM7:FC78 CMP #10
ROM7:FC79 BNE loc_1FCBA
ROM7:FC7A LDA #0
 
ROM7:FCBA loc_1FCBA:
ROM7:FCBA STA drop_counter
ROM7:FCBB LDA object_type,X ; Check if this is ObjectType_Zola.
ROM7:FCBC CMP #ObjectType_Zola
ROM7:FCBD BEQ skip
ROM7:FCBE INC object_type ; What's this doing? Object X isn't a killable object
  ; (X = 1 is the first object, 0 is Link) and this seems
  ; to count kills on the current screen except for Zola.
 
ROM7:FCBF skip: ; All dead enemies turn into this, whether they actually have
ROM7:FCBF LDA #ObjectType_FloorPickup ; a floor pickup or not. If they have no item, this is invisible.
ROM7:FCC0 STA object_type,X ; Set to ObjectType_FloorPickup.
ROM7:FCC1 STA object_slot_in_use,X
ROM7:FCC2 LDA #EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FCC3 STA enemy_properties,X ; Set EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FCC4 JSR enemy_killed
 
ROM7:FCC5 set_no_spawn_cloud_thunk: ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM7:FCC5 JMP set_enemy_spawn_state_to_spawned
 
Function chunk for update_monster
ROM7:FCC6 spawn_monster_main:
ROM7:FCC6 LDX processing_object_index
ROM7:FCC7 LDA dungeon_idx
ROM7:FCC8 BNE skip_spawn_from_side ; Skip if not on the overworld
ROM7:FCC9 LDA current_screen_data_5 ; This is the dungeon_screen_data_5 value for the
  ; current room. This has different interpretations
  ; for the overworld and dungeons.
ROM7:FCCA AND #ScreenData_Overworld_5_MonstersEnterFromSide
ROM7:FCCB BEQ skip_spawn_from_side ; Skip if enemies don't enter from the side.
ROM7:FCCC LDA object_type,X
ROM7:FCCD CMP #ObjectType_Zola ; These enemy types never enter from the side.
ROM7:FCCE BEQ skip_spawn_from_side
ROM7:FCCF CMP #ObjectType_Flame_Unkillable
ROM7:FCD0 BEQ skip_spawn_from_side
ROM7:FCD1 CMP #ObjectType_Armos
ROM7:FCD2 BEQ skip_spawn_from_side
ROM7:FCD3 CMP #ObjectType_Whirlwind
ROM7:FCD4 BEQ skip_spawn_from_side
ROM7:FCD5 CMP #ObjectType_Octorok_Projectile
ROM7:FCD6 BCS skip_spawn_from_side ; Ignore this for projectiles.
 
ROM7:FCD7 check_spawn_from_side_timer: ; Timer before the next enemy enters from the side.
ROM7:FCD7 LDA enter_from_side_timer
ROM7:FCD8 BEQ enter_from_side_timer_elapsed
ROM7:FCD9 STA object_slot_in_use,X ; This probably marks that this enemy hasn't actually spawned yet.
ROM7:FCDA RTS
 
ROM7:FCDB enter_from_side_timer_elapsed: ; This enemy is entering from the side, and the timer to spawn the next enemy has elapsed.
ROM7:FCDB LDX processing_object_index
ROM7:FCDC LDA #5
ROM7:FCDD JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FCDE JSR get_next_spawn_from_side_position
ROM7:FCDF LDA spawn_from_side_position
ROM7:FCE0 PHA ; Push the spawn from side position.
ROM7:FCE1 ASL A ; Shift the X position from 0x0F to 0xF0.
ROM7:FCE2 ASL A
ROM7:FCE3 ASL A
ROM7:FCE4 ASL A
ROM7:FCE5 STA object_x,X ; Store the enemy's X spawn position.
ROM7:FCE6 PLA ; Restore the spawn from side position.
ROM7:FCE7 AND #$F0 ; Mask out the spawn from side Y position.
ROM7:FCE8 SEC
ROM7:FCE9 SBC #3
ROM7:FCEA STA object_y,X ; Store the enemy's Y spawn position.
ROM7:FCEB LDA prng_1,X
ROM7:FCEC AND #3
ROM7:FCED CLC
ROM7:FCEE ADC #2
ROM7:FCEF STA enter_from_side_timer ; Set the time to the next spawn from side to 2-6 frames.
ROM7:FCF0 LDA #5
ROM7:FCF1 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FCF2 JSR check_if_spawn_is_near_link ; Check if the current enemy is close to Link. Set carry if close, clear carry otherwise.
ROM7:FCF3 BCS check_spawn_from_side_timer ; If the enemy spawned too close to Link, don't spawn it here.
  ; Jump back and try again so we pick a different spawn location.
ROM7:FCF4 LDA #0
ROM7:FCF5 STA enemy_spawn_state,X ; Mark this spawn from side enemy as spawned.
 
ROM7:FCF6 skip_spawn_from_side:
ROM7:FCF6 LDA #4
ROM7:FCF7 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FCF8 LDX processing_object_index
ROM7:FCF9 LDY object_type,X
ROM7:FCFA CPY #ObjectType_Armos ; Armos
ROM7:FCFB BEQ skip_set_action_timer
ROM7:FCFC CPY #ObjectType_GhiniFromTombs ; Ghini
ROM7:FCFD BEQ skip_set_action_timer
ROM7:FCFE CPY #ObjectType_Octorok_Projectile
ROM7:FCFF BCS skip_set_action_timer ; > ObjectType_Octorok_Projectile
ROM7:FD00 TXA
ROM7:FD01 STA enemy_action_timers,X
 
ROM7:FD02 skip_set_action_timer: ; ObjectType_None
ROM7:FD02 LDA default_enemy_properties,Y
ROM7:FD03 STA enemy_properties,X ; Set this enemy's initial properties from default_enemy_properties.
ROM7:FD04 TYA ; A = Y (object type)
ROM7:FD05 STA var_0 ; Store the object type.
ROM7:FD06 LSR A
ROM7:FD07 TAY
ROM7:FD08 LDA enemy_health_table,Y
ROM7:FD09 JSR unpack_enemy_health ; If var_0 if even, return A & 0xF0. Otherwise, return (A << 4) (shifting 0x0F into 0xF0).
ROM7:FD0A STA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
ROM7:FD0B LDA var_0
ROM7:FD0C CMP #$6A
ROM7:FD0D BCC call_spawn_object ; If A < 0x6A, spawn normally.
ROM7:FD0E LDA #1
ROM7:FD0F JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FD10 JMP spawn_event ; Object IDs >= 0x6A are things like shops.
 
ROM7:FD11 call_spawn_object:
ROM7:FD11 CMP #ObjectType_Ladder
ROM7:FD12 BCC call_object_spawn ; If A < 0x5F, jump to call jump table
ROM7:FD13 JMP spawn_default ; Otherwise, just call the default
 
ROM7:FD14 call_object_spawn:
ROM7:FD14 JSR call_jump_table
 
ROM7:FD15   .WORD no_spawn
ROM7:FD17   .WORD spawn_monster_basic ; BlueLynel
ROM7:FD19   .WORD spawn_monster_basic ; RedLynel
ROM7:FD1B   .WORD spawn_monster_basic ; BlueMoblin
ROM7:FD1D   .WORD spawn_monster_basic ; RedMoblin
ROM7:FD1F   .WORD spawn_monster_basic ; BlueGoriya
ROM7:FD21   .WORD spawn_monster_basic ; RedGoriya
ROM7:FD23   .WORD spawn_monster_octorok_or_ghini_master ; RedOctorok
ROM7:FD25   .WORD spawn_monster_fast_octorok ; RedOctorokFast
ROM7:FD27   .WORD spawn_monster_octorok_or_ghini_master ; BlueOctorok
ROM7:FD29   .WORD spawn_monster_fast_octorok ; BlueOctorokFast
ROM7:FD2B   .WORD spawn_darknut ; RedDarknut
ROM7:FD2D   .WORD spawn_darknut ; BlueDarknut
ROM7:FD2F   .WORD spawn_tektite ; BlueTektite
ROM7:FD31   .WORD spawn_tektite ; RedTektite
ROM7:FD33   .WORD spawn_leever ; BlueLeever
ROM7:FD35   .WORD spawn_leever ; RedLeever (0x10)
ROM7:FD37   .WORD spawn_monster_no_timer_no_spawn_cloud ; Zola
ROM7:FD39   .WORD spawn_monster_basic ; Vire
ROM7:FD3B   .WORD spawn_monster_basic ; Zol
ROM7:FD3D   .WORD spawn_monster_basic ; Gel1
ROM7:FD3F   .WORD spawn_gel2 ; Gel2
ROM7:FD41   .WORD spawn_monster_basic ; PolsVoice
ROM7:FD43   .WORD spawn_monster_basic ; LikeLike
ROM7:FD45   .WORD no_spawn ; Digdogger_Spawn
ROM7:FD47   .WORD no_spawn ; Smoke
ROM7:FD49   .WORD spawn_peahat ; Peahat
ROM7:FD4B   .WORD spawn_blue_keese ; BlueKeese
ROM7:FD4D   .WORD spawn_red_keese ; RedKeese
ROM7:FD4F   .WORD spawn_red_keese ; DarkKeese
ROM7:FD51   .WORD spawn_armos_or_ghini ; Armos
ROM7:FD53   .WORD spawn_falling_rocks_spawner ; FallingRocks_Spawn
ROM7:FD55   .WORD spawn_falling_rock ; FallingRock (0x20)
ROM7:FD57   .WORD spawn_monster_octorok_or_ghini_master ; GhiniMaster
ROM7:FD59   .WORD spawn_armos_or_ghini ; GhiniFromTombs
ROM7:FD5B   .WORD spawn_monster_no_timer_no_spawn_cloud ; BlueWizzrobe
ROM7:FD5D   .WORD spawn_monster_no_timer_no_spawn_cloud ; RedWizzrobe
ROM7:FD5F   .WORD spawn_monster_no_timer_no_spawn_cloud ; ObjectType_Patra_Eye_1
ROM7:FD61   .WORD spawn_monster_no_timer_no_spawn_cloud ; ObjectType_Patra_Eye_2
ROM7:FD63   .WORD spawn_monster_no_timer_no_spawn_cloud ; WallMaster
ROM7:FD65   .WORD spawn_rope ; Rope
ROM7:FD67   .WORD no_spawn ; ObjectType_Unknown_29
ROM7:FD69   .WORD spawn_monster_basic ; Stalfos
ROM7:FD6B   .WORD spawn_bubble ; Bubble
ROM7:FD6D   .WORD spawn_bubble ; BlueBubble
ROM7:FD6F   .WORD spawn_bubble ; RedBubble
ROM7:FD71   .WORD no_spawn ; ObjectType_Whirlwind
ROM7:FD73   .WORD spawn_lake_fairy ; Lake fairy
ROM7:FD75   .WORD spawn_monster_basic ; Gibdo (0x30)
ROM7:FD77   .WORD spawn_dodongo ; DodongoMiniboss
ROM7:FD79   .WORD spawn_dodongo ; DodongoBoss
ROM7:FD7B   .WORD spawn_gohma ; BlueGohma
ROM7:FD7D   .WORD spawn_gohma ; RedGohma
ROM7:FD7F   .WORD spawn_ten_rupee ; TenRupee
ROM7:FD81   .WORD spawn_hungry_goriya ; HungryGoriya
ROM7:FD83   .WORD spawn_zelda ; Zelda
ROM7:FD85   .WORD spawn_digdogger_3 ; Digdogger_3
ROM7:FD87   .WORD spawn_digdogger_1 ; Digdogger_1
ROM7:FD89   .WORD spawn_lanmola ; RedLanmola
ROM7:FD8B   .WORD spawn_lanmola ; BlueLanmola
ROM7:FD8D   .WORD spawn_manhandla ; Manhandla
ROM7:FD8F   .WORD spawn_aquamentus ; Aquamentus
ROM7:FD91   .WORD spawn_ganon ; Ganon
ROM7:FD93   .WORD no_spawn ; Flame
ROM7:FD95   .WORD no_spawn ; ObjectType_Flame_Unkillable (0x40)
ROM7:FD97   .WORD spawn_moldorm ; ObjectType_Moldorm
ROM7:FD99   .WORD spawn_gleeok ; ObjectType_Gleeok_1_Head
ROM7:FD9B   .WORD spawn_gleeok ; ObjectType_Gleeok_2_Heads
ROM7:FD9D   .WORD spawn_gleeok ; ObjectType_Gleeok_3_Heads
ROM7:FD9F   .WORD spawn_gleeok ; ObjectType_Gleeok_4_Heads
ROM7:FDA1   .WORD spawn_gleeok_flying_head ; ObjectType_Gleeok_Flying_Head
ROM7:FDA3   .WORD spawn_patra ; ObjectType_Patra_1
ROM7:FDA5   .WORD spawn_patra ; ObjectType_Patra_2
ROM7:FDA7   .WORD spawn_wall_trap ; WallTrap_Vert
ROM7:FDA9   .WORD spawn_wall_trap ; WallTrap_Horiz
ROM7:FDAB   .WORD spawn_old_man ; ObjectType_OldMan_0
ROM7:FDAD   .WORD spawn_old_man ; ObjectType_OldMan_1
ROM7:FDAF   .WORD spawn_old_man ; ObjectType_OldMan_2
ROM7:FDB1   .WORD spawn_old_man ; ObjectType_OldMan_3
ROM7:FDB3   .WORD spawn_old_man ; ObjectType_OldMan_4
ROM7:FDB5   .WORD spawn_old_man ; ObjectType_OldMan_5 (0x50)
ROM7:FDB7   .WORD spawn_old_man_mugger ; ObjectType_OldMan_Mugger
ROM7:FDB9   .WORD spawn_old_man ; ObjectType_OldMan_7
ROM7:FDBB   .WORD spawn_projectile ; Octorok_Projectile
ROM7:FDBD   .WORD spawn_unknown_0x54 ; ObjectType_Unknown_Projectile_54
ROM7:FDBF   .WORD spawn_projectile ; Homing_Fireball_1
ROM7:FDC1   .WORD spawn_projectile ; Homing_Fireball_2
ROM7:FDC3   .WORD spawn_projectile ; Lynel_Sword
ROM7:FDC5   .WORD spawn_projectile ; ObjectType_Unknown_Projectile_58
ROM7:FDC7   .WORD spawn_projectile ; ObjectType_Unknown_Projectile_59
ROM7:FDC9   .WORD spawn_projectile ; ObjectType_Unknown_Projectile_5A
ROM7:FDCB   .WORD set_enemy_spawn_state_to_spawned ; ObjectType_Moblin_Arrow
ROM7:FDCD   .WORD set_enemy_spawn_state_to_spawned ; ObjectType_Goriya_Boomerang
ROM7:FDCF   .WORD set_enemy_killed ; ObjectType_EnemyDeath
ROM7:FDD1   .WORD spawn_recorder_pond_daemon ; ObjectType_RecorderPondDaemon
 
Subroutine update_monster_whirlwind
ROM7:FE40 update_monster_whirlwind:
 
ROM7:FE40 LDA #1
ROM7:FE41 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE42 JMP update_monster_whirlwind_main
 
Subroutine spawn_ten_rupee
ROM7:FE48 spawn_ten_rupee:
 
ROM7:FE48 LDA #1
ROM7:FE49 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE4A JMP spawn_ten_rupees_main ; This object creates ten copies of itself when it's spawned.
  ; The copies act like 1-rupee drops.
 
Subroutine update_monster_10_rupee
ROM7:FE50 update_monster_10_rupee:
 
ROM7:FE50 LDA #1
ROM7:FE51 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE52 JMP update_monster_10_rupee_main
 
Subroutine spawn_wall_trap
ROM7:FE58 spawn_wall_trap:
 
ROM7:FE58 LDA #1
ROM7:FE59 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE5A JMP spawn_wall_trap_main ; Load to copy to spawned traps
 
Subroutine update_monster_wall_trap
ROM7:FE60 update_monster_wall_trap:
 
ROM7:FE60 LDA #1
ROM7:FE61 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE62 JMP update_monster_wall_trap_main
 
Subroutine spawn_old_man
ROM7:FE68 spawn_old_man:
 
ROM7:FE68 LDA #1
ROM7:FE69 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE6A JMP spawn_old_man_main
 
Subroutine spawn_old_man_mugger
ROM7:FE70 spawn_old_man_mugger:
ROM7:FE70 LDA #1
ROM7:FE71 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE72 JMP spawn_old_man_mugger_main
 
Subroutine spawn_hungry_goriya
ROM7:FE78 spawn_hungry_goriya:
 
ROM7:FE78 LDA #1
ROM7:FE79 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE7A JMP spawn_hungry_goriya_main
 
Subroutine update_monster_old_man
ROM7:FE80 update_monster_old_man:
ROM7:FE80 LDA #1
ROM7:FE81 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE82 JMP update_monster_old_man_main
 
Subroutine update_monster_event_1
ROM7:FE88 update_monster_event_1:
ROM7:FE88 LDA #1
ROM7:FE89 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE8A JMP update_monster_event_1_main
 
Subroutine update_monster_hungry_goriya
ROM7:FE90 update_monster_hungry_goriya:
 
ROM7:FE90 LDA #1
ROM7:FE91 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FE92 JMP update_monster_hungry_goriya_main
 
Subroutine decrease_invincibility_frames
; Reduce the i-frames for object X.
ROM7:FE98 decrease_invincibility_frames:
ROM7:FE98 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
ROM7:FE99 BEQ ret ; Return if 0
ROM7:FE9A LDA frame_counter
ROM7:FE9B LSR A
ROM7:FE9C BCS ret ; Return if the frame number is odd
ROM7:FE9D DEC invincibility_frames,X ; Decrement every other frame
  ; Invincibility frames?
 
ROM7:FE9E ret:
ROM7:FE9E RTS
 
Subroutine set_enemy_killed
ROM7:FEA6 set_enemy_killed:
ROM7:FEA6 LDA #Sound1_KilledEnemy
ROM7:FEA7 STA play_sound_1 ; Play Sound1_KilledEnemy
ROM7:FEA8 LDA #$10
ROM7:FEA9 STA enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
ROM7:FEAA RTS
 
Subroutine delete_enemy
; X = object slot
ROM7:FEB1 delete_enemy:
 
ROM7:FEB1 LDA #ObjectType_None
 
ROM7:FEB3 create_enemy:
ROM7:FEB3 STA object_type,X
ROM7:FEB4 LDA #0
ROM7:FEB5 JMP continue ; Set to 0
 
Subroutine find_last_available_object_idx
; Result is returned in tmp_result.
ROM7:FEBB find_last_available_object_idx:
ROM7:FEBB LDY #12 ; 12 objects
 
ROM7:FEBC check_next_object:
ROM7:FEBC DEY
ROM7:FEBD BEQ no_available_slots
ROM7:FEBE LDA object_type,Y ; load to see if this slot is empty
ROM7:FEBF BNE check_next_object ; skip if 0 (no object)
ROM7:FEC0 STY tmp_result
 
ROM7:FEC1 no_available_slots: ; Caller does BEQ to jump if no slot was available.
ROM7:FEC1 CPY #0
ROM7:FEC2 RTS
 
Subroutine spawn_default
ROM7:FECA spawn_default:
ROM7:FECA LDA #EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink
ROM7:FECB STA enemy_properties,X ; Set to EnemyProperties_SkipAutomaticUpdate|EnemyProperties_ReverseDirectionAfterHittingLink.
ROM7:FECC BNE spawn_monster_no_timer_no_spawn_cloud
 
ROM7:FED1 spawn_recorder_pond_daemon:
ROM7:FED1 LDA #1
ROM7:FED2 STA recorder_lake_state ; Set to 0x01
 
ROM7:FED6 spawn_monster_no_timer_no_spawn_cloud:
ROM7:FED6 LDA #0
ROM7:FED7 STA enemy_action_timers,X ; Set to 0x00
 
ROM7:FEDA set_enemy_spawn_state_to_spawned: ; Set enemy_spawn_state[X] = 0, which is spawned and not dead or in a spawn cloud.
ROM7:FEDA LDA #0
ROM7:FEDB STA enemy_spawn_state,X ; Set to 0 (no spawn cloud)
ROM7:FEDC RTS
 
ROM7:FEE0 ppu_recorder_lake_palette_shift: .BYTE $3F
ROM7:FEE1   .BYTE $C
ROM7:FEE2   .BYTE 4
ROM7:FEE3   .BYTE $F
ROM7:FEE4   .BYTE $17
ROM7:FEE5   .BYTE $37
ROM7:FEE6   .BYTE $12
ROM7:FEE7   .BYTE $FF
ROM7:FEE8 ppu_recorder_lake_palette_shift_colors: .BYTE $12
ROM7:FEE9   .BYTE $11
ROM7:FEEA   .BYTE $22
ROM7:FEEB   .BYTE $21
ROM7:FEEC   .BYTE $31
ROM7:FEED   .BYTE $32
ROM7:FEEE   .BYTE $33
ROM7:FEEF   .BYTE $35
ROM7:FEF0   .BYTE $34
ROM7:FEF1   .BYTE $36
ROM7:FEF2   .BYTE $37
ROM7:FEF3   .BYTE $37
 
Subroutine update_recorder_pond_daemon
ROM7:FEF4 update_recorder_pond_daemon:
 
ROM7:FEF4 LDY recorder_lake_state ; 0 = closed, 0x01-0x0B=lake palette shift, 0x0C=open
ROM7:FEF5 CPY #$C
ROM7:FEF6 BCS locret_1FF28 ; Skip if the lake is already open.
ROM7:FEF7 LDA frame_counter
ROM7:FEF8 AND #7
ROM7:FEF9 CMP #4 ; Advance every 8 frames
ROM7:FEFA BNE locret_1FF28
ROM7:FEFB INC recorder_lake_state ; Advance the lake state
ROM7:FEFC CPY #$B
ROM7:FEFD BEQ move_into_position
 
ROM7:FF0A loc_1FF0A: ; A = whistle lake status (before we incremented it)
ROM7:FF0A TYA
ROM7:FF0B PHA ; Push A
ROM7:FF0C LDY #7
 
ROM7:FF0D loop: ; Copy the command to shift the lake palette
ROM7:FF0D LDA ppu_recorder_lake_palette_shift,Y
ROM7:FF0E STA ppu_command_buffer,Y
ROM7:FF0F DEY
ROM7:FF10 BPL loop
ROM7:FF11 PLA ; Pop A (whistle lake status)
ROM7:FF12 TAY
ROM7:FF13 LDA ppu_recorder_lake_palette_shift_colors,Y ; Copy the current lake palette color into the PPU command
ROM7:FF14 STA ppu_command_buffer_06
ROM7:FF15 CPY #$A
ROM7:FF16 BNE locret_1FF28
ROM7:FF17 LDA #$99
ROM7:FF18 STA screen_first_solid_tile_id ; Set to 0x99
 
ROM7:FF28 locret_1FF28:
ROM7:FF28 RTS
 
Function chunk for update_recorder_pond_daemon
ROM7:FF29 move_into_position:
ROM7:FF29 LDA #$60
ROM7:FF2A STA object_x,X
ROM7:FF2B LDA #$90
ROM7:FF2C STA object_y,X
ROM7:FF2D JMP handle_recorder_lake_door
 
Function chunk for task0_Scrolling_0
ROM7:FF34 loc_1FF34:
ROM7:FF34 LDA frame_counter
ROM7:FF35 AND #4
ROM7:FF36 BEQ locret_1FF28
ROM7:FF37 DEC recorder_lake_state ; 0 = closed, 0x01-0x0B=lake palette shift, 0x0C=open
ROM7:FF38 LDY recorder_lake_state ; 0 = closed, 0x01-0x0B=lake palette shift, 0x0C=open
ROM7:FF39 JMP loc_1FF0A ; A = whistle lake status (before we incremented it)
 
ROM7:FF3A   .BYTE $FF
ROM7:FF3B   .BYTE $FF
ROM7:FF3C   .BYTE $FF
ROM7:FF3D   .BYTE $FF
ROM7:FF3E   .BYTE $FF
ROM7:FF3F   .BYTE $FF
ROM7:FF40   .BYTE $FF
ROM7:FF41   .BYTE $FF
ROM7:FF42   .BYTE $FF
ROM7:FF43   .BYTE $FF
ROM7:FF44   .BYTE $FF
ROM7:FF45   .BYTE $FF
ROM7:FF46   .BYTE $FF
 
Subroutine OnReset
; This is the initial entry point. It also comes back ; here to do a complete reset after the end credits finish. ; ; This only does basic bootstrapping. The main entry point ; for frame updates is OnNMI.
ROM7:FF50 OnReset:
 
ROM7:FF50 SEI
ROM7:FF51 CLD
ROM7:FF52 LDA #0
ROM7:FF53 STA PPUCTRL
ROM7:FF54 LDX #$FF
ROM7:FF55 TXS
 
ROM7:FF5A initial_vsync_1:
ROM7:FF5A LDA PPUSTATUS
ROM7:FF5B AND #$80
ROM7:FF5C BEQ initial_vsync_1
 
ROM7:FF61 initial_vsync_2:
ROM7:FF61 LDA PPUSTATUS
ROM7:FF62 AND #$80
ROM7:FF63 BEQ initial_vsync_2
ROM7:FF64 ORA #$FF
ROM7:FF65 STA rom2_sprite_data_ptrs ; Reset the MMC1.
ROM7:FF66 STA ppu_command_table ; 0x00
ROM7:FF67 STA byte_1C000
ROM7:FF68 STA byte_1E000
ROM7:FF69 LDA #$F
ROM7:FF6A JSR set_mmc_control_register
ROM7:FF6B LDA #0
ROM7:FF6C STA ppu_command_table ; Set chr bank 0 to 0
ROM7:FF6D LSR A
ROM7:FF6E STA ppu_command_table ; 0x00
ROM7:FF6F LSR A
ROM7:FF70 STA ppu_command_table ; 0x00
ROM7:FF71 LSR A
ROM7:FF72 STA ppu_command_table ; 0x00
ROM7:FF73 LSR A
ROM7:FF74 STA ppu_command_table ; 0x00
ROM7:FF75 LDA #7
ROM7:FF76 JSR set_prg_bank ; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FF77 JMP continue_setup
 
Subroutine set_mmc_control_register
ROM7:FF98 set_mmc_control_register:
ROM7:FF98 STA rom2_sprite_data_ptrs
ROM7:FF99 LSR A
ROM7:FF9A STA rom2_sprite_data_ptrs
ROM7:FF9B LSR A
ROM7:FF9C STA rom2_sprite_data_ptrs
ROM7:FF9D LSR A
ROM7:FF9E STA rom2_sprite_data_ptrs
ROM7:FF9F LSR A
ROM7:FFA0 STA rom2_sprite_data_ptrs
ROM7:FFA1 RTS
 
Subroutine set_prg_bank
; Map the ROM bank specified in A to $8000-$BFFF.
ROM7:FFAC set_prg_bank:
ROM7:FFAC STA $E000
ROM7:FFAD LSR A
ROM7:FFAE STA $E000
ROM7:FFAF LSR A
ROM7:FFB0 STA $E000
ROM7:FFB1 LSR A
ROM7:FFB2 STA $E000
ROM7:FFB3 LSR A
ROM7:FFB4 STA $E000
ROM7:FFB5 RTS
 
ROM7:FFB6 Skipped empty chunk
ROM7:FFF0 OnIRQ: .BYTE $E0
ROM7:FFF1   .BYTE $76
ROM7:FFF2   .BYTE 0
ROM7:FFF3   .BYTE 0
ROM7:FFF4   .BYTE $38
ROM7:FFF5   .BYTE 4
ROM7:FFF6   .BYTE 1
ROM7:FFF7   .BYTE 4
ROM7:FFF8   .BYTE 1
ROM7:FFF9   .BYTE $BE
ROM7:FFFA OnNMIVec: .WORD OnNMI
ROM7:FFFC OnResetVec: .WORD OnReset ; This is the initial entry point. It also comes back
  ; here to do a complete reset after the end credits finish.
 
  ; This only does basic bootstrapping. The main entry point
  ; for frame updates is OnNMI.
ROM7:FFFE OnIRQVec: .WORD OnIRQ
 
Segment: SRAM
SRAM:6000  
SRAM:6001 sram_check_byte:
SRAM:6002 byte_26002:
SRAM:6003  
SRAM:6004  
SRAM:6005  
SRAM:6006  
SRAM:6007  
SRAM:6008  
SRAM:6009  
SRAM:600A byte_2600A:
SRAM:600B  
SRAM:600C  
SRAM:600D  
SRAM:600E  
SRAM:600F  
SRAM:6010  
SRAM:6011  
SRAM:6012 byte_26012:
SRAM:6013  
SRAM:6014  
SRAM:6015  
SRAM:6016  
SRAM:6017  
SRAM:6018  
SRAM:6019  
SRAM:601A byte_2601A:
SRAM:601B  
SRAM:601C  
SRAM:601D  
SRAM:601E  
SRAM:601F  
SRAM:6020  
SRAM:6021  
SRAM:6022  
SRAM:6023  
SRAM:6024  
SRAM:6025  
SRAM:6026  
SRAM:6027  
SRAM:6028  
SRAM:6029  
SRAM:602A  
SRAM:602B  
SRAM:602C  
SRAM:602D  
SRAM:602E  
SRAM:602F  
SRAM:6030  
SRAM:6031  
SRAM:6032  
SRAM:6033  
SRAM:6034  
SRAM:6035  
SRAM:6036  
SRAM:6037  
SRAM:6038  
SRAM:6039  
SRAM:603A  
SRAM:603B  
SRAM:603C  
SRAM:603D  
SRAM:603E  
SRAM:603F  
SRAM:6040  
SRAM:6041  
SRAM:6042 byte_26042:
SRAM:6043  
SRAM:6044  
SRAM:6045  
SRAM:6046  
SRAM:6047  
SRAM:6048  
SRAM:6049  
SRAM:604A  
SRAM:604B  
SRAM:604C  
SRAM:604D  
SRAM:604E  
SRAM:604F  
SRAM:6050  
SRAM:6051  
SRAM:6052  
SRAM:6053  
SRAM:6054  
SRAM:6055  
SRAM:6056  
SRAM:6057  
SRAM:6058  
SRAM:6059  
SRAM:605A  
SRAM:605B  
SRAM:605C  
SRAM:605D  
SRAM:605E  
SRAM:605F  
SRAM:6060  
SRAM:6061  
SRAM:6062  
SRAM:6063  
SRAM:6064  
SRAM:6065  
SRAM:6066  
SRAM:6067  
SRAM:6068  
SRAM:6069  
SRAM:606A byte_2606A:
SRAM:606B  
SRAM:606C  
SRAM:606D  
SRAM:606E  
SRAM:606F  
SRAM:6070  
SRAM:6071  
SRAM:6072  
SRAM:6073  
SRAM:6074  
SRAM:6075  
SRAM:6076  
SRAM:6077  
SRAM:6078  
SRAM:6079  
SRAM:607A  
SRAM:607B  
SRAM:607C  
SRAM:607D  
SRAM:607E  
SRAM:607F  
SRAM:6080  
SRAM:6081  
SRAM:6082  
SRAM:6083  
SRAM:6084  
SRAM:6085  
SRAM:6086  
SRAM:6087  
SRAM:6088  
SRAM:6089  
SRAM:608A  
SRAM:608B  
SRAM:608C  
SRAM:608D  
SRAM:608E  
SRAM:608F  
SRAM:6090  
SRAM:6091  
SRAM:6092 byte_26092:
SRAM:6093  
SRAM:6094  
SRAM:6095  
SRAM:6096  
SRAM:6097  
SRAM:6098  
SRAM:6099  
SRAM:609A  
SRAM:609B  
SRAM:609C  
SRAM:609D  
SRAM:609E  
SRAM:609F  
SRAM:60A0  
SRAM:60A1  
SRAM:60A2  
SRAM:60A3  
SRAM:60A4  
SRAM:60A5  
SRAM:60A6  
SRAM:60A7  
SRAM:60A8  
SRAM:60A9  
SRAM:60AA  
SRAM:60AB  
SRAM:60AC  
SRAM:60AD  
SRAM:60AE  
SRAM:60AF  
SRAM:60B0  
SRAM:60B1  
SRAM:60B2  
SRAM:60B3  
SRAM:60B4  
SRAM:60B5  
SRAM:60B6  
SRAM:60B7  
SRAM:60B8  
SRAM:60B9  
SRAM:60BA  
SRAM:60BB  
SRAM:60BC  
SRAM:60BD  
SRAM:60BE  
SRAM:60BF  
SRAM:60C0  
SRAM:60C1  
SRAM:60C2  
SRAM:60C3  
SRAM:60C4  
SRAM:60C5  
SRAM:60C6  
SRAM:60C7  
SRAM:60C8  
SRAM:60C9  
SRAM:60CA  
SRAM:60CB  
SRAM:60CC  
SRAM:60CD  
SRAM:60CE  
SRAM:60CF  
SRAM:60D0  
SRAM:60D1  
SRAM:60D2  
SRAM:60D3  
SRAM:60D4  
SRAM:60D5  
SRAM:60D6  
SRAM:60D7  
SRAM:60D8  
SRAM:60D9  
SRAM:60DA  
SRAM:60DB  
SRAM:60DC  
SRAM:60DD  
SRAM:60DE  
SRAM:60DF  
SRAM:60E0  
SRAM:60E1  
SRAM:60E2  
SRAM:60E3  
SRAM:60E4  
SRAM:60E5  
SRAM:60E6  
SRAM:60E7  
SRAM:60E8  
SRAM:60E9  
SRAM:60EA  
SRAM:60EB  
SRAM:60EC  
SRAM:60ED  
SRAM:60EE  
SRAM:60EF  
SRAM:60F0  
SRAM:60F1  
SRAM:60F2  
SRAM:60F3  
SRAM:60F4  
SRAM:60F5  
SRAM:60F6  
SRAM:60F7  
SRAM:60F8  
SRAM:60F9  
SRAM:60FA  
SRAM:60FB  
SRAM:60FC  
SRAM:60FD  
SRAM:60FE  
SRAM:60FF  
SRAM:6100  
SRAM:6101  
SRAM:6102  
SRAM:6103  
SRAM:6104  
SRAM:6105  
SRAM:6106  
SRAM:6107  
SRAM:6108  
SRAM:6109  
SRAM:610A  
SRAM:610B  
SRAM:610C  
SRAM:610D  
SRAM:610E  
SRAM:610F  
SRAM:6110  
SRAM:6111  
SRAM:6112  
SRAM:6113  
SRAM:6114  
SRAM:6115  
SRAM:6116  
SRAM:6117  
SRAM:6118  
SRAM:6119  
SRAM:611A  
SRAM:611B  
SRAM:611C  
SRAM:611D  
SRAM:611E  
SRAM:611F  
SRAM:6120  
SRAM:6121  
SRAM:6122  
SRAM:6123  
SRAM:6124  
SRAM:6125  
SRAM:6126  
SRAM:6127  
SRAM:6128  
SRAM:6129  
SRAM:612A  
SRAM:612B  
SRAM:612C  
SRAM:612D  
SRAM:612E  
SRAM:612F  
SRAM:6130  
SRAM:6131  
SRAM:6132  
SRAM:6133  
SRAM:6134  
SRAM:6135  
SRAM:6136  
SRAM:6137  
SRAM:6138  
SRAM:6139  
SRAM:613A  
SRAM:613B  
SRAM:613C  
SRAM:613D  
SRAM:613E  
SRAM:613F  
SRAM:6140  
SRAM:6141  
SRAM:6142  
SRAM:6143  
SRAM:6144  
SRAM:6145  
SRAM:6146  
SRAM:6147  
SRAM:6148  
SRAM:6149  
SRAM:614A  
SRAM:614B  
SRAM:614C  
SRAM:614D  
SRAM:614E  
SRAM:614F  
SRAM:6150  
SRAM:6151  
SRAM:6152  
SRAM:6153  
SRAM:6154  
SRAM:6155  
SRAM:6156  
SRAM:6157  
SRAM:6158  
SRAM:6159  
SRAM:615A  
SRAM:615B  
SRAM:615C  
SRAM:615D  
SRAM:615E  
SRAM:615F  
SRAM:6160  
SRAM:6161  
SRAM:6162  
SRAM:6163  
SRAM:6164  
SRAM:6165  
SRAM:6166  
SRAM:6167  
SRAM:6168  
SRAM:6169  
SRAM:616A  
SRAM:616B  
SRAM:616C  
SRAM:616D  
SRAM:616E  
SRAM:616F  
SRAM:6170  
SRAM:6171  
SRAM:6172  
SRAM:6173  
SRAM:6174  
SRAM:6175  
SRAM:6176  
SRAM:6177  
SRAM:6178  
SRAM:6179  
SRAM:617A  
SRAM:617B  
SRAM:617C  
SRAM:617D  
SRAM:617E  
SRAM:617F  
SRAM:6180  
SRAM:6181  
SRAM:6182  
SRAM:6183  
SRAM:6184  
SRAM:6185  
SRAM:6186  
SRAM:6187  
SRAM:6188  
SRAM:6189  
SRAM:618A  
SRAM:618B  
SRAM:618C  
SRAM:618D  
SRAM:618E  
SRAM:618F  
SRAM:6190  
SRAM:6191  
SRAM:6192  
SRAM:6193  
SRAM:6194  
SRAM:6195  
SRAM:6196  
SRAM:6197  
SRAM:6198  
SRAM:6199  
SRAM:619A  
SRAM:619B  
SRAM:619C  
SRAM:619D  
SRAM:619E  
SRAM:619F  
SRAM:61A0  
SRAM:61A1  
SRAM:61A2  
SRAM:61A3  
SRAM:61A4  
SRAM:61A5  
SRAM:61A6  
SRAM:61A7  
SRAM:61A8  
SRAM:61A9  
SRAM:61AA  
SRAM:61AB  
SRAM:61AC  
SRAM:61AD  
SRAM:61AE  
SRAM:61AF  
SRAM:61B0  
SRAM:61B1  
SRAM:61B2  
SRAM:61B3  
SRAM:61B4  
SRAM:61B5  
SRAM:61B6  
SRAM:61B7  
SRAM:61B8  
SRAM:61B9  
SRAM:61BA  
SRAM:61BB  
SRAM:61BC  
SRAM:61BD  
SRAM:61BE  
SRAM:61BF  
SRAM:61C0  
SRAM:61C1  
SRAM:61C2  
SRAM:61C3  
SRAM:61C4  
SRAM:61C5  
SRAM:61C6  
SRAM:61C7  
SRAM:61C8  
SRAM:61C9  
SRAM:61CA  
SRAM:61CB  
SRAM:61CC  
SRAM:61CD  
SRAM:61CE  
SRAM:61CF  
SRAM:61D0  
SRAM:61D1  
SRAM:61D2  
SRAM:61D3  
SRAM:61D4  
SRAM:61D5  
SRAM:61D6  
SRAM:61D7  
SRAM:61D8  
SRAM:61D9  
SRAM:61DA  
SRAM:61DB  
SRAM:61DC  
SRAM:61DD  
SRAM:61DE  
SRAM:61DF  
SRAM:61E0  
SRAM:61E1  
SRAM:61E2  
SRAM:61E3  
SRAM:61E4  
SRAM:61E5  
SRAM:61E6  
SRAM:61E7  
SRAM:61E8  
SRAM:61E9  
SRAM:61EA  
SRAM:61EB  
SRAM:61EC  
SRAM:61ED  
SRAM:61EE  
SRAM:61EF  
SRAM:61F0  
SRAM:61F1  
SRAM:61F2  
SRAM:61F3  
SRAM:61F4  
SRAM:61F5  
SRAM:61F6  
SRAM:61F7  
SRAM:61F8  
SRAM:61F9  
SRAM:61FA  
SRAM:61FB  
SRAM:61FC  
SRAM:61FD  
SRAM:61FE  
SRAM:61FF  
SRAM:6200  
SRAM:6201  
SRAM:6202  
SRAM:6203  
SRAM:6204  
SRAM:6205  
SRAM:6206  
SRAM:6207  
SRAM:6208  
SRAM:6209  
SRAM:620A  
SRAM:620B  
SRAM:620C  
SRAM:620D  
SRAM:620E  
SRAM:620F  
SRAM:6210  
SRAM:6211  
SRAM:6212 byte_26212:
SRAM:6213  
SRAM:6214  
SRAM:6215  
SRAM:6216  
SRAM:6217  
SRAM:6218  
SRAM:6219  
SRAM:621A  
SRAM:621B  
SRAM:621C  
SRAM:621D  
SRAM:621E  
SRAM:621F  
SRAM:6220  
SRAM:6221  
SRAM:6222  
SRAM:6223  
SRAM:6224  
SRAM:6225  
SRAM:6226  
SRAM:6227  
SRAM:6228  
SRAM:6229  
SRAM:622A  
SRAM:622B  
SRAM:622C  
SRAM:622D  
SRAM:622E  
SRAM:622F  
SRAM:6230  
SRAM:6231  
SRAM:6232  
SRAM:6233  
SRAM:6234  
SRAM:6235  
SRAM:6236  
SRAM:6237  
SRAM:6238  
SRAM:6239  
SRAM:623A  
SRAM:623B  
SRAM:623C  
SRAM:623D  
SRAM:623E  
SRAM:623F  
SRAM:6240  
SRAM:6241  
SRAM:6242  
SRAM:6243  
SRAM:6244  
SRAM:6245  
SRAM:6246  
SRAM:6247  
SRAM:6248  
SRAM:6249  
SRAM:624A  
SRAM:624B  
SRAM:624C  
SRAM:624D  
SRAM:624E  
SRAM:624F  
SRAM:6250  
SRAM:6251  
SRAM:6252  
SRAM:6253  
SRAM:6254  
SRAM:6255  
SRAM:6256  
SRAM:6257  
SRAM:6258  
SRAM:6259  
SRAM:625A  
SRAM:625B  
SRAM:625C  
SRAM:625D  
SRAM:625E  
SRAM:625F  
SRAM:6260  
SRAM:6261  
SRAM:6262  
SRAM:6263  
SRAM:6264  
SRAM:6265  
SRAM:6266  
SRAM:6267  
SRAM:6268  
SRAM:6269  
SRAM:626A  
SRAM:626B  
SRAM:626C  
SRAM:626D  
SRAM:626E  
SRAM:626F  
SRAM:6270  
SRAM:6271  
SRAM:6272  
SRAM:6273  
SRAM:6274  
SRAM:6275  
SRAM:6276  
SRAM:6277  
SRAM:6278  
SRAM:6279  
SRAM:627A  
SRAM:627B  
SRAM:627C  
SRAM:627D  
SRAM:627E  
SRAM:627F  
SRAM:6280  
SRAM:6281  
SRAM:6282  
SRAM:6283  
SRAM:6284  
SRAM:6285  
SRAM:6286  
SRAM:6287  
SRAM:6288  
SRAM:6289  
SRAM:628A  
SRAM:628B  
SRAM:628C  
SRAM:628D  
SRAM:628E  
SRAM:628F  
SRAM:6290  
SRAM:6291  
SRAM:6292  
SRAM:6293  
SRAM:6294  
SRAM:6295  
SRAM:6296  
SRAM:6297  
SRAM:6298  
SRAM:6299  
SRAM:629A  
SRAM:629B  
SRAM:629C  
SRAM:629D  
SRAM:629E  
SRAM:629F  
SRAM:62A0  
SRAM:62A1  
SRAM:62A2  
SRAM:62A3  
SRAM:62A4  
SRAM:62A5  
SRAM:62A6  
SRAM:62A7  
SRAM:62A8  
SRAM:62A9  
SRAM:62AA  
SRAM:62AB  
SRAM:62AC  
SRAM:62AD  
SRAM:62AE  
SRAM:62AF  
SRAM:62B0  
SRAM:62B1  
SRAM:62B2  
SRAM:62B3  
SRAM:62B4  
SRAM:62B5  
SRAM:62B6  
SRAM:62B7  
SRAM:62B8  
SRAM:62B9  
SRAM:62BA  
SRAM:62BB  
SRAM:62BC  
SRAM:62BD  
SRAM:62BE  
SRAM:62BF  
SRAM:62C0  
SRAM:62C1  
SRAM:62C2  
SRAM:62C3  
SRAM:62C4  
SRAM:62C5  
SRAM:62C6  
SRAM:62C7  
SRAM:62C8  
SRAM:62C9  
SRAM:62CA  
SRAM:62CB  
SRAM:62CC  
SRAM:62CD  
SRAM:62CE  
SRAM:62CF  
SRAM:62D0  
SRAM:62D1  
SRAM:62D2  
SRAM:62D3  
SRAM:62D4  
SRAM:62D5  
SRAM:62D6  
SRAM:62D7  
SRAM:62D8  
SRAM:62D9  
SRAM:62DA  
SRAM:62DB  
SRAM:62DC  
SRAM:62DD  
SRAM:62DE  
SRAM:62DF  
SRAM:62E0  
SRAM:62E1  
SRAM:62E2  
SRAM:62E3  
SRAM:62E4  
SRAM:62E5  
SRAM:62E6  
SRAM:62E7  
SRAM:62E8  
SRAM:62E9  
SRAM:62EA  
SRAM:62EB  
SRAM:62EC  
SRAM:62ED  
SRAM:62EE  
SRAM:62EF  
SRAM:62F0  
SRAM:62F1  
SRAM:62F2  
SRAM:62F3  
SRAM:62F4  
SRAM:62F5  
SRAM:62F6  
SRAM:62F7  
SRAM:62F8  
SRAM:62F9  
SRAM:62FA  
SRAM:62FB  
SRAM:62FC  
SRAM:62FD  
SRAM:62FE  
SRAM:62FF  
SRAM:6300  
SRAM:6301  
SRAM:6302  
SRAM:6303  
SRAM:6304  
SRAM:6305  
SRAM:6306  
SRAM:6307  
SRAM:6308  
SRAM:6309  
SRAM:630A  
SRAM:630B  
SRAM:630C  
SRAM:630D  
SRAM:630E  
SRAM:630F  
SRAM:6310  
SRAM:6311  
SRAM:6312  
SRAM:6313  
SRAM:6314  
SRAM:6315  
SRAM:6316  
SRAM:6317  
SRAM:6318  
SRAM:6319  
SRAM:631A  
SRAM:631B  
SRAM:631C  
SRAM:631D  
SRAM:631E  
SRAM:631F  
SRAM:6320  
SRAM:6321  
SRAM:6322  
SRAM:6323  
SRAM:6324  
SRAM:6325  
SRAM:6326  
SRAM:6327  
SRAM:6328  
SRAM:6329  
SRAM:632A  
SRAM:632B  
SRAM:632C  
SRAM:632D  
SRAM:632E  
SRAM:632F  
SRAM:6330  
SRAM:6331  
SRAM:6332  
SRAM:6333  
SRAM:6334  
SRAM:6335  
SRAM:6336  
SRAM:6337  
SRAM:6338  
SRAM:6339  
SRAM:633A  
SRAM:633B  
SRAM:633C  
SRAM:633D  
SRAM:633E  
SRAM:633F  
SRAM:6340  
SRAM:6341  
SRAM:6342  
SRAM:6343  
SRAM:6344  
SRAM:6345  
SRAM:6346  
SRAM:6347  
SRAM:6348  
SRAM:6349  
SRAM:634A  
SRAM:634B  
SRAM:634C  
SRAM:634D  
SRAM:634E  
SRAM:634F  
SRAM:6350  
SRAM:6351  
SRAM:6352  
SRAM:6353  
SRAM:6354  
SRAM:6355  
SRAM:6356  
SRAM:6357  
SRAM:6358  
SRAM:6359  
SRAM:635A  
SRAM:635B  
SRAM:635C  
SRAM:635D  
SRAM:635E  
SRAM:635F  
SRAM:6360  
SRAM:6361  
SRAM:6362  
SRAM:6363  
SRAM:6364  
SRAM:6365  
SRAM:6366  
SRAM:6367  
SRAM:6368  
SRAM:6369  
SRAM:636A  
SRAM:636B  
SRAM:636C  
SRAM:636D  
SRAM:636E  
SRAM:636F  
SRAM:6370  
SRAM:6371  
SRAM:6372  
SRAM:6373  
SRAM:6374  
SRAM:6375  
SRAM:6376  
SRAM:6377  
SRAM:6378  
SRAM:6379  
SRAM:637A  
SRAM:637B  
SRAM:637C  
SRAM:637D  
SRAM:637E  
SRAM:637F  
SRAM:6380  
SRAM:6381  
SRAM:6382  
SRAM:6383  
SRAM:6384  
SRAM:6385  
SRAM:6386  
SRAM:6387  
SRAM:6388  
SRAM:6389  
SRAM:638A  
SRAM:638B  
SRAM:638C  
SRAM:638D  
SRAM:638E  
SRAM:638F  
SRAM:6390  
SRAM:6391  
SRAM:6392 byte_26392:
SRAM:6393  
SRAM:6394  
SRAM:6395  
SRAM:6396  
SRAM:6397  
SRAM:6398  
SRAM:6399  
SRAM:639A  
SRAM:639B  
SRAM:639C  
SRAM:639D  
SRAM:639E  
SRAM:639F  
SRAM:63A0  
SRAM:63A1  
SRAM:63A2  
SRAM:63A3  
SRAM:63A4  
SRAM:63A5  
SRAM:63A6  
SRAM:63A7  
SRAM:63A8  
SRAM:63A9  
SRAM:63AA  
SRAM:63AB  
SRAM:63AC  
SRAM:63AD  
SRAM:63AE  
SRAM:63AF  
SRAM:63B0  
SRAM:63B1  
SRAM:63B2  
SRAM:63B3  
SRAM:63B4  
SRAM:63B5  
SRAM:63B6  
SRAM:63B7  
SRAM:63B8  
SRAM:63B9  
SRAM:63BA  
SRAM:63BB  
SRAM:63BC  
SRAM:63BD  
SRAM:63BE  
SRAM:63BF  
SRAM:63C0  
SRAM:63C1  
SRAM:63C2  
SRAM:63C3  
SRAM:63C4  
SRAM:63C5  
SRAM:63C6  
SRAM:63C7  
SRAM:63C8  
SRAM:63C9  
SRAM:63CA  
SRAM:63CB  
SRAM:63CC  
SRAM:63CD  
SRAM:63CE  
SRAM:63CF  
SRAM:63D0  
SRAM:63D1  
SRAM:63D2  
SRAM:63D3  
SRAM:63D4  
SRAM:63D5  
SRAM:63D6  
SRAM:63D7  
SRAM:63D8  
SRAM:63D9  
SRAM:63DA  
SRAM:63DB  
SRAM:63DC  
SRAM:63DD  
SRAM:63DE  
SRAM:63DF  
SRAM:63E0  
SRAM:63E1  
SRAM:63E2  
SRAM:63E3  
SRAM:63E4  
SRAM:63E5  
SRAM:63E6  
SRAM:63E7  
SRAM:63E8  
SRAM:63E9  
SRAM:63EA  
SRAM:63EB  
SRAM:63EC  
SRAM:63ED  
SRAM:63EE  
SRAM:63EF  
SRAM:63F0  
SRAM:63F1  
SRAM:63F2  
SRAM:63F3  
SRAM:63F4  
SRAM:63F5  
SRAM:63F6  
SRAM:63F7  
SRAM:63F8  
SRAM:63F9  
SRAM:63FA  
SRAM:63FB  
SRAM:63FC  
SRAM:63FD  
SRAM:63FE  
SRAM:63FF  
SRAM:6400  
SRAM:6401  
SRAM:6402  
SRAM:6403  
SRAM:6404  
SRAM:6405  
SRAM:6406  
SRAM:6407  
SRAM:6408  
SRAM:6409  
SRAM:640A  
SRAM:640B  
SRAM:640C  
SRAM:640D  
SRAM:640E  
SRAM:640F  
SRAM:6410  
SRAM:6411  
SRAM:6412  
SRAM:6413  
SRAM:6414  
SRAM:6415  
SRAM:6416  
SRAM:6417  
SRAM:6418  
SRAM:6419  
SRAM:641A  
SRAM:641B  
SRAM:641C  
SRAM:641D  
SRAM:641E  
SRAM:641F  
SRAM:6420  
SRAM:6421  
SRAM:6422  
SRAM:6423  
SRAM:6424  
SRAM:6425  
SRAM:6426  
SRAM:6427  
SRAM:6428  
SRAM:6429  
SRAM:642A  
SRAM:642B  
SRAM:642C  
SRAM:642D  
SRAM:642E  
SRAM:642F  
SRAM:6430  
SRAM:6431  
SRAM:6432  
SRAM:6433  
SRAM:6434  
SRAM:6435  
SRAM:6436  
SRAM:6437  
SRAM:6438  
SRAM:6439  
SRAM:643A  
SRAM:643B  
SRAM:643C  
SRAM:643D  
SRAM:643E  
SRAM:643F  
SRAM:6440  
SRAM:6441  
SRAM:6442  
SRAM:6443  
SRAM:6444  
SRAM:6445  
SRAM:6446  
SRAM:6447  
SRAM:6448  
SRAM:6449  
SRAM:644A  
SRAM:644B  
SRAM:644C  
SRAM:644D  
SRAM:644E  
SRAM:644F  
SRAM:6450  
SRAM:6451  
SRAM:6452  
SRAM:6453  
SRAM:6454  
SRAM:6455  
SRAM:6456  
SRAM:6457  
SRAM:6458  
SRAM:6459  
SRAM:645A  
SRAM:645B  
SRAM:645C  
SRAM:645D  
SRAM:645E  
SRAM:645F  
SRAM:6460  
SRAM:6461  
SRAM:6462  
SRAM:6463  
SRAM:6464  
SRAM:6465  
SRAM:6466  
SRAM:6467  
SRAM:6468  
SRAM:6469  
SRAM:646A  
SRAM:646B  
SRAM:646C  
SRAM:646D  
SRAM:646E  
SRAM:646F  
SRAM:6470  
SRAM:6471  
SRAM:6472  
SRAM:6473  
SRAM:6474  
SRAM:6475  
SRAM:6476  
SRAM:6477  
SRAM:6478  
SRAM:6479  
SRAM:647A  
SRAM:647B  
SRAM:647C  
SRAM:647D  
SRAM:647E  
SRAM:647F  
SRAM:6480  
SRAM:6481  
SRAM:6482  
SRAM:6483  
SRAM:6484  
SRAM:6485  
SRAM:6486  
SRAM:6487  
SRAM:6488  
SRAM:6489  
SRAM:648A  
SRAM:648B  
SRAM:648C  
SRAM:648D  
SRAM:648E  
SRAM:648F  
SRAM:6490  
SRAM:6491  
SRAM:6492  
SRAM:6493  
SRAM:6494  
SRAM:6495  
SRAM:6496  
SRAM:6497  
SRAM:6498  
SRAM:6499  
SRAM:649A  
SRAM:649B  
SRAM:649C  
SRAM:649D  
SRAM:649E  
SRAM:649F  
SRAM:64A0  
SRAM:64A1  
SRAM:64A2  
SRAM:64A3  
SRAM:64A4  
SRAM:64A5  
SRAM:64A6  
SRAM:64A7  
SRAM:64A8  
SRAM:64A9  
SRAM:64AA  
SRAM:64AB  
SRAM:64AC  
SRAM:64AD  
SRAM:64AE  
SRAM:64AF  
SRAM:64B0  
SRAM:64B1  
SRAM:64B2  
SRAM:64B3  
SRAM:64B4  
SRAM:64B5  
SRAM:64B6  
SRAM:64B7  
SRAM:64B8  
SRAM:64B9  
SRAM:64BA  
SRAM:64BB  
SRAM:64BC  
SRAM:64BD  
SRAM:64BE  
SRAM:64BF  
SRAM:64C0  
SRAM:64C1  
SRAM:64C2  
SRAM:64C3  
SRAM:64C4  
SRAM:64C5  
SRAM:64C6  
SRAM:64C7  
SRAM:64C8  
SRAM:64C9  
SRAM:64CA  
SRAM:64CB  
SRAM:64CC  
SRAM:64CD  
SRAM:64CE  
SRAM:64CF  
SRAM:64D0  
SRAM:64D1  
SRAM:64D2  
SRAM:64D3  
SRAM:64D4  
SRAM:64D5  
SRAM:64D6  
SRAM:64D7  
SRAM:64D8  
SRAM:64D9  
SRAM:64DA  
SRAM:64DB  
SRAM:64DC  
SRAM:64DD  
SRAM:64DE  
SRAM:64DF  
SRAM:64E0  
SRAM:64E1  
SRAM:64E2  
SRAM:64E3  
SRAM:64E4  
SRAM:64E5  
SRAM:64E6  
SRAM:64E7  
SRAM:64E8  
SRAM:64E9  
SRAM:64EA  
SRAM:64EB  
SRAM:64EC  
SRAM:64ED  
SRAM:64EE  
SRAM:64EF  
SRAM:64F0  
SRAM:64F1  
SRAM:64F2  
SRAM:64F3  
SRAM:64F4  
SRAM:64F5  
SRAM:64F6  
SRAM:64F7  
SRAM:64F8  
SRAM:64F9  
SRAM:64FA  
SRAM:64FB  
SRAM:64FC  
SRAM:64FD  
SRAM:64FE  
SRAM:64FF  
SRAM:6500  
SRAM:6501  
SRAM:6502  
SRAM:6503  
SRAM:6504  
SRAM:6505  
SRAM:6506  
SRAM:6507  
SRAM:6508  
SRAM:6509  
SRAM:650A  
SRAM:650B  
SRAM:650C  
SRAM:650D  
SRAM:650E  
SRAM:650F  
SRAM:6510  
SRAM:6511  
SRAM:6512 byte_26512:
SRAM:6513 byte_26513:
SRAM:6514 byte_26514:
SRAM:6515 byte_26515:
SRAM:6516 byte_26516:
SRAM:6517 byte_26517:
SRAM:6518 byte_26518:
SRAM:6519 byte_26519:
SRAM:651A byte_2651A:
SRAM:651B byte_2651B:
SRAM:651C byte_2651C:
SRAM:651D byte_2651D:
SRAM:651E byte_2651E:
SRAM:651F  
SRAM:6520  
SRAM:6521 byte_26521:
SRAM:6522  
SRAM:6523  
SRAM:6524 byte_26524:
SRAM:6525  
SRAM:6526  
SRAM:6527  
SRAM:6528  
SRAM:6529  
SRAM:652A byte_2652A:
SRAM:652B byte_2652B:
SRAM:652C byte_2652C:
SRAM:652D  
SRAM:652E  
SRAM:652F  
SRAM:6530 room_tiles_x_00:
SRAM:6531  
SRAM:6532  
SRAM:6533  
SRAM:6534  
SRAM:6535  
SRAM:6536  
SRAM:6537  
SRAM:6538  
SRAM:6539  
SRAM:653A  
SRAM:653B  
SRAM:653C  
SRAM:653D  
SRAM:653E  
SRAM:653F  
SRAM:6540  
SRAM:6541  
SRAM:6542  
SRAM:6543  
SRAM:6544  
SRAM:6545  
SRAM:6546 room_tiles_x_01:
SRAM:6547  
SRAM:6548  
SRAM:6549  
SRAM:654A  
SRAM:654B  
SRAM:654C  
SRAM:654D  
SRAM:654E  
SRAM:654F  
SRAM:6550  
SRAM:6551  
SRAM:6552  
SRAM:6553  
SRAM:6554  
SRAM:6555  
SRAM:6556  
SRAM:6557  
SRAM:6558  
SRAM:6559  
SRAM:655A  
SRAM:655B  
SRAM:655C room_tiles_x_02:
SRAM:655D  
SRAM:655E  
SRAM:655F  
SRAM:6560  
SRAM:6561  
SRAM:6562  
SRAM:6563  
SRAM:6564  
SRAM:6565  
SRAM:6566  
SRAM:6567  
SRAM:6568  
SRAM:6569  
SRAM:656A  
SRAM:656B  
SRAM:656C  
SRAM:656D  
SRAM:656E  
SRAM:656F  
SRAM:6570  
SRAM:6571  
SRAM:6572 room_tiles_x_03:
SRAM:6573  
SRAM:6574  
SRAM:6575  
SRAM:6576  
SRAM:6577  
SRAM:6578  
SRAM:6579  
SRAM:657A  
SRAM:657B  
SRAM:657C  
SRAM:657D  
SRAM:657E  
SRAM:657F  
SRAM:6580  
SRAM:6581  
SRAM:6582  
SRAM:6583  
SRAM:6584  
SRAM:6585  
SRAM:6586  
SRAM:6587  
SRAM:6588 room_tiles_x_04:
SRAM:6589  
SRAM:658A  
SRAM:658B  
SRAM:658C  
SRAM:658D  
SRAM:658E  
SRAM:658F  
SRAM:6590  
SRAM:6591  
SRAM:6592  
SRAM:6593  
SRAM:6594  
SRAM:6595  
SRAM:6596  
SRAM:6597  
SRAM:6598  
SRAM:6599  
SRAM:659A  
SRAM:659B  
SRAM:659C  
SRAM:659D  
SRAM:659E room_tiles_x_05:
SRAM:659F  
SRAM:65A0  
SRAM:65A1  
SRAM:65A2  
SRAM:65A3  
SRAM:65A4  
SRAM:65A5  
SRAM:65A6  
SRAM:65A7  
SRAM:65A8  
SRAM:65A9  
SRAM:65AA  
SRAM:65AB  
SRAM:65AC  
SRAM:65AD  
SRAM:65AE  
SRAM:65AF  
SRAM:65B0  
SRAM:65B1  
SRAM:65B2  
SRAM:65B3  
SRAM:65B4 room_tiles_x_06:
SRAM:65B5  
SRAM:65B6  
SRAM:65B7  
SRAM:65B8  
SRAM:65B9  
SRAM:65BA  
SRAM:65BB  
SRAM:65BC  
SRAM:65BD  
SRAM:65BE  
SRAM:65BF  
SRAM:65C0  
SRAM:65C1  
SRAM:65C2  
SRAM:65C3  
SRAM:65C4  
SRAM:65C5  
SRAM:65C6  
SRAM:65C7  
SRAM:65C8  
SRAM:65C9  
SRAM:65CA room_tiles_x_07:
SRAM:65CB  
SRAM:65CC  
SRAM:65CD  
SRAM:65CE  
SRAM:65CF  
SRAM:65D0  
SRAM:65D1  
SRAM:65D2  
SRAM:65D3  
SRAM:65D4  
SRAM:65D5  
SRAM:65D6  
SRAM:65D7  
SRAM:65D8  
SRAM:65D9  
SRAM:65DA  
SRAM:65DB  
SRAM:65DC  
SRAM:65DD  
SRAM:65DE  
SRAM:65DF  
SRAM:65E0 room_tiles_x_08:
SRAM:65E1  
SRAM:65E2  
SRAM:65E3  
SRAM:65E4  
SRAM:65E5  
SRAM:65E6  
SRAM:65E7  
SRAM:65E8  
SRAM:65E9  
SRAM:65EA  
SRAM:65EB  
SRAM:65EC  
SRAM:65ED  
SRAM:65EE  
SRAM:65EF  
SRAM:65F0  
SRAM:65F1  
SRAM:65F2  
SRAM:65F3  
SRAM:65F4  
SRAM:65F5  
SRAM:65F6 room_tiles_x_09:
SRAM:65F7  
SRAM:65F8  
SRAM:65F9  
SRAM:65FA  
SRAM:65FB  
SRAM:65FC  
SRAM:65FD  
SRAM:65FE  
SRAM:65FF  
SRAM:6600  
SRAM:6601  
SRAM:6602  
SRAM:6603  
SRAM:6604  
SRAM:6605  
SRAM:6606  
SRAM:6607  
SRAM:6608  
SRAM:6609  
SRAM:660A  
SRAM:660B  
SRAM:660C room_tiles_x_10:
SRAM:660D  
SRAM:660E  
SRAM:660F  
SRAM:6610  
SRAM:6611  
SRAM:6612  
SRAM:6613  
SRAM:6614  
SRAM:6615  
SRAM:6616  
SRAM:6617  
SRAM:6618  
SRAM:6619  
SRAM:661A  
SRAM:661B  
SRAM:661C  
SRAM:661D  
SRAM:661E  
SRAM:661F  
SRAM:6620  
SRAM:6621  
SRAM:6622 room_tiles_x_11:
SRAM:6623  
SRAM:6624  
SRAM:6625  
SRAM:6626  
SRAM:6627  
SRAM:6628  
SRAM:6629  
SRAM:662A  
SRAM:662B  
SRAM:662C  
SRAM:662D  
SRAM:662E  
SRAM:662F  
SRAM:6630  
SRAM:6631  
SRAM:6632  
SRAM:6633  
SRAM:6634  
SRAM:6635  
SRAM:6636  
SRAM:6637  
SRAM:6638 room_tiles_x_12:
SRAM:6639  
SRAM:663A  
SRAM:663B  
SRAM:663C  
SRAM:663D  
SRAM:663E  
SRAM:663F  
SRAM:6640  
SRAM:6641  
SRAM:6642  
SRAM:6643  
SRAM:6644  
SRAM:6645  
SRAM:6646  
SRAM:6647  
SRAM:6648  
SRAM:6649  
SRAM:664A  
SRAM:664B  
SRAM:664C  
SRAM:664D  
SRAM:664E room_tiles_x_13:
SRAM:664F  
SRAM:6650  
SRAM:6651  
SRAM:6652  
SRAM:6653  
SRAM:6654  
SRAM:6655  
SRAM:6656  
SRAM:6657  
SRAM:6658  
SRAM:6659  
SRAM:665A  
SRAM:665B  
SRAM:665C  
SRAM:665D  
SRAM:665E  
SRAM:665F  
SRAM:6660  
SRAM:6661  
SRAM:6662  
SRAM:6663  
SRAM:6664 room_tiles_x_14:
SRAM:6665  
SRAM:6666  
SRAM:6667  
SRAM:6668  
SRAM:6669  
SRAM:666A  
SRAM:666B  
SRAM:666C  
SRAM:666D  
SRAM:666E  
SRAM:666F  
SRAM:6670  
SRAM:6671  
SRAM:6672  
SRAM:6673  
SRAM:6674  
SRAM:6675  
SRAM:6676  
SRAM:6677  
SRAM:6678  
SRAM:6679  
SRAM:667A room_tiles_x_15:
SRAM:667B  
SRAM:667C  
SRAM:667D  
SRAM:667E  
SRAM:667F  
SRAM:6680  
SRAM:6681  
SRAM:6682  
SRAM:6683  
SRAM:6684  
SRAM:6685  
SRAM:6686  
SRAM:6687  
SRAM:6688  
SRAM:6689  
SRAM:668A  
SRAM:668B  
SRAM:668C  
SRAM:668D  
SRAM:668E  
SRAM:668F  
SRAM:6690 room_tiles_x_16:
SRAM:6691  
SRAM:6692  
SRAM:6693  
SRAM:6694  
SRAM:6695  
SRAM:6696  
SRAM:6697  
SRAM:6698  
SRAM:6699  
SRAM:669A  
SRAM:669B  
SRAM:669C  
SRAM:669D  
SRAM:669E  
SRAM:669F  
SRAM:66A0  
SRAM:66A1  
SRAM:66A2  
SRAM:66A3  
SRAM:66A4  
SRAM:66A5  
SRAM:66A6 room_tiles_x_17:
SRAM:66A7  
SRAM:66A8  
SRAM:66A9  
SRAM:66AA  
SRAM:66AB  
SRAM:66AC  
SRAM:66AD  
SRAM:66AE  
SRAM:66AF  
SRAM:66B0  
SRAM:66B1  
SRAM:66B2  
SRAM:66B3  
SRAM:66B4  
SRAM:66B5  
SRAM:66B6  
SRAM:66B7  
SRAM:66B8  
SRAM:66B9  
SRAM:66BA  
SRAM:66BB  
SRAM:66BC room_tiles_x_18:
SRAM:66BD  
SRAM:66BE  
SRAM:66BF  
SRAM:66C0  
SRAM:66C1  
SRAM:66C2  
SRAM:66C3  
SRAM:66C4  
SRAM:66C5  
SRAM:66C6  
SRAM:66C7  
SRAM:66C8  
SRAM:66C9  
SRAM:66CA  
SRAM:66CB  
SRAM:66CC  
SRAM:66CD  
SRAM:66CE  
SRAM:66CF  
SRAM:66D0  
SRAM:66D1  
SRAM:66D2 room_tiles_x_19:
SRAM:66D3  
SRAM:66D4  
SRAM:66D5  
SRAM:66D6  
SRAM:66D7  
SRAM:66D8  
SRAM:66D9  
SRAM:66DA  
SRAM:66DB  
SRAM:66DC  
SRAM:66DD  
SRAM:66DE  
SRAM:66DF  
SRAM:66E0  
SRAM:66E1  
SRAM:66E2  
SRAM:66E3  
SRAM:66E4  
SRAM:66E5  
SRAM:66E6  
SRAM:66E7  
SRAM:66E8 room_tiles_x_20:
SRAM:66E9  
SRAM:66EA  
SRAM:66EB  
SRAM:66EC  
SRAM:66ED  
SRAM:66EE  
SRAM:66EF  
SRAM:66F0  
SRAM:66F1  
SRAM:66F2  
SRAM:66F3  
SRAM:66F4  
SRAM:66F5  
SRAM:66F6  
SRAM:66F7  
SRAM:66F8  
SRAM:66F9  
SRAM:66FA  
SRAM:66FB  
SRAM:66FC  
SRAM:66FD  
SRAM:66FE room_tiles_x_21:
SRAM:66FF  
SRAM:6700  
SRAM:6701  
SRAM:6702  
SRAM:6703  
SRAM:6704  
SRAM:6705  
SRAM:6706  
SRAM:6707  
SRAM:6708  
SRAM:6709  
SRAM:670A  
SRAM:670B  
SRAM:670C  
SRAM:670D  
SRAM:670E  
SRAM:670F  
SRAM:6710  
SRAM:6711  
SRAM:6712  
SRAM:6713  
SRAM:6714 room_tiles_x_22:
SRAM:6715  
SRAM:6716  
SRAM:6717  
SRAM:6718  
SRAM:6719  
SRAM:671A  
SRAM:671B  
SRAM:671C  
SRAM:671D  
SRAM:671E  
SRAM:671F  
SRAM:6720  
SRAM:6721  
SRAM:6722  
SRAM:6723  
SRAM:6724  
SRAM:6725  
SRAM:6726  
SRAM:6727  
SRAM:6728  
SRAM:6729  
SRAM:672A room_tiles_x_23:
SRAM:672B  
SRAM:672C  
SRAM:672D  
SRAM:672E  
SRAM:672F  
SRAM:6730  
SRAM:6731  
SRAM:6732  
SRAM:6733  
SRAM:6734  
SRAM:6735  
SRAM:6736  
SRAM:6737  
SRAM:6738  
SRAM:6739  
SRAM:673A  
SRAM:673B  
SRAM:673C  
SRAM:673D  
SRAM:673E  
SRAM:673F  
SRAM:6740 room_tiles_x_24:
SRAM:6741  
SRAM:6742  
SRAM:6743  
SRAM:6744  
SRAM:6745  
SRAM:6746  
SRAM:6747  
SRAM:6748  
SRAM:6749  
SRAM:674A  
SRAM:674B  
SRAM:674C  
SRAM:674D  
SRAM:674E  
SRAM:674F  
SRAM:6750  
SRAM:6751  
SRAM:6752  
SRAM:6753  
SRAM:6754  
SRAM:6755  
SRAM:6756 room_tiles_x_25:
SRAM:6757  
SRAM:6758  
SRAM:6759  
SRAM:675A  
SRAM:675B  
SRAM:675C  
SRAM:675D  
SRAM:675E  
SRAM:675F  
SRAM:6760  
SRAM:6761  
SRAM:6762  
SRAM:6763  
SRAM:6764  
SRAM:6765  
SRAM:6766  
SRAM:6767  
SRAM:6768  
SRAM:6769  
SRAM:676A  
SRAM:676B  
SRAM:676C room_tiles_x_26:
SRAM:676D  
SRAM:676E  
SRAM:676F  
SRAM:6770  
SRAM:6771  
SRAM:6772  
SRAM:6773  
SRAM:6774  
SRAM:6775  
SRAM:6776  
SRAM:6777  
SRAM:6778  
SRAM:6779  
SRAM:677A  
SRAM:677B  
SRAM:677C  
SRAM:677D  
SRAM:677E  
SRAM:677F  
SRAM:6780  
SRAM:6781  
SRAM:6782 room_tiles_x_27:
SRAM:6783  
SRAM:6784  
SRAM:6785  
SRAM:6786  
SRAM:6787  
SRAM:6788  
SRAM:6789  
SRAM:678A  
SRAM:678B  
SRAM:678C  
SRAM:678D  
SRAM:678E  
SRAM:678F  
SRAM:6790  
SRAM:6791  
SRAM:6792  
SRAM:6793  
SRAM:6794  
SRAM:6795  
SRAM:6796  
SRAM:6797  
SRAM:6798 room_tiles_x_28:
SRAM:6799  
SRAM:679A  
SRAM:679B  
SRAM:679C  
SRAM:679D  
SRAM:679E  
SRAM:679F  
SRAM:67A0  
SRAM:67A1  
SRAM:67A2  
SRAM:67A3  
SRAM:67A4  
SRAM:67A5  
SRAM:67A6  
SRAM:67A7  
SRAM:67A8  
SRAM:67A9  
SRAM:67AA  
SRAM:67AB  
SRAM:67AC  
SRAM:67AD  
SRAM:67AE room_tiles_x_29:
SRAM:67AF  
SRAM:67B0  
SRAM:67B1  
SRAM:67B2  
SRAM:67B3  
SRAM:67B4  
SRAM:67B5  
SRAM:67B6  
SRAM:67B7  
SRAM:67B8  
SRAM:67B9  
SRAM:67BA  
SRAM:67BB  
SRAM:67BC  
SRAM:67BD  
SRAM:67BE  
SRAM:67BF  
SRAM:67C0  
SRAM:67C1  
SRAM:67C2  
SRAM:67C3  
SRAM:67C4 room_tiles_x_30:
SRAM:67C5  
SRAM:67C6  
SRAM:67C7  
SRAM:67C8  
SRAM:67C9  
SRAM:67CA  
SRAM:67CB  
SRAM:67CC  
SRAM:67CD  
SRAM:67CE  
SRAM:67CF  
SRAM:67D0  
SRAM:67D1  
SRAM:67D2  
SRAM:67D3  
SRAM:67D4  
SRAM:67D5  
SRAM:67D6  
SRAM:67D7  
SRAM:67D8  
SRAM:67D9  
SRAM:67DA room_tiles_x_31:
SRAM:67DB  
SRAM:67DC  
SRAM:67DD  
SRAM:67DE  
SRAM:67DF  
SRAM:67E0  
SRAM:67E1  
SRAM:67E2  
SRAM:67E3  
SRAM:67E4  
SRAM:67E5  
SRAM:67E6  
SRAM:67E7  
SRAM:67E8  
SRAM:67E9  
SRAM:67EA  
SRAM:67EB  
SRAM:67EC  
SRAM:67ED  
SRAM:67EE  
SRAM:67EF  
SRAM:67F0 copied_ppu_data_0: ; This set of PPU commands is copied from ROM6:9CD8 (some_ppu_palette_0-7).
SRAM:67F1  
SRAM:67F2  
SRAM:67F3  
SRAM:67F4  
SRAM:67F5  
SRAM:67F6  
SRAM:67F7  
SRAM:67F8  
SRAM:67F9  
SRAM:67FA  
SRAM:67FB  
SRAM:67FC  
SRAM:67FD  
SRAM:67FE  
SRAM:67FF  
SRAM:6800  
SRAM:6801  
SRAM:6802  
SRAM:6803  
SRAM:6804 byte_26804:
SRAM:6805  
SRAM:6806  
SRAM:6807  
SRAM:6808  
SRAM:6809  
SRAM:680A  
SRAM:680B  
SRAM:680C  
SRAM:680D  
SRAM:680E  
SRAM:680F  
SRAM:6810 unk_26810:
SRAM:6811  
SRAM:6812  
SRAM:6813  
SRAM:6814 copied_ppu_data_1:
SRAM:6815  
SRAM:6816  
SRAM:6817 unk_26817:
SRAM:6818  
SRAM:6819  
SRAM:681A  
SRAM:681B  
SRAM:681C copied_ppu_data_2:
SRAM:681D  
SRAM:681E  
SRAM:681F  
SRAM:6820  
SRAM:6821  
SRAM:6822  
SRAM:6823  
SRAM:6824  
SRAM:6825 unk_26825:
SRAM:6826  
SRAM:6827 byte_26827:
SRAM:6828 byte_26828:
SRAM:6829  
SRAM:682A  
SRAM:682B  
SRAM:682C  
SRAM:682D  
SRAM:682E  
SRAM:682F  
SRAM:6830  
SRAM:6831  
SRAM:6832  
SRAM:6833  
SRAM:6834  
SRAM:6835  
SRAM:6836  
SRAM:6837  
SRAM:6838  
SRAM:6839  
SRAM:683A  
SRAM:683B  
SRAM:683C  
SRAM:683D  
SRAM:683E  
SRAM:683F  
SRAM:6840  
SRAM:6841  
SRAM:6842  
SRAM:6843  
SRAM:6844  
SRAM:6845  
SRAM:6846  
SRAM:6847 copied_ppu_data_3:
SRAM:6848  
SRAM:6849  
SRAM:684A  
SRAM:684B unk_2684B:
SRAM:684C  
SRAM:684D  
SRAM:684E  
SRAM:684F copied_ppu_data_4:
SRAM:6850  
SRAM:6851  
SRAM:6852  
SRAM:6853  
SRAM:6854  
SRAM:6855  
SRAM:6856  
SRAM:6857  
SRAM:6858  
SRAM:6859 copied_ppu_data_5:
SRAM:685A  
SRAM:685B  
SRAM:685C  
SRAM:685D  
SRAM:685E  
SRAM:685F  
SRAM:6860  
SRAM:6861  
SRAM:6862  
SRAM:6863  
SRAM:6864  
SRAM:6865 copied_ppu_data_6:
SRAM:6866  
SRAM:6867  
SRAM:6868  
SRAM:6869  
SRAM:686A  
SRAM:686B  
SRAM:686C  
SRAM:686D  
SRAM:686E  
SRAM:686F  
SRAM:6870  
SRAM:6871  
SRAM:6872  
SRAM:6873 copied_ppu_data_7:
SRAM:6874  
SRAM:6875  
SRAM:6876  
SRAM:6877  
SRAM:6878  
SRAM:6879  
SRAM:687A  
SRAM:687B  
SRAM:687C  
SRAM:687D  
SRAM:687E dungeon_screen_data_0: ; This is copied from dungeon_screen_attr_1Q_1, etc.
SRAM:687F  
SRAM:6880  
SRAM:6881  
SRAM:6882  
SRAM:6883  
SRAM:6884  
SRAM:6885  
SRAM:6886  
SRAM:6887  
SRAM:6888  
SRAM:6889  
SRAM:688A  
SRAM:688B  
SRAM:688C  
SRAM:688D  
SRAM:688E  
SRAM:688F  
SRAM:6890  
SRAM:6891  
SRAM:6892  
SRAM:6893  
SRAM:6894  
SRAM:6895  
SRAM:6896  
SRAM:6897  
SRAM:6898  
SRAM:6899  
SRAM:689A  
SRAM:689B  
SRAM:689C  
SRAM:689D  
SRAM:689E  
SRAM:689F  
SRAM:68A0  
SRAM:68A1  
SRAM:68A2  
SRAM:68A3  
SRAM:68A4  
SRAM:68A5  
SRAM:68A6  
SRAM:68A7  
SRAM:68A8  
SRAM:68A9  
SRAM:68AA  
SRAM:68AB  
SRAM:68AC  
SRAM:68AD  
SRAM:68AE  
SRAM:68AF  
SRAM:68B0  
SRAM:68B1  
SRAM:68B2  
SRAM:68B3  
SRAM:68B4  
SRAM:68B5  
SRAM:68B6  
SRAM:68B7  
SRAM:68B8  
SRAM:68B9  
SRAM:68BA  
SRAM:68BB  
SRAM:68BC  
SRAM:68BD  
SRAM:68BE  
SRAM:68BF  
SRAM:68C0  
SRAM:68C1  
SRAM:68C2  
SRAM:68C3  
SRAM:68C4  
SRAM:68C5  
SRAM:68C6  
SRAM:68C7  
SRAM:68C8  
SRAM:68C9  
SRAM:68CA  
SRAM:68CB  
SRAM:68CC  
SRAM:68CD  
SRAM:68CE  
SRAM:68CF  
SRAM:68D0  
SRAM:68D1  
SRAM:68D2  
SRAM:68D3  
SRAM:68D4  
SRAM:68D5  
SRAM:68D6  
SRAM:68D7  
SRAM:68D8  
SRAM:68D9  
SRAM:68DA  
SRAM:68DB  
SRAM:68DC  
SRAM:68DD  
SRAM:68DE  
SRAM:68DF  
SRAM:68E0  
SRAM:68E1  
SRAM:68E2  
SRAM:68E3  
SRAM:68E4  
SRAM:68E5  
SRAM:68E6  
SRAM:68E7  
SRAM:68E8  
SRAM:68E9  
SRAM:68EA  
SRAM:68EB  
SRAM:68EC  
SRAM:68ED  
SRAM:68EE  
SRAM:68EF  
SRAM:68F0  
SRAM:68F1  
SRAM:68F2  
SRAM:68F3  
SRAM:68F4  
SRAM:68F5  
SRAM:68F6  
SRAM:68F7  
SRAM:68F8  
SRAM:68F9  
SRAM:68FA  
SRAM:68FB  
SRAM:68FC  
SRAM:68FD  
SRAM:68FE dungeon_screen_data_1:
SRAM:68FF  
SRAM:6900  
SRAM:6901  
SRAM:6902  
SRAM:6903  
SRAM:6904  
SRAM:6905  
SRAM:6906  
SRAM:6907  
SRAM:6908  
SRAM:6909  
SRAM:690A  
SRAM:690B  
SRAM:690C  
SRAM:690D  
SRAM:690E  
SRAM:690F  
SRAM:6910  
SRAM:6911  
SRAM:6912  
SRAM:6913  
SRAM:6914  
SRAM:6915  
SRAM:6916  
SRAM:6917  
SRAM:6918  
SRAM:6919  
SRAM:691A  
SRAM:691B  
SRAM:691C  
SRAM:691D  
SRAM:691E  
SRAM:691F  
SRAM:6920  
SRAM:6921  
SRAM:6922  
SRAM:6923  
SRAM:6924  
SRAM:6925  
SRAM:6926  
SRAM:6927  
SRAM:6928  
SRAM:6929  
SRAM:692A  
SRAM:692B  
SRAM:692C  
SRAM:692D  
SRAM:692E  
SRAM:692F  
SRAM:6930  
SRAM:6931  
SRAM:6932  
SRAM:6933  
SRAM:6934  
SRAM:6935  
SRAM:6936  
SRAM:6937  
SRAM:6938  
SRAM:6939  
SRAM:693A  
SRAM:693B  
SRAM:693C  
SRAM:693D  
SRAM:693E  
SRAM:693F  
SRAM:6940  
SRAM:6941  
SRAM:6942  
SRAM:6943  
SRAM:6944  
SRAM:6945  
SRAM:6946  
SRAM:6947  
SRAM:6948  
SRAM:6949  
SRAM:694A  
SRAM:694B  
SRAM:694C  
SRAM:694D  
SRAM:694E  
SRAM:694F  
SRAM:6950  
SRAM:6951  
SRAM:6952  
SRAM:6953  
SRAM:6954  
SRAM:6955  
SRAM:6956  
SRAM:6957  
SRAM:6958  
SRAM:6959  
SRAM:695A  
SRAM:695B  
SRAM:695C  
SRAM:695D  
SRAM:695E  
SRAM:695F  
SRAM:6960  
SRAM:6961  
SRAM:6962  
SRAM:6963  
SRAM:6964  
SRAM:6965  
SRAM:6966  
SRAM:6967  
SRAM:6968  
SRAM:6969  
SRAM:696A  
SRAM:696B  
SRAM:696C  
SRAM:696D  
SRAM:696E  
SRAM:696F  
SRAM:6970  
SRAM:6971  
SRAM:6972  
SRAM:6973  
SRAM:6974  
SRAM:6975  
SRAM:6976  
SRAM:6977  
SRAM:6978  
SRAM:6979  
SRAM:697A  
SRAM:697B  
SRAM:697C  
SRAM:697D  
SRAM:697E dungeon_screen_data_2:
SRAM:697F  
SRAM:6980  
SRAM:6981  
SRAM:6982  
SRAM:6983  
SRAM:6984  
SRAM:6985  
SRAM:6986  
SRAM:6987  
SRAM:6988  
SRAM:6989  
SRAM:698A  
SRAM:698B  
SRAM:698C  
SRAM:698D  
SRAM:698E  
SRAM:698F  
SRAM:6990  
SRAM:6991  
SRAM:6992  
SRAM:6993  
SRAM:6994  
SRAM:6995  
SRAM:6996  
SRAM:6997  
SRAM:6998  
SRAM:6999  
SRAM:699A  
SRAM:699B  
SRAM:699C  
SRAM:699D  
SRAM:699E  
SRAM:699F  
SRAM:69A0  
SRAM:69A1  
SRAM:69A2  
SRAM:69A3  
SRAM:69A4  
SRAM:69A5  
SRAM:69A6  
SRAM:69A7  
SRAM:69A8  
SRAM:69A9  
SRAM:69AA  
SRAM:69AB  
SRAM:69AC  
SRAM:69AD  
SRAM:69AE  
SRAM:69AF  
SRAM:69B0  
SRAM:69B1  
SRAM:69B2  
SRAM:69B3  
SRAM:69B4  
SRAM:69B5  
SRAM:69B6  
SRAM:69B7  
SRAM:69B8  
SRAM:69B9  
SRAM:69BA  
SRAM:69BB  
SRAM:69BC  
SRAM:69BD  
SRAM:69BE  
SRAM:69BF  
SRAM:69C0  
SRAM:69C1  
SRAM:69C2  
SRAM:69C3  
SRAM:69C4  
SRAM:69C5  
SRAM:69C6  
SRAM:69C7  
SRAM:69C8  
SRAM:69C9  
SRAM:69CA  
SRAM:69CB  
SRAM:69CC  
SRAM:69CD  
SRAM:69CE  
SRAM:69CF  
SRAM:69D0  
SRAM:69D1  
SRAM:69D2  
SRAM:69D3  
SRAM:69D4  
SRAM:69D5  
SRAM:69D6  
SRAM:69D7  
SRAM:69D8  
SRAM:69D9  
SRAM:69DA  
SRAM:69DB  
SRAM:69DC  
SRAM:69DD  
SRAM:69DE  
SRAM:69DF  
SRAM:69E0  
SRAM:69E1  
SRAM:69E2  
SRAM:69E3  
SRAM:69E4  
SRAM:69E5  
SRAM:69E6  
SRAM:69E7  
SRAM:69E8  
SRAM:69E9  
SRAM:69EA  
SRAM:69EB  
SRAM:69EC  
SRAM:69ED  
SRAM:69EE  
SRAM:69EF  
SRAM:69F0  
SRAM:69F1  
SRAM:69F2  
SRAM:69F3  
SRAM:69F4  
SRAM:69F5  
SRAM:69F6  
SRAM:69F7  
SRAM:69F8  
SRAM:69F9  
SRAM:69FA  
SRAM:69FB  
SRAM:69FC  
SRAM:69FD  
SRAM:69FE dungeon_screen_data_3:
SRAM:69FF  
SRAM:6A00  
SRAM:6A01  
SRAM:6A02  
SRAM:6A03  
SRAM:6A04  
SRAM:6A05  
SRAM:6A06  
SRAM:6A07  
SRAM:6A08  
SRAM:6A09  
SRAM:6A0A  
SRAM:6A0B  
SRAM:6A0C  
SRAM:6A0D  
SRAM:6A0E  
SRAM:6A0F  
SRAM:6A10  
SRAM:6A11  
SRAM:6A12  
SRAM:6A13  
SRAM:6A14  
SRAM:6A15  
SRAM:6A16  
SRAM:6A17  
SRAM:6A18  
SRAM:6A19  
SRAM:6A1A  
SRAM:6A1B  
SRAM:6A1C  
SRAM:6A1D  
SRAM:6A1E  
SRAM:6A1F  
SRAM:6A20  
SRAM:6A21  
SRAM:6A22  
SRAM:6A23  
SRAM:6A24  
SRAM:6A25  
SRAM:6A26  
SRAM:6A27  
SRAM:6A28  
SRAM:6A29  
SRAM:6A2A  
SRAM:6A2B  
SRAM:6A2C  
SRAM:6A2D  
SRAM:6A2E  
SRAM:6A2F  
SRAM:6A30  
SRAM:6A31  
SRAM:6A32  
SRAM:6A33  
SRAM:6A34  
SRAM:6A35  
SRAM:6A36  
SRAM:6A37  
SRAM:6A38  
SRAM:6A39  
SRAM:6A3A  
SRAM:6A3B  
SRAM:6A3C  
SRAM:6A3D  
SRAM:6A3E  
SRAM:6A3F  
SRAM:6A40  
SRAM:6A41  
SRAM:6A42  
SRAM:6A43  
SRAM:6A44  
SRAM:6A45  
SRAM:6A46  
SRAM:6A47  
SRAM:6A48  
SRAM:6A49  
SRAM:6A4A  
SRAM:6A4B  
SRAM:6A4C  
SRAM:6A4D  
SRAM:6A4E  
SRAM:6A4F  
SRAM:6A50  
SRAM:6A51  
SRAM:6A52  
SRAM:6A53  
SRAM:6A54  
SRAM:6A55  
SRAM:6A56  
SRAM:6A57  
SRAM:6A58  
SRAM:6A59  
SRAM:6A5A  
SRAM:6A5B  
SRAM:6A5C  
SRAM:6A5D  
SRAM:6A5E  
SRAM:6A5F  
SRAM:6A60  
SRAM:6A61  
SRAM:6A62  
SRAM:6A63  
SRAM:6A64  
SRAM:6A65  
SRAM:6A66  
SRAM:6A67  
SRAM:6A68  
SRAM:6A69  
SRAM:6A6A  
SRAM:6A6B  
SRAM:6A6C  
SRAM:6A6D  
SRAM:6A6E  
SRAM:6A6F  
SRAM:6A70  
SRAM:6A71  
SRAM:6A72  
SRAM:6A73  
SRAM:6A74  
SRAM:6A75  
SRAM:6A76  
SRAM:6A77  
SRAM:6A78  
SRAM:6A79  
SRAM:6A7A  
SRAM:6A7B  
SRAM:6A7C  
SRAM:6A7D  
SRAM:6A7E dungeon_screen_data_4:
SRAM:6A7F  
SRAM:6A80  
SRAM:6A81  
SRAM:6A82  
SRAM:6A83  
SRAM:6A84  
SRAM:6A85  
SRAM:6A86  
SRAM:6A87  
SRAM:6A88  
SRAM:6A89  
SRAM:6A8A  
SRAM:6A8B  
SRAM:6A8C  
SRAM:6A8D  
SRAM:6A8E  
SRAM:6A8F  
SRAM:6A90  
SRAM:6A91  
SRAM:6A92  
SRAM:6A93  
SRAM:6A94  
SRAM:6A95  
SRAM:6A96  
SRAM:6A97  
SRAM:6A98  
SRAM:6A99  
SRAM:6A9A  
SRAM:6A9B  
SRAM:6A9C  
SRAM:6A9D  
SRAM:6A9E  
SRAM:6A9F  
SRAM:6AA0  
SRAM:6AA1  
SRAM:6AA2  
SRAM:6AA3  
SRAM:6AA4  
SRAM:6AA5  
SRAM:6AA6  
SRAM:6AA7  
SRAM:6AA8  
SRAM:6AA9  
SRAM:6AAA  
SRAM:6AAB  
SRAM:6AAC  
SRAM:6AAD  
SRAM:6AAE  
SRAM:6AAF  
SRAM:6AB0  
SRAM:6AB1  
SRAM:6AB2  
SRAM:6AB3  
SRAM:6AB4  
SRAM:6AB5  
SRAM:6AB6  
SRAM:6AB7  
SRAM:6AB8  
SRAM:6AB9  
SRAM:6ABA  
SRAM:6ABB  
SRAM:6ABC  
SRAM:6ABD  
SRAM:6ABE  
SRAM:6ABF  
SRAM:6AC0  
SRAM:6AC1  
SRAM:6AC2  
SRAM:6AC3  
SRAM:6AC4  
SRAM:6AC5  
SRAM:6AC6  
SRAM:6AC7  
SRAM:6AC8  
SRAM:6AC9  
SRAM:6ACA  
SRAM:6ACB  
SRAM:6ACC  
SRAM:6ACD  
SRAM:6ACE  
SRAM:6ACF  
SRAM:6AD0  
SRAM:6AD1  
SRAM:6AD2  
SRAM:6AD3  
SRAM:6AD4  
SRAM:6AD5  
SRAM:6AD6  
SRAM:6AD7  
SRAM:6AD8  
SRAM:6AD9  
SRAM:6ADA  
SRAM:6ADB  
SRAM:6ADC  
SRAM:6ADD  
SRAM:6ADE  
SRAM:6ADF  
SRAM:6AE0  
SRAM:6AE1  
SRAM:6AE2  
SRAM:6AE3  
SRAM:6AE4  
SRAM:6AE5  
SRAM:6AE6  
SRAM:6AE7  
SRAM:6AE8  
SRAM:6AE9  
SRAM:6AEA  
SRAM:6AEB  
SRAM:6AEC  
SRAM:6AED  
SRAM:6AEE  
SRAM:6AEF  
SRAM:6AF0  
SRAM:6AF1  
SRAM:6AF2  
SRAM:6AF3  
SRAM:6AF4  
SRAM:6AF5  
SRAM:6AF6  
SRAM:6AF7  
SRAM:6AF8  
SRAM:6AF9  
SRAM:6AFA  
SRAM:6AFB  
SRAM:6AFC  
SRAM:6AFD  
SRAM:6AFE dungeon_screen_data_5:
SRAM:6AFF  
SRAM:6B00  
SRAM:6B01  
SRAM:6B02  
SRAM:6B03  
SRAM:6B04  
SRAM:6B05  
SRAM:6B06  
SRAM:6B07  
SRAM:6B08  
SRAM:6B09  
SRAM:6B0A  
SRAM:6B0B  
SRAM:6B0C  
SRAM:6B0D  
SRAM:6B0E  
SRAM:6B0F  
SRAM:6B10  
SRAM:6B11  
SRAM:6B12  
SRAM:6B13  
SRAM:6B14  
SRAM:6B15  
SRAM:6B16  
SRAM:6B17  
SRAM:6B18  
SRAM:6B19  
SRAM:6B1A  
SRAM:6B1B  
SRAM:6B1C  
SRAM:6B1D  
SRAM:6B1E  
SRAM:6B1F  
SRAM:6B20  
SRAM:6B21  
SRAM:6B22  
SRAM:6B23  
SRAM:6B24  
SRAM:6B25  
SRAM:6B26  
SRAM:6B27  
SRAM:6B28  
SRAM:6B29  
SRAM:6B2A  
SRAM:6B2B  
SRAM:6B2C  
SRAM:6B2D  
SRAM:6B2E  
SRAM:6B2F  
SRAM:6B30  
SRAM:6B31  
SRAM:6B32  
SRAM:6B33  
SRAM:6B34  
SRAM:6B35  
SRAM:6B36  
SRAM:6B37  
SRAM:6B38  
SRAM:6B39  
SRAM:6B3A  
SRAM:6B3B  
SRAM:6B3C  
SRAM:6B3D  
SRAM:6B3E  
SRAM:6B3F  
SRAM:6B40  
SRAM:6B41  
SRAM:6B42  
SRAM:6B43  
SRAM:6B44  
SRAM:6B45  
SRAM:6B46  
SRAM:6B47  
SRAM:6B48  
SRAM:6B49  
SRAM:6B4A  
SRAM:6B4B  
SRAM:6B4C  
SRAM:6B4D  
SRAM:6B4E  
SRAM:6B4F  
SRAM:6B50  
SRAM:6B51  
SRAM:6B52  
SRAM:6B53  
SRAM:6B54  
SRAM:6B55  
SRAM:6B56  
SRAM:6B57  
SRAM:6B58  
SRAM:6B59  
SRAM:6B5A  
SRAM:6B5B  
SRAM:6B5C  
SRAM:6B5D  
SRAM:6B5E  
SRAM:6B5F  
SRAM:6B60  
SRAM:6B61  
SRAM:6B62  
SRAM:6B63  
SRAM:6B64  
SRAM:6B65  
SRAM:6B66  
SRAM:6B67  
SRAM:6B68  
SRAM:6B69  
SRAM:6B6A  
SRAM:6B6B  
SRAM:6B6C  
SRAM:6B6D  
SRAM:6B6E  
SRAM:6B6F  
SRAM:6B70  
SRAM:6B71  
SRAM:6B72  
SRAM:6B73  
SRAM:6B74  
SRAM:6B75  
SRAM:6B76  
SRAM:6B77  
SRAM:6B78  
SRAM:6B79  
SRAM:6B7A  
SRAM:6B7B  
SRAM:6B7C  
SRAM:6B7D  
SRAM:6B7E ppu_data_for_current_dungeon:
SRAM:6B7E  
SRAM:6B7F  
SRAM:6B80  
SRAM:6B81  
SRAM:6B82  
SRAM:6B83  
SRAM:6B84  
SRAM:6B85  
SRAM:6B86  
SRAM:6B87  
SRAM:6B88  
SRAM:6B89  
SRAM:6B8A  
SRAM:6B8B  
SRAM:6B8C  
SRAM:6B8D  
SRAM:6B8E  
SRAM:6B8F  
SRAM:6B90  
SRAM:6B91  
SRAM:6B92  
SRAM:6B93  
 
SRAM:6B94  
SRAM:6B95  
SRAM:6B96  
SRAM:6B97  
SRAM:6B98  
SRAM:6B99  
SRAM:6B9A  
SRAM:6B9B  
SRAM:6B9C  
SRAM:6B9D  
SRAM:6B9E  
SRAM:6B9F  
SRAM:6BA0  
SRAM:6BA1  
SRAM:6BA2  
SRAM:6BA3  
SRAM:6BA4  
SRAM:6BA5  
SRAM:6BA6  
SRAM:6BA7  
SRAM:6BA8  
SRAM:6BA9  
SRAM:6BAA  
SRAM:6BAB  
SRAM:6BAC  
SRAM:6BAD  
SRAM:6BAE  
SRAM:6BAF  
SRAM:6BB0  
SRAM:6BB1  
SRAM:6BB2  
SRAM:6BB3  
SRAM:6BB4  
SRAM:6BB5  
SRAM:6BB6  
SRAM:6BB7  
SRAM:6BB8  
SRAM:6BB9  
SRAM:6BBA  
SRAM:6BBB  
SRAM:6BBC  
SRAM:6BBD  
SRAM:6BBE  
SRAM:6BBF  
SRAM:6BC0  
SRAM:6BC1  
SRAM:6BC2  
SRAM:6BC3  
SRAM:6BC4  
SRAM:6BC5  
SRAM:6BC6  
SRAM:6BC7  
SRAM:6BC8  
SRAM:6BC9  
SRAM:6BCA  
SRAM:6BCB  
SRAM:6BCC  
SRAM:6BCD  
SRAM:6BCE  
SRAM:6BCF  
SRAM:6BD0  
SRAM:6BD1  
SRAM:6BD2  
SRAM:6BD3  
SRAM:6BD4  
SRAM:6BD5  
SRAM:6BD6  
SRAM:6BD7  
SRAM:6BD8  
SRAM:6BD9  
SRAM:6BDA  
SRAM:6BDB  
SRAM:6BDC  
SRAM:6BDD  
SRAM:6BDE  
SRAM:6BDF  
SRAM:6BE0  
SRAM:6BE1  
SRAM:6BE2  
SRAM:6BE3  
SRAM:6BE4  
SRAM:6BE5  
SRAM:6BE6  
SRAM:6BE7  
SRAM:6BE8  
SRAM:6BE9  
SRAM:6BEA  
SRAM:6BEB  
SRAM:6BEC  
SRAM:6BED  
SRAM:6BEE  
SRAM:6BEF  
SRAM:6BF0  
SRAM:6BF1  
SRAM:6BF2  
SRAM:6BF3  
SRAM:6BF4  
SRAM:6BF5  
SRAM:6BF6  
SRAM:6BF7  
SRAM:6BF8  
SRAM:6BF9  
SRAM:6BFA  
SRAM:6BFB  
SRAM:6BFC  
SRAM:6BFD  
SRAM:6BFE  
SRAM:6BFF  
SRAM:6C00  
SRAM:6C01  
SRAM:6C02  
SRAM:6C03  
SRAM:6C04  
SRAM:6C05  
SRAM:6C06  
SRAM:6C07  
SRAM:6C08  
SRAM:6C09  
SRAM:6C0A  
SRAM:6C0B  
SRAM:6C0C  
SRAM:6C0D  
SRAM:6C0E  
SRAM:6C0F  
SRAM:6C10  
SRAM:6C11  
SRAM:6C12  
SRAM:6C13  
SRAM:6C14  
SRAM:6C15  
SRAM:6C16  
SRAM:6C17  
SRAM:6C18  
SRAM:6C19  
SRAM:6C1A  
SRAM:6C1B  
SRAM:6C1C  
SRAM:6C1D  
SRAM:6C1E  
SRAM:6C1F  
SRAM:6C20  
SRAM:6C21  
SRAM:6C22  
SRAM:6C23  
SRAM:6C24  
SRAM:6C25  
SRAM:6C26  
SRAM:6C27  
SRAM:6C28  
SRAM:6C29  
SRAM:6C2A  
SRAM:6C2B  
SRAM:6C2C  
SRAM:6C2D  
SRAM:6C2E  
SRAM:6C2F  
SRAM:6C30  
SRAM:6C31  
SRAM:6C32  
SRAM:6C33  
SRAM:6C34  
SRAM:6C35  
SRAM:6C36  
SRAM:6C37  
SRAM:6C38  
SRAM:6C39  
SRAM:6C3A  
SRAM:6C3B  
SRAM:6C3C  
SRAM:6C3D  
SRAM:6C3E  
SRAM:6C3F  
SRAM:6C40  
SRAM:6C41  
SRAM:6C42  
SRAM:6C43  
SRAM:6C44  
SRAM:6C45  
SRAM:6C46  
SRAM:6C47  
SRAM:6C48  
SRAM:6C49  
SRAM:6C4A  
SRAM:6C4B  
SRAM:6C4C  
SRAM:6C4D  
SRAM:6C4E  
SRAM:6C4F  
SRAM:6C50  
SRAM:6C51  
SRAM:6C52  
SRAM:6C53  
SRAM:6C54  
SRAM:6C55  
SRAM:6C56  
SRAM:6C57  
SRAM:6C58  
SRAM:6C59  
SRAM:6C5A  
SRAM:6C5B  
SRAM:6C5C  
SRAM:6C5D  
SRAM:6C5E  
SRAM:6C5F  
SRAM:6C60  
SRAM:6C61  
SRAM:6C62  
SRAM:6C63  
SRAM:6C64  
SRAM:6C65  
SRAM:6C66  
SRAM:6C67  
SRAM:6C68  
SRAM:6C69  
SRAM:6C6A  
SRAM:6C6B  
SRAM:6C6C  
SRAM:6C6D  
SRAM:6C6E  
SRAM:6C6F  
SRAM:6C70  
SRAM:6C71  
SRAM:6C72  
SRAM:6C73  
SRAM:6C74  
SRAM:6C75  
SRAM:6C76  
SRAM:6C77  
SRAM:6C78  
SRAM:6C79  
SRAM:6C7A  
SRAM:6C7B  
SRAM:6C7C  
SRAM:6C7D  
SRAM:6C7E  
SRAM:6C7F  
SRAM:6C80  
SRAM:6C81  
SRAM:6C82  
SRAM:6C83  
SRAM:6C84  
SRAM:6C85  
SRAM:6C86  
SRAM:6C87  
SRAM:6C88  
SRAM:6C89  
SRAM:6C8A  
SRAM:6C8B  
SRAM:6C8C  
SRAM:6C8D  
SRAM:6C8E  
SRAM:6C8F  
 
Segment: CODE
 
Subroutine start_task1
; Set next_work_values_idx to 0, and set active_game_mode_task to 1.
CODE:6C90 start_task1:
CODE:6C90 LDA #0
CODE:6C91 STA task_state ; Set to 0
CODE:6C92 INC active_game_mode_task ; Set to 1
 
CODE:6C96 locret_106C96:
CODE:6C96 RTS
 
CODE:6C97 ppu_hud_update_command: .BYTE $20
CODE:6C98   .BYTE $B6
CODE:6C99   .BYTE 8
CODE:6C9A   .BYTE $24
CODE:6C9B   .BYTE $24
CODE:6C9C   .BYTE $24
CODE:6C9D   .BYTE $24
CODE:6C9E   .BYTE $24
CODE:6C9F   .BYTE $24
CODE:6CA0   .BYTE $24
CODE:6CA1   .BYTE $24
CODE:6CA2   .BYTE $20
CODE:6CA3   .BYTE $D6
CODE:6CA4   .BYTE 8
CODE:6CA5   .BYTE $24
CODE:6CA6   .BYTE $24
CODE:6CA7   .BYTE $24
CODE:6CA8   .BYTE $24
CODE:6CA9   .BYTE $24
CODE:6CAA   .BYTE $24
CODE:6CAB   .BYTE $24
CODE:6CAC   .BYTE $24
CODE:6CAD   .BYTE $20
CODE:6CAE   .BYTE $6C
CODE:6CAF   .BYTE 3
CODE:6CB0   .BYTE $21
CODE:6CB1   .BYTE 0
CODE:6CB2   .BYTE $24
CODE:6CB3   .BYTE $20
CODE:6CB4   .BYTE $AC
CODE:6CB5   .BYTE 3
CODE:6CB6   .BYTE $21
CODE:6CB7   .BYTE 0
CODE:6CB8   .BYTE $24
CODE:6CB9   .BYTE $20
CODE:6CBA   .BYTE $CC
CODE:6CBB   .BYTE 3
CODE:6CBC   .BYTE $21
CODE:6CBD   .BYTE 0
CODE:6CBE   .BYTE $24
CODE:6CBF   .BYTE $FF
 
Function chunk for task1_Normal
CODE:6CC0 task1_Normal_p1:
CODE:6CC0 LDA current_ppu_command_index
CODE:6CC1 BNE locret_106C96
CODE:6CC2 LDA ppu_command_buffer
CODE:6CC3 BPL locret_106C96
CODE:6CC4 LDY #$27 ; sword_type+0x27 = pending_rupees_sub
CODE:6CC5 LDA num_rupees
CODE:6CC6 BEQ zero_add_subtract_rupees ; If we have zero rupees, zero out pending_rupees_sub
CODE:6CC7 LDY #$26 ; sword_type+0x26 = pending_rupees_add
CODE:6CC8 CMP #$FF ; If we have 0xFF rupees, zero out pending_rupees_add
CODE:6CC9 BNE check_add_subtract_rupees
 
CODE:6CCA zero_add_subtract_rupees:
CODE:6CCA LDA #0
CODE:6CCB STA sword_type,Y ; Zero out pending_rupees_add or pending_rupees_sub.
 
CODE:6CCC check_add_subtract_rupees: ; The rest of this only happens on even frames.
CODE:6CCC LDA frame_counter
CODE:6CCD LSR A
CODE:6CCE BCS locret_106C96
CODE:6CCF LDA pending_rupees_add
CODE:6CD0 BEQ no_pending_rupees_to_add
CODE:6CD1 DEC pending_rupees_add
CODE:6CD2 INC num_rupees ; Add a rupee from pending_rupees_add
CODE:6CD3 LDA #Sound3_GainRupee
CODE:6CD4 STA play_sound_3
 
CODE:6CD5 no_pending_rupees_to_add:
CODE:6CD5 LDA pending_rupees_sub
CODE:6CD6 BEQ no_pending_rupees_to_subtract
CODE:6CD7 DEC pending_rupees_sub
CODE:6CD8 DEC num_rupees ; Subtract a rupee from pending_rupees_sub
CODE:6CD9 LDA #Sound3_GainRupee
CODE:6CDA STA play_sound_3
 
CODE:6D00 no_pending_rupees_to_subtract: ; The rest of this is updating numbers and hearts in the HUD.
CODE:6D00 LDY #$28
 
CODE:6D01 ppu_loop: ; Copy a PPU command to update the HUD digits. Parts of this
CODE:6D01 LDA ppu_hud_update_command,Y ; command will be updated with the digits in the HUD below.
CODE:6D02 STA ppu_command_buffer,Y
CODE:6D03 DEY
CODE:6D04 BPL ppu_loop
CODE:6D05 LDY #3
CODE:6D06 LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:6D07 STA var_14
CODE:6D08 LDA partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:6D09 STA var_15
CODE:6D0A JSR update_hud_hearts
CODE:6D0B LDX #2
CODE:6D0C LDA num_rupees
CODE:6D0D LDY #$1B ; Offset in ppu_command_buffer for this number.
CODE:6D0E JSR update_hud_number
CODE:6D0F LDY #$21 ; Offset in ppu_command_buffer for this number.
CODE:6D10 LDA have_magic_key
CODE:6D11 BEQ no_magic_key
CODE:6D12 STY var_0
CODE:6D13 LDA #$21
CODE:6D14 STA var_1
CODE:6D15 LDA #$A
CODE:6D16 JSR loc_106D75
CODE:6D17 LDX #8 ; X unused?
CODE:6D18 JSR update_magic_key
CODE:6D19 JMP update_hud_bombs
 
CODE:6D1A no_magic_key: ; X unused?
CODE:6D1A LDX #8
CODE:6D1B LDA num_keys
CODE:6D1C JSR update_hud_number
 
CODE:6D1D update_hud_bombs: ; X unused?
CODE:6D1D LDX #$E
CODE:6D1E LDA num_bombs
CODE:6D1F LDY #$27 ; Offset in ppu_command_buffer for this number.
CODE:6D20 JMP update_hud_number
 
CODE:6D21 update_hud_number: ; Update a number in the HUD (rupees, bombs and keys).
CODE:6D21 STY var_0 ; A = number to display
  ; Y = ppu_command_buffer offset
CODE:6D22 JSR update_hud_number_1
 
CODE:6D23 update_magic_key: ; Copy 3 bytes from var_1 to ppu_command_buffer.
CODE:6D23 LDY #2
CODE:6D24 LDX var_0 ; Reload ppu_command_buffer offset
 
CODE:6D25 ppu_loop_2:
CODE:6D25 LDA var_1,Y
CODE:6D26 STA ppu_command_buffer,X
CODE:6D27 DEX
CODE:6D28 DEY
CODE:6D29 BPL ppu_loop_2
CODE:6D2A RTS
 
Subroutine update_hud_number_1
CODE:6D64 update_hud_number_1:
CODE:6D64 JSR convert_number_to_string ; Convert A to digits in var_1, var_2 and var_3. Leading
  ; zeroes are set to 0x24. A = var_2 (tens digit), Y = var_1 (hundreds digit).
CODE:6D65 CPY #$24
CODE:6D66 BNE have_hundreds_digit ; Branch if we have a hundreds digit.
CODE:6D67 LDY #$21 ; Replace 0x24 with 0x21.
 
CODE:6D68 have_hundreds_digit:
CODE:6D68 STY var_1
CODE:6D69 CMP #$24 ; Compare A (tens digit).
CODE:6D6A BNE have_tens_digit ; Branch if we have a tens digit.
CODE:6D6B LDA var_3 ; A = ones digit.
 
CODE:6D75 loc_106D75: ; Store A in the tens digit.
CODE:6D75 STA var_2
CODE:6D76 LDA #$24
CODE:6D77 STA var_3
 
CODE:6D78 have_tens_digit:
CODE:6D78 RTS
 
Subroutine add_mask_to_play_sound_0
; play_sound_0 |= A
CODE:6D7C add_mask_to_play_sound_0:
CODE:6D7C LDY #1
CODE:6D7D BNE play_sound_on_channel ; Play sound A on channel Y.
 
Subroutine add_play_sound_2
; Play a sound on play_sound_2. A is the mask of the sound to play.
CODE:6D80 add_play_sound_2:
CODE:6D80 LDY #3
 
CODE:6D82 play_sound_on_channel: ; Play sound A on channel Y.
CODE:6D82 ORA play_music,Y
CODE:6D83 STA play_music,Y ; Set to a nonzero value to start playing music. This is set
  ; back to 0 once the song has started.
CODE:6D84 RTS
 
Subroutine task0_InOverworldCellar_7
CODE:6D89 task0_InOverworldCellar_7:
CODE:6D89 LDA task_state
CODE:6D8A PHA
CODE:6D8B JSR task0_FinishingTransition_state_0
CODE:6D8C JSR clear_ladder_and_player_projectiles
CODE:6D8D LDA #$70
CODE:6D8E STA object_x
CODE:6D8F LDA #$DD
CODE:6D90 STA object_y
CODE:6D91 LDA #8
 
CODE:6D9C loc_106D9C:
CODE:6D9C STA object_direction
CODE:6D9D JSR update_link_sprite_and_check_ladder ; This handles a couple things: updating Link's walking sprite
  ; for walking and the big shield, and creating the ladder object
  ; if we're walking over a water gap.
CODE:6D9E JSR task0_Normal_1
CODE:6D9F PLA
CODE:6DA0 STA task_state
CODE:6DA1 LDA #0
CODE:6DA2 STA active_game_mode_task ; Set to 0
CODE:6DA3 INC task_state
CODE:6DA4 LDA #$30
CODE:6DA5 STA object_tile_offset_whole
CODE:6DA6 LDA #1
CODE:6DA7 STA is_in_cellar ; Set to 1
CODE:6DA8 RTS
 
Subroutine clear_overworld_room_object_info
CODE:6DB7 clear_overworld_room_object_info:
CODE:6DB7 LDA #0
CODE:6DB8 STA overworld_room_object_type ; Set to 0
CODE:6DB9 STA overworld_room_object_x ; Set to 0
CODE:6DBA STA overworld_room_object_y ; Set to 0
CODE:6DBB RTS
 
CODE:6DC3 walking_bits_2: .BYTE ControllerBits_Dpad_Up
CODE:6DC4   .BYTE ControllerBits_Dpad_Down
CODE:6DC5   .BYTE ControllerBits_Dpad_Left
CODE:6DC6   .BYTE ControllerBits_Dpad_Right
CODE:6DC7 off_106DC7: .WORD byte_2601A
CODE:6DC9   .WORD byte_26092
CODE:6DCB   .WORD byte_26002
CODE:6DCD   .WORD byte_26512
CODE:6DCF   .WORD byte_26515
CODE:6DD1   .WORD byte_26518
CODE:6DD3   .WORD byte_2651B
CODE:6DD5   .WORD byte_26042
CODE:6DD7   .WORD byte_26212
CODE:6DD9   .WORD byte_2600A
CODE:6DDB   .WORD byte_26513
CODE:6DDD   .WORD byte_26516
CODE:6DDF   .WORD byte_26519
CODE:6DE1   .WORD byte_2651C
CODE:6DE3   .WORD byte_2606A
CODE:6DE5   .WORD byte_26392
CODE:6DE7   .WORD byte_26012
CODE:6DE9   .WORD byte_26514
CODE:6DEB   .WORD byte_26517
CODE:6DED   .WORD byte_2651A
CODE:6DEF   .WORD byte_2651D
 
Subroutine sub_106DF1
CODE:6DF1 sub_106DF1:
CODE:6DF1 LDA #$FF ; A = 0xFF
CODE:6DF2 LDY current_save_slot ; Y = save slot
 
CODE:6DF3 loop:
CODE:6DF3 CLC
CODE:6DF4 ADC #$E ; A += 0xE (starts with 0xD)
CODE:6DF5 DEY
CODE:6DF6 BPL loop ; A = 0xFF + 0xE*save_slot
CODE:6DF7 TAY ; Y = A
CODE:6DF8 LDX #$D
 
CODE:6DF9 loop2:
CODE:6DF9 LDA off_106DC7,Y
CODE:6DFA STA 0,X
CODE:6DFB DEY
CODE:6DFC DEX
CODE:6DFD BPL loop2
CODE:6DFE LDA #$7F ; Set var_14 to 0x067F (screen_status_0).
CODE:6DFF STA var_14
CODE:6E00 LDA #6
CODE:6E01 STA var_15
CODE:6E02 RTS
 
Subroutine check_boomerang_sound
; If boomerang_sound_timer has expired, play the boomerang sound.
CODE:6E10 check_boomerang_sound:
CODE:6E10 LDA boomerang_sound_timer
CODE:6E11 BNE ret
CODE:6E12 TYA ; A = Sound2_FireArrow
CODE:6E13 JSR add_play_sound_2 ; Play Sound2_FireArrow
CODE:6E14 LDA #10
CODE:6E15 STA boomerang_sound_timer ; Set to 10.
 
CODE:6E16 ret:
CODE:6E16 RTS
 
Subroutine clear_some_oam_sprites
; Clear the sprites created by update_object_sprite.
CODE:6E1D clear_some_oam_sprites:
CODE:6E1D LDX #$60 ; These sprites begin at sprite_oam_data+0x60.
CODE:6E1E LDA #$F8 ; Set the Y position of each sprite to 0xF8 to hide it.
 
CODE:6E1F loop:
CODE:6E1F STA sprite_oam_data,X
CODE:6E20 INX ; Skip to the next sprite.
CODE:6E21 INX
CODE:6E22 INX
CODE:6E23 INX
CODE:6E24 CPX #0
CODE:6E25 BNE loop
CODE:6E26 LDA first_sprite_index ; Set next_sprite_index to first_sprite_index+1 and
  ; increment first_sprite_index. I'm not sure why this
  ; is done.
CODE:6E27 JSR set_next_sprite_index_after_A
CODE:6E28 STA first_sprite_index
CODE:6E29 RTS
 
Subroutine set_next_sprite_index
; Increase next_sprite_index.
CODE:6E36 set_next_sprite_index:
CODE:6E36 LDA next_sprite_index
 
CODE:6E39 set_next_sprite_index_after_A:
CODE:6E39 CLC
CODE:6E3A ADC #1
CODE:6E3B CMP #$28
CODE:6E3C BNE skip
 
CODE:6E40 reset_sprite_index_to_zero: ; Set next_sprite_index to 0.
CODE:6E40 LDA #0
 
CODE:6E41 skip:
CODE:6E41 STA next_sprite_index
 
CODE:6E45 locret_106E45:
CODE:6E45 RTS
 
Subroutine stop_walking_to_top_half_of_screen
; If walking_state is Up and we're Y < 0x0x8E, stop walking. ; This is used for old men/hungry goriya that block walking ; onto their half of the screen.
CODE:6E46 stop_walking_to_top_half_of_screen:
CODE:6E46 LDA object_y
CODE:6E47 CMP #$8E
CODE:6E48 BCS locret_106E45 ; Stop if object_y >= 0x8E. The player can walk up to this point.
CODE:6E49 LDA var_15
CODE:6E4A AND #ControllerBits_Dpad_Up
CODE:6E4B BEQ locret_106E45 ; Stop if not up. This doesn't prevent walking in other directions.
CODE:6E4C JMP set_var_15_to_0 ; Clear the walking state to prevent moving further in this direction.
 
Subroutine convert_number_to_string
; Convert A to digits in var_1, var_2 and var_3. Leading ; zeroes are set to 0x24. A = var_2 (tens digit), Y = var_1 (hundreds digit).
CODE:6E55 convert_number_to_string:
CODE:6E55 JSR divide_by_10 ; Out Y = in A / 10, Out A = in A % 10.
CODE:6E56 STA var_3 ; Store A % 10 (ones digit)
CODE:6E57 TYA ; A = A / 10
CODE:6E58 JSR divide_by_10 ; Out Y = in A / 10, Out A = in A % 10.
CODE:6E59 CPY #0
CODE:6E5A BNE loc_106E69 ; Branch if Y != 0 (has hundreds digit)
CODE:6E5B LDY #$24 ; No hundreds digit. Change hundreds from 0 to 0x24.
CODE:6E5C CMP #0
CODE:6E5D BNE loc_106E69 ; Branch if A != 0 (has tens digit)
CODE:6E5E TYA ; No tens digit. Change tens from 0 to 0x24.
 
CODE:6E69 loc_106E69: ; Store tens digit
CODE:6E69 STA var_2
CODE:6E6A STY var_1 ; Store hundreds digit
 
CODE:6E6D locret_106E6D:
CODE:6E6D RTS
 
Subroutine divide_by_10
; Out Y = in A / 10, Out A = in A % 10.
CODE:6E6E divide_by_10:
CODE:6E6E LDY #0
 
CODE:6E6F loop:
CODE:6E6F CMP #10
CODE:6E70 BCC locret_106E6D
CODE:6E71 SBC #10
CODE:6E72 INY
CODE:6E73 BNE loop
 
Subroutine update_hud_hearts
CODE:6E79 update_hud_hearts:
CODE:6E79 STY var_13
CODE:6E7A LDA var_14
CODE:6E7B PHA
CODE:6E7C AND #$F
CODE:6E7D STA var_0
CODE:6E7E LDA #$F
CODE:6E7F SEC
CODE:6E80 SBC var_0
CODE:6E81 STA var_0
CODE:6E82 PLA
CODE:6E83 LSR A
CODE:6E84 LSR A
CODE:6E85 LSR A
CODE:6E86 LSR A
CODE:6E87 STA var_1
CODE:6E88 LDA #$F
CODE:6E89 SEC
CODE:6E8A SBC var_1
CODE:6E8B STA var_1
CODE:6E8C LDX #0
CODE:6E8D TYA
CODE:6E8E CLC
CODE:6E8F ADC #7
CODE:6E90 STA var_11
CODE:6E91 LDY #7
 
CODE:6EA1 loc_106EA1:
CODE:6EA1 CPY #$FF
CODE:6EA2 BNE loc_106EAE
CODE:6EA3 LDA var_13
CODE:6EA4 CLC
CODE:6EA5 ADC #$12
CODE:6EA6 STA var_11
CODE:6EA7 LDY #$12
 
CODE:6EAE loc_106EAE:
CODE:6EAE LDA var_14
CODE:6EAF BEQ loc_106EB6
CODE:6EB0 CPX var_1
CODE:6EB1 BCS loc_106EBA
 
CODE:6EB6 loc_106EB6:
CODE:6EB6 LDA #$24
CODE:6EB7 BNE loc_106ED7
 
CODE:6EBA loc_106EBA:
CODE:6EBA CPX 0
CODE:6EBB BEQ loc_106EC4
CODE:6EBC BCC loc_106ED5
 
CODE:6EC0 loc_106EC0:
CODE:6EC0 LDA #$F2
CODE:6EC1 BNE loc_106ED7
 
CODE:6EC4 loc_106EC4:
CODE:6EC4 LDA var_15
CODE:6EC5 BEQ loc_106ED5
CODE:6EC6 CMP #$80
CODE:6EC7 BCS loc_106EC0
CODE:6EC8 LDA #0
CODE:6EC9 STA force_beam_sword ; Set to 0
CODE:6ECA LDA #$65
CODE:6ECB BNE loc_106ED7
 
CODE:6ED5 loc_106ED5:
CODE:6ED5 LDA #$66
 
CODE:6ED7 loc_106ED7:
CODE:6ED7 STY var_12
CODE:6ED8 LDY var_11
CODE:6ED9 STA ppu_command_buffer,Y
CODE:6EDA DEC var_11
CODE:6EDB LDY var_12
CODE:6EDC DEY
CODE:6EDD INX
CODE:6EDE CPX #$10
CODE:6EDF BNE loc_106EA1
CODE:6EE0 RTS
 
Subroutine stop_sounds
CODE:6EE9 stop_sounds:
CODE:6EE9 LDA #Sound3_Stop
CODE:6EEA STA play_sound_3 ; Set Sound3_Stop
CODE:6EEB STA play_sound_2 ; Set Sound3_Stop
CODE:6EEC ASL A
CODE:6EED STA audio_misc_0605
CODE:6EEE STA audio_misc_0607
CODE:6EEF RTS
 
CODE:6EF9 wall_master_hidden_under_wall_offset: .BYTE 8
CODE:6EFA   .BYTE 0
 
Subroutine update_clipping_sprites_under_wall
; Update clipping for the current object. This handles cutting ; off Link (and wall masters) as he goes under left/right side ; doors in dungeons.
CODE:6EFB update_clipping_sprites_under_wall:
CODE:6EFB LDY #$A ; Y = 0x0A
CODE:6EFC LDX #0
CODE:6EFD LDA object_x,X
CODE:6EFE STA var_0 ; Save object X
CODE:6EFF LDX #1
 
CODE:6F00 loop: ; Restore object X
CODE:6F00 LDA var_0
CODE:6F01 CLC
CODE:6F02 ADC wall_master_hidden_under_wall_offset,X
CODE:6F03 CMP #$E9
CODE:6F04 BCS near_edge ; A + (8 or 0) >= 0xE9
CODE:6F05 CMP #$10 ; A + (8 or 0) >= 0x10
CODE:6F06 BCS not_near_edge
 
CODE:6F07 near_edge: ; A + (8 or 0) >= 0xE9 or < 0x10
CODE:6F07 LDA sprite_oam_data_40,Y
CODE:6F08 ORA #$20
CODE:6F09 STA sprite_oam_data_40,Y
 
CODE:6F0A not_near_edge:
CODE:6F0A INY
CODE:6F0B INY
CODE:6F0C INY
CODE:6F0D INY
CODE:6F0E CPY #0
CODE:6F0F BNE loc_106F25
CODE:6F10 LDY #$20
 
CODE:6F25 loc_106F25:
CODE:6F25 DEX
CODE:6F26 BPL loop
CODE:6F27 RTS
 
Subroutine check_object_against_screen_bounding_box_x
; If the current object is out of the bounding box for the ; current screen on the X axis and is moving in the direction ; it's out of bounds (walking_state), clear walking_state to ; stop it moving further in that direction.
CODE:6F29 check_object_against_screen_bounding_box_x:
CODE:6F29 LDY #ControllerBits_Dpad_Left ; Y = 2
CODE:6F2A LDA object_x,X
CODE:6F2B STA var_0 ; Store object X
CODE:6F2C CPX #0 ; Skip this adjustment for object 0. (When does this
  ; happen? 0 is Link.)
CODE:6F2D BEQ skip_boomerang_x_adjustment_1
CODE:6F2E CPX #$D
CODE:6F2F BCS do_boomerang_x_adjustment_1 ; X >= 0xD
CODE:6F30 LDA object_type,X ; check if ObjectType_Goriya_Boomerang
CODE:6F31 CMP #ObjectType_Goriya_Boomerang
CODE:6F32 BNE skip_boomerang_x_adjustment_1
 
CODE:6F33 do_boomerang_x_adjustment_1: ; Restore object X
CODE:6F33 LDA var_0
CODE:6F34 CLC ; Adjust the bounding box for Goriya boomerangs.
CODE:6F35 ADC #11 ; X += 11
CODE:6F36 STA var_0 ; Store modified object X
 
CODE:6F37 skip_boomerang_x_adjustment_1: ; Store modified object X
CODE:6F37 LDA var_0
CODE:6F38 CMP screen_min_x ; This is copied from ROM5:B054 byte_17054 on the overworld, and ROM5:B059 in dungeons. See ROM5:B05E setup_byte_346.
CODE:6F39 BCC finish_object_bounds_check ; Object X < Min X
CODE:6F3A CPX #0
CODE:6F3B BEQ skip_boomerang_x_adjustment_2 ; Skip this adjustment for object 0.
CODE:6F3C CPX #$D
CODE:6F3D BCS do_boomerang_x_adjustment_2 ; X >= 0xD
CODE:6F3E LDA object_type,X ; check if ObjectType_Goriya_Boomerang
CODE:6F3F CMP #ObjectType_Goriya_Boomerang
CODE:6F40 BNE skip_boomerang_x_adjustment_2
 
CODE:6F41 do_boomerang_x_adjustment_2: ; Restore object X
CODE:6F41 LDA var_0
CODE:6F42 SEC ; Adjust the bounding box for Goriya boomerangs.
CODE:6F43 SBC #23 ; X -= 23
CODE:6F44 STA var_0 ; Store modified object X
 
CODE:6F45 skip_boomerang_x_adjustment_2: ; Restore object X
CODE:6F45 LDY #ControllerBits_Dpad_Right
CODE:6F46 LDA var_0
CODE:6F47 CMP screen_max_x
CODE:6F48 BCC locret_106FB5 ; Object X < Max X
 
CODE:6F6B finish_object_bounds_check:
CODE:6F6B TYA
CODE:6F6C AND var_15
CODE:6F6D BEQ locret_106FB5 ; The object isn't moving in the direction that it's out of bounds.
CODE:6F6E JMP set_var_15_to_0 ; The object is moving in the direction it's out of bounds.
  ; Stop it from moving further.
 
Subroutine check_object_against_screen_bounding_box_y
; If the current object is out of the bounding box for the ; current screen on the Y axis and is moving in the direction ; it's out of bounds (walking_state), clear walking_state to ; stop it moving further in that direction.
CODE:6F73 check_object_against_screen_bounding_box_y:
CODE:6F73 LDY #ControllerBits_Dpad_Up
CODE:6F74 LDA object_y,X
CODE:6F75 STA var_0 ; Store object Y
CODE:6F76 CPX #0
CODE:6F77 BEQ skip_boomerang_y_adjustment_1
CODE:6F78 CPX #$D
CODE:6F79 BCS do_boomerang_y_adjustment_1
CODE:6F7A LDA object_type,X ; check if ObjectType_Goriya_Boomerang
CODE:6F7B CMP #ObjectType_Goriya_Boomerang
CODE:6F7C BNE skip_boomerang_y_adjustment_1
 
CODE:6F7D do_boomerang_y_adjustment_1: ; Restore object Y
CODE:6F7D LDA var_0
CODE:6F7E CLC ; Adjust the bounding box for Goriya boomerangs.
CODE:6F7F ADC #15 ; X += 15
CODE:6F80 STA var_0 ; Store modified object Y
 
CODE:6F81 skip_boomerang_y_adjustment_1: ; Restore object Y
CODE:6F81 LDA var_0
CODE:6F82 CMP screen_min_y
CODE:6F83 BCC finish_object_bounds_check ; Object Y < Min Y
CODE:6F84 CPX #0
CODE:6F85 BEQ skip_boomerang_y_adjustment_2
CODE:6F86 CPX #$D
CODE:6F87 BCS do_boomerang_y_adjustment_2 ; A >= 0xD
CODE:6F88 LDA object_type,X ; check if ObjectType_Goriya_Boomerang
CODE:6F89 CMP #ObjectType_Goriya_Boomerang
CODE:6F8A BNE skip_boomerang_y_adjustment_2
 
CODE:6F8B do_boomerang_y_adjustment_2: ; Store modified object Y
CODE:6F8B LDA var_0
CODE:6F8C SEC ; Adjust the bounding box for Goriya boomerangs.
CODE:6F8D SBC #33 ; Y -= 33
CODE:6F8E STA var_0 ; Store modified object Y
 
CODE:6F8F skip_boomerang_y_adjustment_2:
CODE:6F8F LDY #ControllerBits_Dpad_Down
CODE:6F90 LDA var_0
CODE:6F91 CMP screen_max_y
CODE:6F92 BCS finish_object_bounds_check ; Object Y >= Min Y
 
CODE:6FB5 locret_106FB5:
CODE:6FB5 RTS
 
Subroutine check_object_against_screen_bounding_box_both_or_walking_state
; If the current object is out of the bounding box for the ; current screen on either axis and is moving in the direction ; it's out of bounds (A), clear walking_state to stop it ; moving further in that direction.
CODE:6FB6 check_object_against_screen_bounding_box_both_or_walking_state:
CODE:6FB6 STA var_15
 
CODE:6FB8 check_object_against_screen_bounding_box_both: ; If the current object is out of the bounding box for the
CODE:6FB8 JSR check_object_against_screen_bounding_box_x ; current screen on either axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction. Set var_15 to the
  ; final walking direction.
CODE:6FB9 JSR check_object_against_screen_bounding_box_y ; If the current object is out of the bounding box for the
  ; current screen on the Y axis and is moving in the direction
  ; it's out of bounds (walking_state), clear walking_state to
  ; stop it moving further in that direction.
CODE:6FBA LDA var_15
CODE:6FBB RTS
 
Subroutine walk_positive
; Increase the object tile offset for the current object ; by its walking speed. ; ; Return with carry set if the object's X or Y position should be ; increased by 1.
CODE:6FC1 walk_positive:
CODE:6FC1 LDA object_tile_offset_fraction,X
CODE:6FC2 CLC
CODE:6FC3 ADC object_walk_speed,X ; Move the object right by its walk speed
CODE:6FC4 STA object_tile_offset_fraction,X
CODE:6FC5 PHP ; Push status
CODE:6FC6 LDA object_tile_offset_whole,X
CODE:6FC7 CMP current_object_tile_size_pos ; If equal, clear carry
CODE:6FC8 BEQ clear_carry
CODE:6FC9 CMP current_object_tile_size_neg ; If equal, clear carry
CODE:6FCA BNE carry_into_whole
 
CODE:6FCB clear_carry: ; Pull status
CODE:6FCB PLP
CODE:6FCC CLC ; Clear carry. This prevents us from adding 1 to the whole
  ; part below, and clears the bit when we return to the caller.
CODE:6FCD PHP ; Push status
 
CODE:6FCE carry_into_whole: ; Pull status
CODE:6FCE PLP
CODE:6FCF PHP ; Push status (this seems like a no-op)
CODE:6FD0 LDA object_tile_offset_whole,X ; Add the carry out of the fraction into the whole part
CODE:6FD1 ADC #0
CODE:6FD2 STA object_tile_offset_whole,X ; Add the carry bit to something_walking
CODE:6FD3 PLP ; Pop status. This restores the carry bit for our caller.
CODE:6FD4 RTS
 
Subroutine walk_negative
; Decrease the object tile offset for the current object ; by its walking speed. ; ; Return with carry clear if the object's X or Y position should be ; decreased by 1.
CODE:6FE8 walk_negative:
CODE:6FE8 LDA object_tile_offset_fraction,X
CODE:6FE9 SEC
CODE:6FEA SBC object_walk_speed,X ; Move the object left by its walk speed
CODE:6FEB STA object_tile_offset_fraction,X
CODE:6FEC PHP ; Push status
CODE:6FED LDA object_tile_offset_whole,X
CODE:6FEE CMP current_object_tile_size_pos ; If equal, set carry
CODE:6FEF BEQ set_carry
CODE:6FF0 CMP current_object_tile_size_neg ; If equal, set carry
CODE:6FF1 BNE carry_into_whole
 
CODE:6FF2 set_carry: ; Pull status
CODE:6FF2 PLP
CODE:6FF3 SEC ; Set carry. Like walk_positive, this prevents us from
  ; modifying the whole part below and makes us return with
  ; the carry bit set.
CODE:6FF4 PHP ; Push status
 
CODE:6FF5 carry_into_whole: ; Pull status
CODE:6FF5 PLP
CODE:6FF6 PHP ; Push status (this seems like a no-op)
CODE:6FF7 LDA object_tile_offset_whole,X ; Subtract the carry from the fraction out of the whole part
CODE:6FF8 SBC #0
CODE:6FF9 STA object_tile_offset_whole,X ; If carry is unset, subtract 1 from something_walking
CODE:6FFA PLP
CODE:6FFB RTS
 
CODE:700F walking_bits: .BYTE 4
CODE:7010   .BYTE 8
CODE:7011   .BYTE 1
CODE:7012   .BYTE 2
 
Subroutine get_opposite_direction_and_index
; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
CODE:7013 get_opposite_direction_and_index:
CODE:7013 LDY #3 ; If more than one direction bit is set, the first match
  ; is returned.
 
  ; In A Out A Out Y
  ; 1 (Right) 2 (Left) 3
  ; 2 (Left) 1 (Right) 2
  ; 4 (Down) 8 (Up) 1
  ; 8 (Up) 4 (Down) 0
 
CODE:7014 check_next_direction: ; a >>= 1
CODE:7014 LSR A
CODE:7015 BCS found_direction
CODE:7016 DEY ; y--
CODE:7017 BPL check_next_direction ; a >>= 1
 
CODE:7018 found_direction:
CODE:7018 LDA walking_bits,Y
CODE:7019 RTS
 
Subroutine absolute_value
; A = abs(A)
CODE:701F absolute_value:
CODE:701F BPL ret
 
CODE:7021 inverse: ; Return -A.
CODE:7021 EOR #$FF
CODE:7022 CLC
CODE:7023 ADC #1
 
CODE:7024 ret:
CODE:7024 RTS
 
Subroutine update_projectile_movement
CODE:7027 update_projectile_movement:
CODE:7027 JSR check_object_against_screen_bounding_box_both_or_walking_state ; Check if the projectile hit a wall.
CODE:7028 BEQ projectile_hit_wall
CODE:7029 LDA object_tile_offset_whole,X
CODE:702A PHA ; Push tile offset.
CODE:702B LDA #0
CODE:702C STA object_tile_offset_whole,X ; Set to 0.
CODE:702D JSR process_movement
CODE:702E PLA ; Restore tile offset.
CODE:702F LDY var_14
CODE:7030 BNE loc_107041
CODE:7031 CLC
CODE:7032 ADC object_tile_offset_whole,X
 
CODE:7041 loc_107041:
CODE:7041 STA object_tile_offset_whole,X
CODE:7042 RTS
 
CODE:7043 projectile_hit_wall:
CODE:7043 LDA #$80
CODE:7044 STA var_14 ; Set var_14 to 0x80 when we hit a wall
CODE:7045 RTS
 
Subroutine sub_10704A
; This is related to boomerang updates. It's called while ; the boomerang is returning.
CODE:704A sub_10704A:
CODE:704A PHA ; Push A.
CODE:704B TAY
CODE:704C LDA #ControllerBits_Dpad_Left
CODE:704D STA var_10
CODE:704E LDA object_x,Y
CODE:704F LDY object_x,X
CODE:7050 JSR sub_1070C3 ; In var_10: a direction
  ; var_0++ if abs(var_1 - var_2) <= 8
 
  ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
CODE:7051 STA var_3
CODE:7052 LDA var_10
CODE:7053 STA var_11
CODE:7054 PLA ; Restore A.
CODE:7055 TAY
CODE:7056 LDA #ControllerBits_Dpad_Up
CODE:7057 STA var_10
CODE:7058 LDA object_y,Y
CODE:7059 LDY object_y,X
CODE:705A JSR sub_1070C3 ; In var_10: a direction
  ; var_0++ if abs(var_1 - var_2) <= 8
 
  ; This is related to boomerang updates. It's called while
  ; the boomerang is returning.
CODE:705B STA var_4
CODE:705C RTS
 
Subroutine sub_10706F
; This is related to boomerang updates. It's called while ; the boomerang is returning.
CODE:706F sub_10706F:
CODE:706F STY var_0
CODE:7070 LDA #$FF
CODE:7071 STA var_1
CODE:7072 LDA var_3
CODE:7073 CMP var_4
CODE:7074 BCS loc_107087
CODE:7075 PHA
CODE:7076 LDA var_4
CODE:7077 STA var_3
CODE:7078 PLA
CODE:7079 STA var_4
CODE:707A LDA #1
CODE:707B STA var_1
 
CODE:7087 loc_107087:
CODE:7087 LDA var_3
CODE:7088 SEC
CODE:7089 SBC var_4
CODE:708A CMP #8
CODE:708B BCC ret
 
CODE:7090 loc_107090:
CODE:7090 LDA var_0
CODE:7091 CLC
CODE:7092 ADC var_1
CODE:7093 STA var_0
CODE:7094 BEQ ret
CODE:7095 CMP #8
CODE:7096 BEQ ret
CODE:7097 LDA var_3
CODE:7098 SEC
 
CODE:70A0 loc_1070A0:
CODE:70A0 SBC var_4
CODE:70A1 STA var_3
CODE:70A2 CMP var_4
CODE:70A3 BCS loc_107090
 
CODE:70A4 ret:
CODE:70A4 LDY var_0
CODE:70A5 RTS
 
Subroutine sub_1070AB
; This is related to boomerang updates. It's called while ; the boomerang is returning.
CODE:70AB sub_1070AB:
CODE:70AB STA object_walk_speed,X
CODE:70AC LDA walk_state_and_weapon_state,X
CODE:70AD AND #$F0
CODE:70AE CMP #WalkState_3_MovementLocked
CODE:70AF BNE ret ; Skip if movement locked
CODE:70B0 LSR object_walk_speed,X
CODE:70B1 DEC enemy_state_11,X
CODE:70B2 BNE ret
CODE:70B3 LDA #WalkState_Unknown2_10|WalkState_3_MovementLocked
CODE:70B4 STA walk_state_and_weapon_state,X
 
CODE:70B5 ret:
CODE:70B5 RTS
 
Subroutine sub_1070C3
; In var_10: a direction ; var_0++ if abs(var_1 - var_2) <= 8 ; ; This is related to boomerang updates. It's called while ; the boomerang is returning.
CODE:70C3 sub_1070C3:
CODE:70C3 STA var_1
CODE:70C4 STY var_2
CODE:70C5 CPY var_1
CODE:70C6 BCS skip_flip ; Branch if var_2 >= var_1
CODE:70C7 STA var_2 ; Ensure var_2 >= var_1
CODE:70C8 STY var_1
CODE:70C9 LSR var_10 ; Shift left to right, or up to down.
 
CODE:70CA skip_flip:
CODE:70CA LDA var_2
CODE:70CB SEC
CODE:70CC SBC var_1
CODE:70CD CMP #9
CODE:70CE BCS locret_1070DC ; Branch if var_2 - var_1 >= 9
CODE:70CF INC var_0 ; var_1 - var_1 <= 8
 
CODE:70DC locret_1070DC:
CODE:70DC RTS
 
Subroutine use_item_bomb
; Load to see if we have any bombs
CODE:70DD use_item_bomb:
CODE:70DD LDA num_bombs
CODE:70DE BEQ locret_1070DC
CODE:70DF LDX #$10
CODE:70E0 LDA walk_state_and_weapon_state,X
CODE:70E1 BEQ loc_1070F9
CODE:70E2 AND #$F0
CODE:70E3 CMP #$10
CODE:70E4 BNE loc_1070F9
CODE:70E5 INX
CODE:70E6 LDA walk_state_and_weapon_state,X
CODE:70E7 BEQ loc_1070F9
CODE:70E8 AND #$F0
CODE:70E9 CMP #$10
CODE:70EA BEQ locret_10713B
 
CODE:70F9 loc_1070F9:
CODE:70F9 TXA
CODE:70FA EOR #1
CODE:70FB TAY
CODE:70FC LDA walk_state_and_weapon_state,Y
CODE:70FD BEQ loc_107106 ; Decrease bombs after dropping one
CODE:70FE CMP #$13
CODE:70FF BCC locret_10713B
 
CODE:7106 loc_107106: ; Decrease bombs after dropping one
CODE:7106 DEC num_bombs
CODE:7107 LDA #Sound3_PlaceBomb
CODE:7108 STA play_sound_3 ; Play Sound3_PlaceBomb
CODE:7109 LDA #0
CODE:710A STA enemy_action_timers,X
CODE:710B LDA #$11
 
CODE:7114 loc_107114:
CODE:7114 STA walk_state_and_weapon_state,X
 
Subroutine sub_107116
CODE:7116 sub_107116:
CODE:7116 LDA #1
CODE:7117 STA object_animation_frame_timer
 
CODE:711B loc_10711B:
CODE:711B LDA #$10
CODE:711C STA walk_state_and_weapon_state
 
CODE:711F loc_10711F:
CODE:711F LDY #$F0
CODE:7120 STA var_1
CODE:7121 STY var_2
CODE:7122 LDA object_direction
CODE:7123 STA object_direction,X
CODE:7124 JSR sub_10713C
CODE:7125 ADC object_x
CODE:7126 STA object_x,X
CODE:7127 LDA object_direction
CODE:7128 LSR A
CODE:7129 LSR A
CODE:712A JSR sub_10713C
CODE:712B ADC object_y
CODE:712C STA object_y,X
 
CODE:713B locret_10713B:
CODE:713B RTS
 
Subroutine sub_10713C
CODE:713C sub_10713C:
CODE:713C LDY #0
CODE:713D STY var_0
CODE:713E AND #3
CODE:713F BEQ loc_10714A
CODE:7140 INY
CODE:7141 AND #1
CODE:7142 BNE loc_10714A
CODE:7143 INY
 
CODE:714A loc_10714A:
CODE:714A LDA var_0,Y
CODE:714B CLC
 
CODE:714E locret_10714E:
CODE:714E RTS
 
Subroutine use_item_candle
CODE:714F use_item_candle:
CODE:714F LDX #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
CODE:7150 LDA walk_state_and_weapon_state,X ; Find a BombOrFire1/BombOrFire2 slot that isn't in use.
CODE:7151 BEQ found_slot
CODE:7152 INX
CODE:7153 LDA walk_state_and_weapon_state,X
CODE:7154 BNE locret_10714E
 
CODE:7155 found_slot:
CODE:7155 LDA have_candle_type
CODE:7156 CMP #1
CODE:7157 BNE can_use_candle ; If we have the magic candle, skip checking whether we've
  ; used the candle already. The magic candle can be used
  ; repeatedly.
CODE:7158 LDA candle_used_in_current_room
CODE:7159 BNE locret_10714E
 
CODE:715A can_use_candle:
CODE:715A LDA #1
CODE:715B STA candle_used_in_current_room ; The candle has been used.
CODE:715C LDA #0
CODE:715D STA object_tile_offset_whole,X ; Set to 0
CODE:715E STA object_tile_offset_fraction,X ; Set to 0
CODE:715F LDA #$20
CODE:7160 STA object_walk_speed,X
CODE:7161 LDA #$21
CODE:7162 STA walk_state_and_weapon_state,X
CODE:7163 LDA #Sound2_Candle
CODE:7164 JSR add_play_sound_2 ; Play Sound2_Candle
CODE:7165 LDA #4
CODE:7166 STA object_animation_frame_timer,X
CODE:7167 JSR loc_10711B
CODE:7168 RTS
 
Subroutine dungeon_get_item_position
; Get this room's item position: A = X position, Y = Y position
CODE:718A dungeon_get_item_position:
CODE:718A LDY map_location
 
CODE:718C loc_10718C:
CODE:718C LDA dungeon_screen_data_5,Y
CODE:718D AND #ScreenData_Dungeon_5_ItemPosition
CODE:718E LSR A ; Shift the item position out of pos 4
CODE:718F LSR A
CODE:7190 LSR A
CODE:7191 LSR A
CODE:7192 TAY ; Y = A
CODE:7193 LDA ppu_data_for_current_dungeon.stair_or_item_pos,Y
CODE:7194 PHA ; push A
CODE:7195 AND #$F ; Mask out the Y position
CODE:7196 ASL A ; Y *= 16
CODE:7197 ASL A
CODE:7198 ASL A
CODE:7199 ASL A
CODE:719A TAY ; Y = A
CODE:719B PLA ; pop A (item pos)
CODE:719C AND #$F0
CODE:719D RTS
 
Function chunk for delete_enemy
CODE:719E continue: ; Set to 0
CODE:719E STA object_knockback,X
CODE:719F STA knockback_frames,X ; Set to 0
CODE:71A0 STA enemy_action_timers,X ; Set to 0
CODE:71A1 STA walk_state_and_weapon_state,X ; Set to 0
CODE:71A2 STA invincibility_frames,X ; Set to 0
CODE:71A3 LDA #$FF
CODE:71A4 STA object_slot_in_use,X ; Set to 0xFF
CODE:71A5 LDA #1
CODE:71A6 STA enemy_spawn_state,X ; Set to 1
CODE:71A7 RTS
 
Subroutine handle_bomb_greyscale_flash
; Handle the screen flashing to greyscale during bomb explosions.
CODE:71BB handle_bomb_greyscale_flash:
CODE:71BB LDA walk_state_and_weapon_state,X
CODE:71BC CMP #BombOrFireState_BombExploding|BombOrFireState_Type_Bomb
CODE:71BD BNE ret2 ; Branch if this bomb isn't in state 3.
CODE:71BE LDA current_ppumask
CODE:71BF LSR A
CODE:71C0 LDY enemy_action_timers,X
CODE:71C1 CPY #22
CODE:71C2 BEQ greyscale_on ; Branch if the timer is at 22 frames.
CODE:71C3 CPY #17
CODE:71C4 BNE check_greyscale_off
 
CODE:71C5 greyscale_on: ; Shift 1 into the bottom PPUMASK bit (PPUMaskBits_Greyscale).
CODE:71C5 ROL A
CODE:71C6 JMP save_ppumask
 
CODE:71C7 check_greyscale_off:
CODE:71C7 CPY #18
CODE:71C8 BEQ greyscale_off ; Branch if the timer is at 18 frames.
CODE:71C9 CPY #13
CODE:71CA BNE ret2
 
CODE:71CB greyscale_off: ; Shift 0 into the bottom PPUMASK bit (not greyscale).
CODE:71CB ASL A
 
CODE:71CC save_ppumask:
CODE:71CC STA current_ppumask
 
CODE:71CD ret2:
CODE:71CD RTS
 
Subroutine setup_minimap_triforce_position_unless_in_cellar_or_whirlwind
CODE:71DE setup_minimap_triforce_position_unless_in_cellar_or_whirlwind:
CODE:71DE LDA game_mode
CODE:71DF CMP #GameMode_InDungeonCellar ; Skip this if we're in a dungeon cellar.
CODE:71E0 BEQ ret
CODE:71E1 LDX held_by_recorder_whirlwind ; Skip this if Link is held by the recorder whirlwind.
CODE:71E2 BNE ret
CODE:71E3 LDA map_location
CODE:71E4 LDX #0
 
CODE:71ED setup_minimap_triforce_position:
CODE:71ED PHA
CODE:71EE AND #$70
CODE:71EF LSR A
CODE:71F0 LSR A
CODE:71F1 ADC #$17
CODE:71F2 STA sprite_oam_data_54,X
CODE:71F3 LDA #$11 ; 0x11 in the overworld
CODE:71F4 LDY dungeon_idx
CODE:71F5 BEQ in_overworld
CODE:71F6 LDA #$12 ; 0x11 in dungeons
 
CODE:71F7 in_overworld:
CODE:71F7 STA var_0
CODE:71F8 PLA
CODE:71F9 AND #$F
CODE:71FA CPY #0
CODE:71FB BEQ loc_107209
CODE:71FC ASL A
 
CODE:7209 loc_107209:
CODE:7209 ASL A
CODE:720A ASL A
CODE:720B ADC var_0
CODE:720C ADC ppu_data_for_current_dungeon.map_pos_x
CODE:720D STA sprite_oam_data_57,X
CODE:720E LDA #$3E
CODE:720F STA sprite_oam_data_55,X
CODE:7210 LDA #0
CODE:7211 CPX #0
CODE:7212 BEQ store_sprite_data
CODE:7213 LDA #3
CODE:7214 PHA
CODE:7215 LDY dungeon_idx
CODE:7216 CPY #9
CODE:7217 BEQ in_death_mountain ; Skip this if we're in death mountain.
CODE:7218 LDA triforce_pieces_collected
CODE:7219 AND call_scrolling_1_task_thunk+1,Y
CODE:721A BNE skip_set_2 ; Branch if we've collected the triforce piece for the current dungeon.
 
CODE:721B in_death_mountain:
CODE:721B LDA frame_counter
CODE:721C AND #$1F
CODE:721D CMP #$10
CODE:721E BCS skip_set_2
CODE:721F PLA
CODE:7220 LDA #2
CODE:7221 PHA
 
CODE:7222 skip_set_2:
CODE:7222 PLA
 
CODE:7223 store_sprite_data:
CODE:7223 STA sprite_oam_data_56,X
 
CODE:7224 ret:
CODE:7224 RTS
 
Subroutine call_update_curtain_from_rom2
; Call update_curtain, and return to ROM2.
CODE:7240 call_update_curtain_from_rom2:
CODE:7240 JSR update_curtain ; This is related to curtains opening and closing.
CODE:7241 LDA #2
CODE:7242 JMP rom2_set_prg_bank
 
Subroutine update_curtain
; This is related to curtains opening and closing.
CODE:7248 update_curtain:
CODE:7248 LDA enemy_action_timers ; Return if enemy_action_timers hasn't expired yet.
CODE:7249 BNE ret
CODE:724A LDA #1
CODE:724B STA var_10 ; Set to 1.
 
CODE:724C loop:
CODE:724C LDX var_10
CODE:724D LDA object_x_12,X ; Get $7C or $7D. This is the curtain left and right position.
  ; (This aliases with other data that isn't used here.)
CODE:724E STA byte_E8
CODE:724F LDA #5
CODE:7250 JSR rom2_set_prg_bank
CODE:7251 LDA #MMCControl_VerticalMirroring|MMCControl_PRGMode_FixedBank1
CODE:7252 JSR rom2_set_mmc_control_register ; Set VerticalMirroring.
CODE:7253 JSR copy_background_column_to_ppu ; This copies a column of background tiles to the PPU.
  ; This is used for curtains opening and horizontal scrolling.
CODE:7254 DEC var_10
CODE:7255 BPL loop
CODE:7256 LDA #$FF
CODE:7257 STA byte_E8 ; Set to 0xFF.
CODE:7258 LDA #5
CODE:7259 STA enemy_action_timers ; Wait 5 frames before advancing the curtain again.
CODE:725A DEC object_x_12 ; Decrease $7C and increase $7D to advance the curtain X positions.
CODE:725B INC link_melee_x
 
CODE:725C ret:
CODE:725C RTS
 
Subroutine increment_16bit_var0_by_1
; 16-bit var0++
CODE:7274 increment_16bit_var0_by_1:
CODE:7274 LDA #1
 
CODE:7276 increment_16bit_var0_by_A: ; 16-bit var0 += A
CODE:7276 CLC
CODE:7277 ADC var_0
CODE:7278 STA var_0
CODE:7279 BCC ret
CODE:727A INC var_1
 
CODE:727B ret:
CODE:727B RTS
 
Subroutine increment_16bit_var2_by_1
; 16-bit var2++
CODE:7280 increment_16bit_var2_by_1:
CODE:7280 LDA #1
 
CODE:7282 increment_16bit_var2_by_A: ; 16-bit var2 += A
CODE:7282 CLC
CODE:7283 ADC var_2
CODE:7284 STA var_2
CODE:7285 BCC ret
CODE:7286 INC var_3
 
CODE:7287 ret:
CODE:7287 RTS
 
Subroutine increment_16bit_var4_by_1
; 16-bit var4++
CODE:728C increment_16bit_var4_by_1:
CODE:728C LDA #1
 
CODE:728E increment_16bit_var4_by_A: ; 16-bit var4 += A
CODE:728E CLC
CODE:728F ADC var_4
CODE:7290 STA var_4
CODE:7291 BCC ret
CODE:7292 INC var_5
 
CODE:7293 ret:
CODE:7293 RTS
 
Subroutine decrement_16bit_var4_by_1
CODE:7298 decrement_16bit_var4_by_1:
CODE:7298 LDA var_4
CODE:7299 SEC
CODE:729A SBC #1
CODE:729B STA var_4
CODE:729C BCS ret
CODE:729D DEC var_5
 
CODE:729E ret:
CODE:729E RTS
 
CODE:72A4 floor_item_to_inventory_item: .BYTE InventoryItem_Bomb ; FloorItem_Bomb
CODE:72A5   .BYTE InventoryItem_Sword ; FloorItem_WoodSword
CODE:72A6   .BYTE InventoryItem_Sword ; FloorItem_WhiteSword
CODE:72A7   .BYTE InventoryItem_Sword ; FloorItem_MagicalSword
CODE:72A8   .BYTE InventoryItem_Meat ; FloorItem_Meat
CODE:72A9   .BYTE InventoryItem_Recorder ; FloorItem_Recorder
CODE:72AA   .BYTE InventoryItem_Candle ; FloorItem_BlueCandle
CODE:72AB   .BYTE InventoryItem_Candle ; FloorItem_RedCandle
CODE:72AC   .BYTE InventoryItem_Arrow ; FloorItem_Arrow
CODE:72AD   .BYTE InventoryItem_Arrow ; FloorItem_SilverArrow
CODE:72AE   .BYTE InventoryItem_Bow ; FloorItem_Bow
CODE:72AF   .BYTE InventoryItem_MagicKey ; FloorItem_MagicKey
CODE:72B0   .BYTE InventoryItem_Raft ; FloorItem_Raft
CODE:72B1   .BYTE InventoryItem_Ladder ; FloorItem_Ladder
CODE:72B2   .BYTE InventoryItem_HoldingUpTriforce ; FloorItem_GanonTriforce
CODE:72B3   .BYTE InventoryItem_5Rupee ; FloorItem_5Rupee
CODE:72B4   .BYTE InventoryItem_Rod ; FloorItem_Rod (0x10)
CODE:72B5   .BYTE InventoryItem_Book ; FloorItem_Book
CODE:72B6   .BYTE InventoryItem_Ring ; FloorItem_BlueRing
CODE:72B7   .BYTE InventoryItem_Ring ; FloorItem_RedRing
CODE:72B8   .BYTE InventoryItem_PowerBracelet ; FloorItem_PowerBracelet
CODE:72B9   .BYTE InventoryItem_Letter ; FloorItem_Letter
CODE:72BA   .BYTE InventoryItem_Compass ; FloorItem_Compass
CODE:72BB   .BYTE InventoryItem_Map ; FloorItem_Map
CODE:72BC   .BYTE InventoryItem_Rupee ; FloorItem_Rupee
CODE:72BD   .BYTE InventoryItem_Key ; FloorItem_Key
CODE:72BE   .BYTE InventoryItem_HeartContainer ; FloorItem_HeartContainer
CODE:72BF   .BYTE InventoryItem_TriforcePiece ; FloorItem_TriforcePiece
CODE:72C0   .BYTE InventoryItem_Shield ; FloorItem_Shield
CODE:72C1   .BYTE InventoryItem_Boomerang ; FloorItem_Boomerang
CODE:72C2   .BYTE InventoryItem_MagicBoomerang ; FloorItem_MagicBoomerang
CODE:72C3   .BYTE InventoryItem_Potion ; FloorItem_BluePotion
CODE:72C4   .BYTE InventoryItem_Potion ; FloorItem_RedPotion
CODE:72C5   .BYTE InventoryItem_Clock ; FloorItem_Clock
CODE:72C6   .BYTE InventoryItem_Heart ; FloorItem_Heart
CODE:72C7   .BYTE InventoryItem_Fairy ; FloorItem_Fairy
CODE:72C8 floor_item_flags: .BYTE InventoryItemFlags_Give_4|InventoryItemFlags_Add ; 0xF is the level of the item or the number of the item to
  ; give. This is used both to tell what level to set items to
  ; after a pickup, and the frame offset for the item's sprite.
 
  ; FloorItem_Bomb
CODE:72C9   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Max ; FloorItem_WoodSword
CODE:72CA   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Max ; FloorItem_WhiteSword
CODE:72CB   .BYTE InventoryItemFlags_Give_3|InventoryItemFlags_Max ; FloorItem_MagicalSword
CODE:72CC   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Meat
CODE:72CD   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Recorder
CODE:72CE   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Max ; FloorItem_BlueCandle
CODE:72CF   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Max ; FloorItem_RedCandle
CODE:72D0   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Max ; FloorItem_Arrow
CODE:72D1   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Max ; FloorItem_SilverArrow
CODE:72D2   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Bow
CODE:72D3   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_MagicKey
CODE:72D4   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Raft
CODE:72D5   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Ladder
CODE:72D6   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_GanonTriforce
CODE:72D7   .BYTE InventoryItemFlags_Give_5|InventoryItemFlags_Add ; FloorItem_5Rupee
CODE:72D8   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Rod
CODE:72D9   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Book
CODE:72DA   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Max ; FloorItem_BlueRing
CODE:72DB   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Max ; FloorItem_RedRing
CODE:72DC   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_PowerBracelet
CODE:72DD   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Letter
CODE:72DE   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Compass
CODE:72DF   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Map
CODE:72E0   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Add ; FloorItem_Rupee
CODE:72E1   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Add ; FloorItem_Key
CODE:72E2   .BYTE InventoryItemFlags_Add ; FloorItem_HeartContainer
CODE:72E3   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Triforce
CODE:72E4   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Shield
CODE:72E5   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Boomerang
CODE:72E6   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_MagicBoomerang
CODE:72E7   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Add ; FloorItem_BluePotion
CODE:72E8   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Max ; FloorItem_RedPotion
CODE:72E9   .BYTE InventoryItemFlags_Give_1|InventoryItemFlags_Item ; FloorItem_Clock
CODE:72EA   .BYTE InventoryItemFlags_Add ; FloorItem_Heart
CODE:72EB   .BYTE InventoryItemFlags_Give_2|InventoryItemFlags_Add ; FloorItem_Fairy
CODE:72EC floor_item_frame_offset: .BYTE $FF ; FloorItem_Bomb
CODE:72ED   .BYTE 1 ; FloorItem_WoodSword
CODE:72EE   .BYTE $FF ; FloorItem_WhiteSword
CODE:72EF   .BYTE 0 ; FloorItem_MagicalSword
CODE:72F0   .BYTE 0 ; FloorItem_Meat
CODE:72F1   .BYTE 2 ; FloorItem_Recorder
CODE:72F2   .BYTE 2 ; FloorItem_BlueCandle
CODE:72F3   .BYTE 0 ; FloorItem_RedCandle
CODE:72F4   .BYTE 1 ; FloorItem_Arrow
CODE:72F5   .BYTE 0 ; FloorItem_SilverArrow
CODE:72F6   .BYTE 2 ; FloorItem_Bow
CODE:72F7   .BYTE 0 ; FloorItem_MagicKey
CODE:72F8   .BYTE 0 ; FloorItem_Raft
CODE:72F9   .BYTE 2 ; FloorItem_Ladder
CODE:72FA   .BYTE 2 ; FloorItem_GanonTriforce
CODE:72FB   .BYTE 1 ; FloorItem_5Rupee
CODE:72FC   .BYTE 2 ; FloorItem_Rod
CODE:72FD   .BYTE 2 ; FloorItem_Book
CODE:72FE   .BYTE 2 ; FloorItem_BlueRing
CODE:72FF   .BYTE 2 ; FloorItem_RedRing
CODE:7300   .BYTE 2 ; FloorItem_PowerBracelet
CODE:7301   .BYTE 2 ; FloorItem_Letter
CODE:7302   .BYTE 2 ; FloorItem_Compass
CODE:7303   .BYTE 2 ; FloorItem_Map
CODE:7304   .BYTE 2 ; FloorItem_Rupee
CODE:7305   .BYTE 2 ; FloorItem_Key
CODE:7306   .BYTE 2 ; FloorItem_HeartContainer
CODE:7307   .BYTE 2 ; FloorItem_Triforce
CODE:7308   .BYTE 1 ; FloorItem_Shield
CODE:7309   .BYTE 0 ; FloorItem_Boomerang
CODE:730A   .BYTE 1 ; FloorItem_MagicBoomerang
CODE:730B   .BYTE 0 ; FloorItem_BluePotion
 
Subroutine mark_room_item_collected
CODE:730C mark_room_item_collected:
CODE:730C JSR get_screen_status ; Load to set ScreenStatus_PickedUpFloorItem.
CODE:730D ORA #ScreenStatusDungeon_PickedUpFloorItem
CODE:730E STA (var_0),Y
CODE:730F RTS
 
Subroutine get_room_status_floor_item_picked_up
CODE:7314 get_room_status_floor_item_picked_up:
 
CODE:7314 LDA ppu_data_for_current_dungeon.screen_status_ptr ; Read position to check 0x10
CODE:7315 STA var_8
CODE:7316 LDA ppu_data_for_current_dungeon.screen_status_ptr+1
CODE:7317 STA var_9
CODE:7318 LDY map_location
CODE:7319 LDA (var_8),Y
CODE:731A AND #ScreenStatusDungeon_PickedUpFloorItem
 
CODE:7324 locret_107324:
CODE:7324 RTS
 
CODE:7325 byte_107325: .BYTE $29
CODE:7326   .BYTE $32
CODE:7327   .BYTE $16
 
Subroutine check_object_collision_0x13
; Check collision with object 0x13. Is this the fixed room ; item?
CODE:7328 check_object_collision_0x13:
CODE:7328 LDA walk_state_and_weapon_state ; Skip if in forced walk animation
CODE:7329 AND #$C0
CODE:732A CMP #$40
CODE:732B BEQ locret_107324 ; Skip if (walk_state & 0xC0) == 0x40.
CODE:732C JSR get_room_status_floor_item_picked_up ; True if we already got the room item?
CODE:732D BNE locret_107324
CODE:732E LDX #$13
CODE:732F LDA walk_state_and_weapon_state,X
CODE:7330 BMI locret_107324
CODE:7331 LDA object_direction,X
CODE:7332 STA var_4
 
CODE:733F check_object_collision: ; var_4 is set to the item that colliding with this object will give.
CODE:733F LDA object_tile_offset_fraction,X
CODE:7340 CMP #$F0 ; Load the item's expiration timer.
CODE:7341 BCS locret_1073B8 ; If this is >= 0xFF, the item just appeared and is still
  ; blinking. It can't be picked up until this finishes.
CODE:7342 LDA object_y ; Compare the object's Y position with Link's Y position.
CODE:7343 CLC
CODE:7344 ADC #3
CODE:7345 SEC
CODE:7346 SBC object_y,X
CODE:7347 JSR absolute_value ; A = abs(A)
CODE:7348 CMP #9
CODE:7349 BCS locret_1073B8 ; Branch if we're >= 9 pixels away from the item.
CODE:734A LDA object_x ; Compare the object's X position with Link's X position.
CODE:734B SEC
CODE:734C SBC object_x,X
CODE:734D JSR absolute_value ; A = abs(A)
CODE:734E CMP #9
CODE:734F BCS locret_1073B8 ; Branch if we're >= 9 pixels away from the item.
CODE:7350 LDA #$FF
CODE:7351 STA walk_state_and_weapon_state,X ; Set to 0xFF.
CODE:7352 STA object_y,X ; Set the Y position to 0xFF.
CODE:7353 CPX #$13 ; 0x13 is the check_object_collision_0x13 entry point above.
CODE:7354 BNE loc_10736E ; Load the floor item to pick up.
CODE:7355 JSR mark_room_item_collected
 
CODE:736E loc_10736E: ; Load the floor item to pick up.
CODE:736E LDA var_4
 
CODE:7370 pick_up_item: ; Pick up an item. A is the FloorItem to pick up.
CODE:7370 LDX #Sound1_Fairy
CODE:7371 STX play_sound_1 ; Play Sound1_Fairy
CODE:7372 CMP #FloorItem_GanonTriforce
CODE:7373 BNE not_ganon_triforce
CODE:7374 LDX #Sound1_ItemAppeared
CODE:7375 STX play_sound_1 ; Play Sound1_ItemAppeared for FloorItem_GanonTriforce
 
CODE:7376 not_ganon_triforce:
CODE:7376 LDX game_mode
CODE:7377 CPX #GameMode_Normal
CODE:7378 BEQ skip_if_normal_mode
CODE:7379 LDX #$80
CODE:737A STX picking_up_item_timer
CODE:737B LDX #Music_PickedUpItem
CODE:737C STX play_music ; Play Music_PickedUpItem
CODE:737D STA picking_up_item ; Save the floor item from var_4.
 
CODE:737E skip_if_normal_mode: ; X = floor item
CODE:737E TAX
CODE:737F LDA floor_item_to_inventory_item,X ; A = floor_item_to_inventory_item[X]
CODE:7380 TAY ; Y = A
CODE:7381 LDA floor_item_flags,X ; A = floor_item_properties_1[X]
CODE:7382 PHA ; push A
CODE:7383 AND #$F
CODE:7384 STA var_10 ; Store the quantity of the item to add.
CODE:7385 PLA ; pop A
CODE:7386 AND #$F0
CODE:7387 BNE collect_floor_item
CODE:7388 CPY #InventoryItem_Map
CODE:7389 BEQ pick_up_per_dungeon_item ; Pick up an item specific to the current dungeon.
CODE:738A CPY #InventoryItem_Compass
CODE:738B BEQ pick_up_per_dungeon_item ; Pick up an item specific to the current dungeon.
CODE:738C CPY #InventoryItem_TriforcePiece
CODE:738D BEQ pick_up_per_dungeon_item ; Pick up an item specific to the current dungeon.
CODE:738E CPY #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
CODE:738F BEQ pick_up_per_dungeon_item ; Pick up an item specific to the current dungeon.
CODE:7390 LDA var_10
 
CODE:73B5 set_item_Y_to_A:
CODE:73B5 STA sword_type,Y
 
CODE:73B8 locret_1073B8:
CODE:73B8 RTS
 
Subroutine pick_up_five_rupee
CODE:73B9 pick_up_five_rupee:
CODE:73B9 LDY #4
 
CODE:73BA loop: ; Play the rupee sound and add 1 to the pending rupee count.
CODE:73BA JSR pick_up_rupee
CODE:73BB DEY
CODE:73BC BPL loop
CODE:73BD RTS
 
Subroutine collect_floor_item
CODE:73C2 collect_floor_item:
CODE:73C2 CMP #InventoryItemFlags_Add ; Check if this is an additive item pickup.
CODE:73C3 BNE collect_floor_item_not_add
CODE:73C4 CPY #InventoryItem_HeartContainer
CODE:73C5 BEQ pick_up_heart_container
CODE:73C6 CPY #InventoryItem_5Rupee
CODE:73C7 BEQ pick_up_five_rupee
CODE:73C8 CPY #InventoryItem_Rupee
CODE:73C9 BEQ pick_up_rupee_thunk
CODE:73CA CPY #InventoryItem_Heart
CODE:73CB BEQ pick_up_something_thunk
CODE:73CC CPY #InventoryItem_Key
CODE:73CD BNE pick_up_other
CODE:73CE JSR pick_up_something
 
CODE:73DD pick_up_other:
CODE:73DD CPY #InventoryItem_Fairy
CODE:73DE BEQ pick_up_heart
CODE:73DF LDA var_10 ; Load the value to add.
CODE:73E0 CLC
CODE:73E1 ADC sword_type,Y ; Add the previous quantity.
CODE:73E2 BCC no_clamp ; If we're passing 0xFF, clamp to 0xFF so we don't wrap the item past 0.
 
CODE:73E9 give_item:
CODE:73E9 LDA #$FF
 
CODE:73EA no_clamp:
CODE:73EA CPY #InventoryItem_Potion
CODE:73EB BNE continue1
CODE:73EC CMP #3 ; Don't allow the potion to be set beyond 2.
CODE:73ED BCC continue1
CODE:73EE LDA #2 ; Clamp potion to 2 (red potion).
 
CODE:73EF continue1:
CODE:73EF CPY #InventoryItem_Bomb
CODE:73F0 BNE continue2
CODE:73F1 CMP max_bombs ; Check if we're setting bombs to more than max_bombs.
CODE:73F2 BCC continue2
CODE:73F3 LDA max_bombs ; Don't set bombs > max_bombs
 
CODE:73F4 continue2:
CODE:73F4 JMP set_item_Y_to_A
 
Subroutine pick_up_heart_container
CODE:7404 pick_up_heart_container:
CODE:7404 LDA sword_type,Y ; Heart containers
CODE:7405 CMP #$F0
CODE:7406 BCS locret_1073B8 ; Skip if heart containers are full
CODE:7407 ADC #$11 ; Add both one heart container and one heart.
CODE:7408 JMP set_item_Y_to_A
 
Subroutine pick_up_rupee_thunk
; Attributes: thunk
CODE:7410 pick_up_rupee_thunk:
CODE:7410 JMP pick_up_rupee ; Play the rupee sound and add 1 to the pending rupee count.
 
Subroutine collect_floor_item_not_add
CODE:7413 collect_floor_item_not_add:
CODE:7413 CMP #InventoryItemFlags_Max
CODE:7414 BNE give_item ; This isn't a "max" item, so it's just a regular item.
  ; These are always just set to 0xFF.
CODE:7415 BEQ collect_floor_item_max ; Number to pick up
 
Subroutine pick_up_per_dungeon_item
; Pick up an item specific to the current dungeon.
CODE:7419 pick_up_per_dungeon_item:
CODE:7419 LDA dungeon_idx
CODE:741A BEQ in_overworld
CODE:741B CPY #InventoryItem_HoldingUpTriforce ; This is used when Link is holding a triforce piece over his head.
CODE:741C BEQ pick_up_ganon_triforce_thunk
CODE:741D CPY #InventoryItem_Map
CODE:741E BNE not_map
CODE:741F LDX #1
CODE:7420 STX reset_room_palette_idx_to_0x44 ; Set to 1 after picking up compass, map or triforce. I'm not
  ; sure what this is for.
 
CODE:7421 not_map:
CODE:7421 SEC
CODE:7422 SBC #1
CODE:7423 CMP #8
CODE:7424 BCC loc_107433
CODE:7425 INY
CODE:7426 INY
 
CODE:7433 loc_107433:
CODE:7433 AND #7
CODE:7434 TAX
CODE:7435 LDA sword_type,Y
CODE:7436 ORA powers_of_two,X ; Convert current dungeon to bit mask and OR it with the field
CODE:7437 STA sword_type,Y ; Update InventoryItem_Map, InventoryItem_Compass or InventoryItem_TriforcePiece.
CODE:7438 CPY #InventoryItem_TriforcePiece
CODE:7439 BNE in_overworld
CODE:743A JSR clear_game_mode_task_and_state ; We picked up a triforce piece. Switch to the triforce
  ; fanfare cutscene.
CODE:743B LDA #GameMode_PickedUpTriforce
CODE:743C STA game_mode ; set GameMode_Unknown_12
 
CODE:743D in_overworld:
CODE:743D RTS
 
Subroutine pick_up_something_thunk
CODE:744B pick_up_something_thunk:
CODE:744B JSR pick_up_something
 
Subroutine pick_up_heart
CODE:744E pick_up_heart:
CODE:744E LDA var_10 ; Number of hearts to fill
CODE:744F STA var_1
 
CODE:7450 loop: ; Set Z if hearts are full, otherwise clear Z.
CODE:7450 JSR is_health_full
CODE:7451 BNE health_not_full
CODE:7452 LDX partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:7453 INX
CODE:7454 BNE half_heart ; Branch if we have a half heart to fill
CODE:7455 RTS
 
CODE:7456 health_not_full: ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7456 INC hearts
CODE:7457 DEC var_1
CODE:7458 BPL loop ; Loop if we have more hearts to fill (fairy)
CODE:7459 RTS
 
CODE:745A half_heart:
CODE:745A LDA #$FF
CODE:745B STA partial_heart ; Fill half heart
CODE:745C RTS
 
Subroutine is_health_full
; Set Z if hearts are full, otherwise clear Z.
CODE:746C is_health_full:
CODE:746C LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:746D PHA ; Store hearts
CODE:746E AND #$F
CODE:746F STA var_0 ; var_0 = current hearts
CODE:7470 PLA ; A = hearts
CODE:7471 LSR A ; A = max hearts (hearts >> 4)
CODE:7472 LSR A
CODE:7473 LSR A
CODE:7474 LSR A
CODE:7475 CMP var_0 ; Compare current hearts to max hearts
CODE:7476 RTS
 
Function chunk for get_room_status_floor_item_picked_up
CODE:747C pick_up_ganon_triforce_thunk:
CODE:747C LDA #1
CODE:747D JSR rom1_set_prg_bank ; This seems like a no-op: this is only called from ROM1,
  ; and if it was called from anywhere else we'd be returning
  ; with the wrong bank set.
CODE:747E JMP pick_up_ganon_triforce
 
CODE:7484 collect_floor_item_max: ; Number to pick up
CODE:7484 LDA var_10
CODE:7485 CMP sword_type,Y
CODE:7486 BCC locret_1074AB
CODE:7487 STA sword_type,Y
CODE:7488 CPY #InventoryItem_Ring ; Passives
CODE:7489 BNE locret_1074AB
CODE:748A LDX current_save_slot ; After picking up a ring, update the save state.
  ; It looks like this is updating the main menu tunic
  ; color.
CODE:748B LDY have_ring_type
CODE:748C LDA byte_107325,Y
CODE:748D LDY byte_1EA0E,X
CODE:748E STA byte_26804,Y
CODE:748F JMP loc_1EA2B
 
Subroutine pick_up_rupee
; Play the rupee sound and add 1 to the pending rupee count.
CODE:74A3 pick_up_rupee:
CODE:74A3 LDA #Sound1_Rupee
CODE:74A4 STA play_sound_1 ; Play Sound1_Rupee for 1-rupee
CODE:74A5 INC pending_rupees_add
 
CODE:74AB locret_1074AB:
CODE:74AB RTS
 
Subroutine pick_up_something
CODE:74AC pick_up_something:
CODE:74AC LDA #Sound1_None
CODE:74AD STA play_sound_1 ; Play nothing
CODE:74AE LDA #Sound3_Pickup
CODE:74AF STA play_sound_3 ; Play Sound3_Pickup
CODE:74B0 RTS
 
Subroutine update_timed_palette_cycle
CODE:74B7 update_timed_palette_cycle:
CODE:74B7 LDA palette_cycle_timer
CODE:74B8 BNE ret
CODE:74B9 LDA next_palette_cycle
CODE:74BA BPL loc_1074C2
CODE:74BB EOR #$83
 
CODE:74C2 loc_1074C2:
CODE:74C2 STA var_0
CODE:74C3 ASL A ; A *= 8
CODE:74C4 ASL A
CODE:74C5 ASL A
CODE:74C6 CLC
CODE:74C7 ADC var_0 ; A = A + A*8
CODE:74C8 AND #$FC
CODE:74C9 TAY
CODE:74CA LDX ppu_command_buffer_bytes_used ; This is the number of bytes used in ppu_command_buffer. This is used to append commands to the buffer without having to scan to find the end of the existing commands.
CODE:74CB LDA #$3F
CODE:74CC STA ppu_command_buffer,X ; Set to 0x3F.
CODE:74CD INX
CODE:74CE LDA #8
CODE:74CF STA ppu_command_buffer,X ; Set to 0x8.
CODE:74D0 INX
CODE:74D1 STA ppu_command_buffer,X ; Set to 0x9.
CODE:74D2 STA var_0 ; Set to 0x9.
CODE:74D3 INX
 
CODE:74D4 loop:
CODE:74D4 LDA ppu_data_for_current_dungeon.palette_enter_stairway,Y
CODE:74D5 STA ppu_command_buffer,X
CODE:74D6 INY
CODE:74D7 INX
CODE:74D8 DEC var_0
CODE:74D9 BNE loop
CODE:74DA LDA #$FF
CODE:74DB STA ppu_command_buffer,X
CODE:74DC STX ppu_command_buffer_bytes_used ; Store the new number of bytes in the PPU command.
CODE:74DD INC next_palette_cycle
CODE:74DE LDA next_palette_cycle
CODE:74DF AND #$F
CODE:74E0 CMP #4
CODE:74E1 BEQ loc_107507
CODE:74E2 LDA #10
CODE:74E3 STA palette_cycle_timer ; Set to 10.
 
CODE:74E4 ret:
CODE:74E4 RTS
 
CODE:7507 loc_107507:
CODE:7507 LDA #0
CODE:7508 RTS
 
CODE:750A byte_10750A: .BYTE $3D
CODE:750B   .BYTE $1C
CODE:750C   .BYTE $20
CODE:750D   .BYTE 0
CODE:750E   .BYTE $DD
CODE:750F   .BYTE $1C
CODE:7510   .BYTE $20
CODE:7511   .BYTE 0
 
Subroutine setup_dungeon_only_sprites
CODE:7512 setup_dungeon_only_sprites:
CODE:7512 LDY #0
CODE:7513 LDX #0
 
CODE:7514 loop:
CODE:7514 LDA byte_10750A,X
CODE:7515 STA sprite_oam_data,Y
CODE:7516 INX
CODE:7517 TXA
CODE:7518 AND #7
CODE:7519 TAX
CODE:751A INY
CODE:751B CPY #$40
CODE:751C BNE loop
CODE:751D RTS
 
CODE:7527 lost_woods_code: .BYTE ControllerBits_Dpad_Up
CODE:7528   .BYTE ControllerBits_Dpad_Left
CODE:7529   .BYTE ControllerBits_Dpad_Down
CODE:752A   .BYTE ControllerBits_Dpad_Left
CODE:752B lost_hills_code: .BYTE ControllerBits_Dpad_Up
CODE:752C   .BYTE ControllerBits_Dpad_Up
CODE:752D   .BYTE ControllerBits_Dpad_Up
CODE:752E   .BYTE ControllerBits_Dpad_Up
 
Subroutine check_lost_woods_code
; If we're in the lost woods or lost hills, check the direction ; code. If we're repeating the room, change map_location_transitioning_to.
CODE:752F check_lost_woods_code:
CODE:752F LDX lost_woods_counter
CODE:7530 LDA object_direction
CODE:7531 LDY map_location
CODE:7532 CPY #$61 ; Lost woods
CODE:7533 BNE not_lost_woods
CODE:7534 CMP lost_woods_code,X
CODE:7535 BNE wrong_lost_woods_code
CODE:7536 CPX #3
CODE:7537 BEQ play_secret
 
CODE:7538 increment_lost_woods_counter:
CODE:7538 INC lost_woods_counter
 
CODE:7539 repeat_room: ; Transition back to the same room.
CODE:7539 STY map_location_transitioning_to
 
CODE:753A ret:
CODE:753A RTS
 
CODE:753B reset_lost_woods_counter: ; Reset lost_woods_counter to 0 after going the wrong way.
CODE:753B LDA #0
CODE:753C STA lost_woods_counter
CODE:753D RTS
 
CODE:753E wrong_lost_woods_code:
CODE:753E CMP #1
CODE:753F BEQ ret
 
CODE:7540 reset_lost_woods_counter_and_repeat_room: ; Reset lost_woods_counter to 0 after going the wrong way.
CODE:7540 JSR reset_lost_woods_counter
CODE:7541 BEQ repeat_room
 
CODE:7542 not_lost_woods:
CODE:7542 CPY #$1B
CODE:7543 BNE reset_lost_woods_counter ; If we're not in the lost woods or lost hills, just reset
  ; the code counter and return.
CODE:7544 CMP lost_hills_code,X
CODE:7545 BEQ correct_lost_hills_direction
CODE:7546 CMP #ControllerBits_Dpad_Left ; Don't reset the lost hills code after going left (but don't
  ; increase it either).
CODE:7547 BNE reset_lost_woods_counter_and_repeat_room
CODE:7548 RTS
 
CODE:7549 correct_lost_hills_direction:
CODE:7549 CPX #3
CODE:754A BNE increment_lost_woods_counter ; If we're not at the final input for the lost woods code,
  ; increment it and return to the same room.
 
CODE:754B play_secret:
CODE:754B LDA #Sound1_Secret
CODE:754C STA play_sound_1 ; Set to a nonzero value to play a one-off sound effect
CODE:754D RTS
 
Subroutine sub_107570
CODE:7570 sub_107570:
CODE:7570 LDA #8
CODE:7571 STA var_0
CODE:7572 LDA var_2
CODE:7573 ASL A
CODE:7574 ROL var_0
CODE:7575 ASL A
CODE:7576 ROL var_0
CODE:7577 AND #$E0
CODE:7578 STA var_1
CODE:7579 LDA var_3
CODE:757A LSR A
CODE:757B LSR A
CODE:757C LSR A
CODE:757D ORA var_1
CODE:757E STA var_1
CODE:757F RTS
 
CODE:7580 Skipped empty chunk
CODE:7594 object_type_to_tile_set:
CODE:7613 object_tile_set_to_tile_index:
CODE:76DF tile_set_to_tile_attributes:
CODE:77AB sprite_index_to_left_half: .BYTE $60 ; Offsets into sprite_oam_data for each sprite. Each sprite
  ; has two OAM sprites, one for the left half and one for the
  ; right half.
 
  ; The left half of the first sprite we update has its OAM
  ; data stored at sprite_oam_data+sprite_ids_left_half[0].
CODE:77AC sprite_index_right_half:
 
Subroutine update_object_sprite
CODE:77D4 update_object_sprite:
 
CODE:77D4 JSR update_walking_frame_for_object ; Update the walking animation frame for objects that cycle every 6 frames.
CODE:77D5 TYA
CODE:77D6 JMP update_object_sprite_horizontal
 
CODE:77DB update_object_sprite_vertical:
CODE:77DB LDY #1
CODE:77DC BNE continue ; Always branch
 
CODE:77DF update_object_sprite_horizontal:
CODE:77DF LDY #0
 
CODE:77E0 continue: ; Set to 0 if horizontal or 1 if vertical
CODE:77E0 STY var_12
CODE:77E1 LDY object_type,X
 
CODE:77E6 update_sprite_for_current_object_type: ; Increase the object ID by one. I'm not sure why this is
CODE:77E6 INY ; offset by one.
 
CODE:77E7 update_sprite_for_current_object_type_no_increment: ; Offset into the tile set
CODE:77E7 STA var_13
CODE:77E8 STY var_14 ; Store object type + 1
CODE:77E9 STX var_8 ; Stash X, so we can restore it when we're done.
CODE:77EA LDY next_sprite_index ; Get the next sprite index to use.
CODE:77EB LDA sprite_index_to_left_half,Y ; Get the offset into sprite_oam_data for the left and right
  ; halves of this sprite.
CODE:77EC STA updating_oam_sprite_id_1
CODE:77ED LDA sprite_index_right_half,Y
CODE:77EE CPX #0
CODE:77EF BNE update_sprite_from_wall_master_or_like_like ; Skip this for Link.
CODE:77F0 LDA #$48 ; Use these offsets for Link. Other code depends on this, such
  ; as replacing Link's sprite for the big shield.
CODE:77F1 STA updating_oam_sprite_id_1
CODE:77F2 LDA #$4C
 
CODE:7804 update_sprite_from_wall_master_or_like_like:
CODE:7804 STA updating_oam_sprite_id_2
CODE:7805 LDY var_14 ; Load object type + 1
CODE:7806 LDA #1
CODE:7807 STA var_7 ; By default, sprites have 2 parts (this value is parts+1).
CODE:7808 LDA #8
CODE:7809 STA var_10 ; Set to 8, which is the default X distance from the left to
  ; the right half sprite.
CODE:780A LDA object_type_to_tile_set,Y ; Get the tile set for this object ID.
CODE:780B CLC
CODE:780C ADC var_13
CODE:780D TAY
CODE:780E LDA object_tile_set_to_tile_index,Y
CODE:780F STA var_2 ; Store left sprite tile index
CODE:7810 CLC
CODE:7811 ADC #2
CODE:7812 STA var_3 ; Store right sprite tile index (left tile index + 2)
CODE:7813 CPX #0
CODE:7814 BEQ skip_enemy_property_check ; Skip this if Link
CODE:7815 CPX #AttackType_Sword
CODE:7816 BCS skip_enemy_property_check ; Skip this if this isn't an object
CODE:7817 LDA enemy_properties,X ; Load to check EnemyProperties_DrawHalfTile.
CODE:7818 AND #EnemyProperties_DrawHalfTile
CODE:7819 BNE half_tile_sprite
CODE:781A LDA enemy_properties,X ; Load to check EnemyProperties_FlipHorizontal_MirrorVertical.
CODE:781B AND #EnemyProperties_FlipHorizontal_MirrorVertical
CODE:781C BNE mirror_vertical_flip_horizontal
 
CODE:781D skip_enemy_property_check:
CODE:781D LDA tile_set_to_tile_attributes,Y
CODE:781E JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
 
CODE:781F mirror_vertical_flip_horizontal:
CODE:781F CPX #0
CODE:7820 BEQ flip_horizontally ; Check if Link
CODE:7821 LDY var_12 ; This is 0 if horizontal or 1 if vertical. If horizontal,
  ; flip horizontally. If vertical, mirror horizontally.
CODE:7822 BEQ flip_horizontally
CODE:7823 JMP mirror_horizontally
 
CODE:7824 half_tile_sprite: ; This object is half a tile. Decrement var_7, so we only draw one sprite instead of two.
CODE:7824 DEC var_7
CODE:7825 JMP check_invincibility_frames_palette_shift ; Skip checking horizontal flipping for half tile sprites.
 
CODE:784E flip_horizontally: ; If var_15 is true, flip the sprite horizontally.
CODE:784E LDA var_15
CODE:784F BEQ check_invincibility_frames_palette_shift
CODE:7850 LDA var_2 ; Swap var_2 and var_3 to flip the left and right side sprites.
CODE:7851 PHA
CODE:7852 LDA var_3
CODE:7853 STA var_2
CODE:7854 PLA
CODE:7855 STA var_3 ; Done swapping var_2 and var_3
CODE:7856 LDA var_4 ; Flip OAMAttributes_FlipHorizontally.
CODE:7857 EOR #OAMAttributes_FlipHorizontally
CODE:7858 STA var_4
CODE:7859 LDA var_5 ; Flip OAMAttributes_FlipHorizontally.
CODE:785A EOR #OAMAttributes_FlipHorizontally
CODE:785B STA var_5
 
CODE:7868 check_invincibility_frames_palette_shift: ; If this object isn't in invincibility frames, skip palette shifting.
CODE:7868 LDY invincibility_frames,X
CODE:7869 BEQ simple_update_sprite ; Update a sprite.
 
  ; updating_oam_sprite_id_1: the sprite_oam_data offset
  ; to update (always a multiple of 4).
  ; updating_oam_sprite_id_2: If updating two sprite, the
  ; second sprite_oam_data offset to update.
  ; var_0: X position
  ; var_1: Y position
  ; var_7: number of sprites to update (1 or 2)
  ; var_2[n]: tile number for sprite n
  ; var_4[n]: tile attributes for sprite n
  ; var_10: distance from first sprite X to second sprite X
CODE:786A LDY #1
 
CODE:786B apply_invincibility_frames_palette_shift:
CODE:786B LDA var_4,Y
CODE:786C AND #$FC ; Clear the palette bits of the OAM attributes.
CODE:786D STA var_4,Y
CODE:786E LDA invincibility_frames,X ; Add invincibility_frames & 0x3 to the palette index.
CODE:786F AND #3
CODE:7870 ORA var_4,Y
CODE:7871 STA var_4,Y
CODE:7872 DEY
CODE:7873 BPL apply_invincibility_frames_palette_shift
 
CODE:7885 simple_update_sprite: ; Update a sprite.
CODE:7885 LDX updating_oam_sprite_id_1
  ; updating_oam_sprite_id_1: the sprite_oam_data offset
  ; to update (always a multiple of 4).
  ; updating_oam_sprite_id_2: If updating two sprite, the
  ; second sprite_oam_data offset to update.
  ; var_0: X position
  ; var_1: Y position
  ; var_7: number of sprites to update (1 or 2)
  ; var_2[n]: tile number for sprite n
  ; var_4[n]: tile attributes for sprite n
  ; var_10: distance from first sprite X to second sprite X
CODE:7886 LDY #0
 
CODE:7887 loop:
CODE:7887 LDA var_2,Y
CODE:7888 STA sprite_oam_data.tile,X ; Tile number
CODE:7889 LDA var_1 ; Get sprite Y position
CODE:788A STA sprite_oam_data,X ; Write sprite Y position
CODE:788B LDA var_0 ; Get sprite X position
CODE:788C STA sprite_oam_data.x_pos,X ; Write sprite X position
CODE:788D CLC
CODE:788E ADC var_10 ; Add the sprite X position to var_0, to update it for the
  ; second sprite (if any). This is usually 8.
CODE:788F STA var_0
CODE:7890 LDA var_4,Y ; Get tile attributes
CODE:7891 STA sprite_oam_data.attr,X ; Write tile attributes
CODE:7892 LDX updating_oam_sprite_id_2 ; Get the second sprite offset.
CODE:7893 LDA var_8 ; Load the original X (the object ID).
CODE:7894 BEQ skip ; Skip if Link.
CODE:7895 JSR set_next_sprite_index ; Increase next_sprite_index.
 
CODE:7896 skip:
CODE:7896 INY
CODE:7897 DEC var_7
CODE:7898 BPL loop
CODE:7899 LDX var_8 ; Restore the object ID.
CODE:789A RTS
 
CODE:78B7 byte_1078B7: .BYTE 0
CODE:78B8   .BYTE 3
CODE:78B9   .BYTE 7
CODE:78BA   .BYTE $A
CODE:78BB   .BYTE $B
CODE:78BC   .BYTE $C
CODE:78BD   .BYTE $D
CODE:78BE   .BYTE $E
CODE:78BF   .BYTE $F
CODE:78C0   .BYTE $11
CODE:78C1   .BYTE $12
CODE:78C2   .BYTE $13
CODE:78C3   .BYTE $14
CODE:78C4   .BYTE $15
CODE:78C5   .BYTE $16
CODE:78C6   .BYTE $17
CODE:78C7   .BYTE $18
CODE:78C8   .BYTE $17
CODE:78C9   .BYTE $18
CODE:78CA   .BYTE $17
CODE:78CB   .BYTE $19
CODE:78CC   .BYTE $1B
CODE:78CD   .BYTE $1C
CODE:78CE   .BYTE $1D
CODE:78CF   .BYTE $1E
CODE:78D0   .BYTE $1F
CODE:78D1   .BYTE $20
CODE:78D2   .BYTE $21
CODE:78D3   .BYTE $1C
CODE:78D4   .BYTE $22
CODE:78D5   .BYTE $22
CODE:78D6   .BYTE $26
CODE:78D7   .BYTE $27
CODE:78D8   .BYTE $28
CODE:78D9   .BYTE $29
CODE:78DA   .BYTE $2B
CODE:78DB   .BYTE $2E
CODE:78DC byte_1078DC: .BYTE $20
CODE:78DD   .BYTE $82
CODE:78DE   .BYTE $3C
CODE:78DF   .BYTE $34
CODE:78E0   .BYTE $70
CODE:78E1   .BYTE $72
CODE:78E2   .BYTE $74
CODE:78E3   .BYTE $28
CODE:78E4   .BYTE $86
CODE:78E5   .BYTE $3C
CODE:78E6   .BYTE $2A
CODE:78E7   .BYTE $26
CODE:78E8   .BYTE $24
CODE:78E9   .BYTE $22
CODE:78EA   .BYTE $40
CODE:78EB   .BYTE $4A
CODE:78EC   .BYTE $8A
CODE:78ED   .BYTE $6C
CODE:78EE   .BYTE $42
CODE:78EF   .BYTE $46
CODE:78F0   .BYTE $76
CODE:78F1   .BYTE $2C
CODE:78F2   .BYTE $4E
CODE:78F3   .BYTE $4C
CODE:78F4   .BYTE $6A
CODE:78F5   .BYTE $50
CODE:78F6   .BYTE $52
CODE:78F7   .BYTE $66
CODE:78F8   .BYTE $32
CODE:78F9   .BYTE $2E
CODE:78FA   .BYTE $68
CODE:78FB   .BYTE $F3
CODE:78FC   .BYTE $6E
CODE:78FD   .BYTE $F2
CODE:78FE   .BYTE $36
CODE:78FF   .BYTE $38
CODE:7900   .BYTE $3A
CODE:7901   .BYTE $3C
CODE:7902   .BYTE $56
CODE:7903   .BYTE $48
CODE:7904   .BYTE $78
CODE:7905   .BYTE $20
CODE:7906   .BYTE $82
CODE:7907   .BYTE $7A
CODE:7908   .BYTE $7C
CODE:7909   .BYTE $30
CODE:790A   .BYTE $64
CODE:790B   .BYTE $62
 
Subroutine sub_10790C
CODE:790C sub_10790C:
CODE:790C JSR store_A_in_tile_attributes ; Store A in var_4 and var_5.
 
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
CODE:790D LDA #0
CODE:790E STA var_15 ; Set to 0
CODE:790F STA var_12 ; Set to 0
 
CODE:7915 after_setting_some_frame_state: ; Save Y
CODE:7915 TYA
CODE:7916 PHA
CODE:7917 LDA #0
CODE:7918 STA byte_52 ; Set to 0
CODE:7919 LDY next_sprite_index
CODE:791A LDA sprite_index_to_left_half,Y
CODE:791B STA updating_oam_sprite_id_1
CODE:791C LDA sprite_index_right_half,Y
CODE:791D STA updating_oam_sprite_id_2
CODE:791E PLA ; Restore Y
CODE:791F TAY
 
CODE:792C loc_10792C:
CODE:792C STX var_8
CODE:792D LDA #1
CODE:792E STA var_7 ; Set to 1
CODE:792F LDA #8
CODE:7930 STA var_10
CODE:7931 LDA byte_1078B7,Y
CODE:7932 CLC
CODE:7933 ADC var_12
CODE:7934 TAY
CODE:7935 LDA byte_1078DC,Y
CODE:7936 STA var_2
CODE:7937 CLC
CODE:7938 ADC #2
CODE:7939 STA var_3
CODE:793A LDA var_2
CODE:793B CMP #$F3
CODE:793C BEQ loc_107955
CODE:793D CMP #$20
CODE:793E BCC loc_10796A
CODE:793F CMP #$62
CODE:7940 BCS loc_10796A
 
CODE:7955 loc_107955: ; This is true if we're being called from update_hold_up_item_2.
CODE:7955 LDA disable_sprite_horizontal_offset
CODE:7956 BNE if_byte_504_not_zero
CODE:7957 LDA var_0
CODE:7958 CLC
CODE:7959 ADC #4
CODE:795A STA var_0
 
CODE:795B if_byte_504_not_zero:
CODE:795B INC byte_52
CODE:795C LDA #0
CODE:795D STA var_7 ; Set to 0
CODE:795E JMP check_invincibility_frames_palette_shift
 
CODE:796A loc_10796A:
CODE:796A CMP #$6C
CODE:796B BCC loc_107975
CODE:796C CMP #$7C
CODE:796D BCC mirror_horizontally
CODE:796E JMP flip_horizontally
 
CODE:7975 loc_107975:
CODE:7975 LDA #7
CODE:7976 STA var_10
 
Function chunk for update_object_sprite
CODE:7979 mirror_horizontally:
CODE:7979 LDA var_2
CODE:797A STA var_3
CODE:797B LDA var_5
CODE:797C EOR #OAMAttributes_FlipHorizontally
CODE:797D STA var_5
CODE:797E JMP check_invincibility_frames_palette_shift
 
Subroutine store_palette_2_in_tile_attributes
; Store 0x2 in var_4 and var_5, and set A to 2. ; ; var_4 and var_5 are the tile attributes for the left ; and right sprites, used by update_object_sprite.
CODE:7986 store_palette_2_in_tile_attributes:
CODE:7986 LDA #OAMAttributes_Palette_2
 
CODE:7988 store_A_in_tile_attributes: ; Store A in var_4 and var_5.
CODE:7988 STA var_4
  ; var_4 and var_5 are the tile attributes for the left
  ; and right sprites, used by update_object_sprite.
CODE:7989 STA var_5
CODE:798A RTS
 
Subroutine setup_gleeok_middle_neck_sprites
CODE:798D setup_gleeok_middle_neck_sprites:
CODE:798D LDY #3
CODE:798E STY var_3 ; Gleeok's palette index
 
CODE:7991 setup_sprites_ganon_moldorm_lanmola: ; On entry, var_3 is the sprite's OAM attributes.
CODE:7991 PHA
CODE:7992 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
CODE:7993 BEQ no_invincibility_frames
CODE:7994 LDA frame_counter ; Set var_3 = frame_counter&3 for invincibility frame palette shifting.
CODE:7995 AND #3
CODE:7996 STA var_3
 
CODE:7997 no_invincibility_frames:
CODE:7997 LDY next_sprite_index
CODE:7998 LDA sprite_index_to_left_half,Y
CODE:7999 TAY
CODE:799A PLA ; Restore A
 
CODE:79A5 update_sprite_attributes_then_advance: ; Tile index
CODE:79A5 STA sprite_oam_data.tile,Y
CODE:79A6 LDA object_x,X
CODE:79A7 STA sprite_oam_data.x_pos,Y ; Sprite X position
CODE:79A8 LDA object_y,X
 
  ; Called from Aquamentus
 
CODE:79AF update_sprite_y_attributes_then_advance: ; Sprite Y position
CODE:79AF STA sprite_oam_data,Y
CODE:79B0 LDA var_3
CODE:79B1 STA sprite_oam_data.attr,Y ; Tile attributes
CODE:79B2 JMP set_next_sprite_index ; Increase next_sprite_index and return.
 
Function chunk for update_monster_wall_trap
CODE:79BA loc_1079BA: ; Check if Link hit this enemy, and if this enemy hit Link.
CODE:79BA JSR check_enemy_hits
CODE:79BB LDA enemy_spawn_state_1
CODE:79BC BEQ update_sprite_zelda_wall_trap
CODE:79BD STA dungeon_shoots_fireballs
CODE:79BE LDA #0
CODE:79BF STA enemy_spawn_state_1
 
Subroutine update_sprite_zelda_wall_trap
CODE:79CA update_sprite_zelda_wall_trap:
CODE:79CA JSR set_var_0_to_object_position ; var_0 = object_x[X], var_1 = object_y[X], walking_state = 0
CODE:79CB JMP update_object_sprite_vertical
 
Subroutine check_enemy_hits
; Check if Link hit this enemy, and if this enemy hit Link.
CODE:79D0 check_enemy_hits:
CODE:79D0 JSR set_position_for_hitbox_check ; Set var_2/var_3 to this object's X/Y position for hit checking.
CODE:79D1 LDA enemy_properties,X ; Check MonsterState9_Invincible
CODE:79D2 AND #EnemyProperties_Invincible ; Skip damage checks if this object is invincible (eg. projectiles).
  ; Unlike invincibility_frames, this case still checks if
  ; the enemy hit Link.
CODE:79D3 BNE monster_is_invincible
CODE:79D4 LDA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
CODE:79D5 BNE ret ; Skip if this object is in i-frames.
CODE:79D6 LDY #AttackType_BoomerangOrMeat ; Boomerangs and meat share a slot. Firing the boomerang
  ; while meat is on the ground makes the meat disappear.
CODE:79D7 JSR check_attack_boomerang
CODE:79D8 LDY #AttackType_SwordBeamOrRodBeam ; The beam of either the beam sword or the rod.
CODE:79D9 JSR check_attack_beam_sword_rod
CODE:79DA LDY #AttackType_BombOrFire1 ; There are two slots for bombs and fire. Two fires can
  ; be shot at once, or a bomb and a fire.
CODE:79DB JSR check_attack_bomb_or_fire
CODE:79DC LDY #AttackType_BombOrFire2
CODE:79DD JSR check_attack_bomb_or_fire
CODE:79DE LDY #AttackType_Sword
CODE:79DF JSR check_attack_sword
CODE:79E0 LDY #AttackType_ArrowOrMeleeRod ; An arrow in the air, or the melee part of the rod attack.
CODE:79E1 JSR check_attack_arrow
 
CODE:79E2 monster_is_invincible: ; Check if Link was hit by an enemy. X is the enemy we're
CODE:79E2 JSR check_link_hit_by_enemy ; checking against.
 
  ; If Link is hit, var_6 and var_12 is set and damage is applied.
CODE:79E3 LDA object_type,X ; Check if goriya, wall master, like like
CODE:79E4 LDY enemy_spawn_state,X ; 0 = enemy spawned, 0x01+ = spawn cloud, 0x10 = dying
CODE:79E5 BEQ spawn_state_is_zero ; Branch if this enemy isn't dying
CODE:79E6 CMP #ObjectType_BlueGoriya
CODE:79E7 BEQ is_goriya
CODE:79E8 CMP #ObjectType_RedGoriya
CODE:79E9 BNE ret
 
CODE:79EA is_goriya: ; This enemy is a dying Goriya. Clear out the boomerang
CODE:79EA LDA walk_state_and_weapon_state,X ; object ID. This is probably so boomerangs don't fly
  ; towards another object if another object is spawned in this
  ; slot.
CODE:79EB BPL ret
CODE:79EC LDY enemy_state_4,X
CODE:79ED LDA #0
CODE:79EE STA object_type,Y ; Set to 0.
 
CODE:79EF ret:
CODE:79EF RTS
 
CODE:79F0 spawn_state_is_zero: ; If a wall master or like like hits Link, set enemy_state_4.
CODE:79F0 CMP #ObjectType_WallMaster
CODE:79F1 BEQ wall_master_or_like_like
CODE:79F2 CMP #ObjectType_LikeLike
CODE:79F3 BNE locret_107A2C
 
CODE:79F4 wall_master_or_like_like: ; var_12 is true if this enemy hit Link.
CODE:79F4 LDA var_12
CODE:79F5 BEQ locret_107A2C
CODE:79F6 INC enemy_state_4,X ; Set to 1 if this enemy has hit Link (wall masters and like likes).
 
CODE:7A2C locret_107A2C:
CODE:7A2C RTS
 
Subroutine set_position_for_hitbox_check
; Set var_2/var_3 to this object's X/Y position for hit checking.
CODE:7A2D set_position_for_hitbox_check:
CODE:7A2D LDA #8
CODE:7A2E STA var_2
CODE:7A2F STA var_3
CODE:7A30 LDA enemy_properties,X ; Load to check EnemyProperties_MoveHitboxRight4Pixels.
CODE:7A31 AND #EnemyProperties_MoveHitboxRight4Pixels
CODE:7A32 BEQ move_hitbox
CODE:7A33 LSR var_2 ; = 4
 
CODE:7A34 move_hitbox:
CODE:7A34 LDA object_x,X
CODE:7A35 CLC
CODE:7A36 ADC var_2 ; var_2 = object X + (property_40? 4:8)
CODE:7A37 STA var_2
CODE:7A38 LDA object_y,X
CODE:7A39 CLC
CODE:7A3A ADC var_3 ; var_3 = object Y + 8
CODE:7A3B STA var_3
 
CODE:7A4A enemy_damage: ; This table starts after this return, but points to the
CODE:7A4A RTS ; same place since value 0 is never used (Link).
 
  ; 0x0F is the number of hearts of damage this enemiy does.
  ; 0xF0 is the fractional number of hearts, where 0x80 is
  ; half a heart.
 
CODE:7A4B   .BYTE 2 ; ObjectType_BlueLynel
CODE:7A4C   .BYTE 1 ; ObjectType_RedLynel
CODE:7A4D   .BYTE $80 ; ObjectType_BlueMoblin
CODE:7A4E   .BYTE $80 ; ObjectType_RedMoblin
CODE:7A4F   .BYTE 1 ; ObjectType_BlueGoriya
CODE:7A50   .BYTE $80 ; ObjectType_RedGoriya
CODE:7A51   .BYTE $80 ; ObjectType_RedOctorok
CODE:7A52   .BYTE $80 ; ObjectType_RedOctorokFast
CODE:7A53   .BYTE $80 ; ObjectType_BlueOctorok
CODE:7A54   .BYTE $80 ; ObjectType_BlueOctorokFast
CODE:7A55   .BYTE 1 ; ObjectType_RedDarknut
CODE:7A56   .BYTE 2 ; ObjectType_BlueDarknut
CODE:7A57   .BYTE $80 ; ObjectType_BlueTektite
CODE:7A58   .BYTE $80 ; ObjectType_RedTektite
CODE:7A59   .BYTE 1 ; ObjectType_BlueLeever
CODE:7A5A   .BYTE $80 ; ObjectType_RedLeever (0x10)
CODE:7A5B   .BYTE $80 ; ObjectType_Zola
CODE:7A5C   .BYTE 1 ; ObjectType_Vire
CODE:7A5D   .BYTE 1 ; ObjectType_Zol
CODE:7A5E   .BYTE $80 ; ObjectType_Gel1
CODE:7A5F   .BYTE $80 ; ObjectType_Gel2
CODE:7A60   .BYTE 2 ; ObjectType_PolsVoice
CODE:7A61   .BYTE 1 ; ObjectType_LikeLike
CODE:7A62   .BYTE 2 ; ObjectType_Digdogger_Spawn
CODE:7A63   .BYTE 0 ; ObjectType_Smoke
CODE:7A64   .BYTE $80 ; ObjectType_Peahat
CODE:7A65   .BYTE $80 ; ObjectType_BlueKeese
CODE:7A66   .BYTE $80 ; ObjectType_RedKeese
CODE:7A67   .BYTE $80 ; ObjectType_DarkKeese
CODE:7A68   .BYTE 1 ; ObjectType_Armos
CODE:7A69   .BYTE $80 ; ObjectType_FallingRocks_Daemon
CODE:7A6A   .BYTE $80 ; ObjectType_FallingRock (0x20)
CODE:7A6B   .BYTE 1 ; ObjectType_Ghini
CODE:7A6C   .BYTE 1 ; ObjectType_GhiniFromTombs
CODE:7A6D   .BYTE 2 ; ObjectType_BlueWizzrobe
CODE:7A6E   .BYTE 1 ; ObjectType_RedWizzrobe
CODE:7A6F   .BYTE 2 ; ObjectType_Unknown_25
CODE:7A70   .BYTE 2 ; ObjectType_Unknown_26
CODE:7A71   .BYTE $80 ; ObjectType_WallMaster
CODE:7A72   .BYTE $80 ; ObjectType_Rope
CODE:7A73   .BYTE $80 ; ObjectType_Unknown_29
CODE:7A74   .BYTE $80 ; ObjectType_Stalfos
CODE:7A75   .BYTE 0 ; ObjectType_Bubble
CODE:7A76   .BYTE 0 ; ObjectType_BlueBubble
CODE:7A77   .BYTE 0 ; ObjectType_RedBubble
CODE:7A78   .BYTE 0 ; ObjectType_Whirlwind
CODE:7A79   .BYTE 0 ; ObjectType_Fairy
CODE:7A7A   .BYTE 2 ; ObjectType_Gibdo (0x30)
CODE:7A7B   .BYTE 1 ; ObjectType_DodongoMiniboss
CODE:7A7C   .BYTE 1 ; ObjectType_DodongoBoss
CODE:7A7D   .BYTE 2 ; ObjectType_BlueGohma
CODE:7A7E   .BYTE 2 ; ObjectType_RedGohma
CODE:7A7F   .BYTE 0 ; ObjectType_TenRupees
CODE:7A80   .BYTE 0 ; ObjectType_HungryGoriya
CODE:7A81   .BYTE 0 ; ObjectType_Zelda
CODE:7A82   .BYTE 2 ; ObjectType_Digdogger_3
CODE:7A83   .BYTE 2 ; ObjectType_Digdogger_1
CODE:7A84   .BYTE 2 ; ObjectType_RedLanmola
CODE:7A85   .BYTE 2 ; ObjectType_BlueLanmola
CODE:7A86   .BYTE 1 ; ObjectType_Manhandla
CODE:7A87   .BYTE 1 ; ObjectType_Aquamentus
CODE:7A88   .BYTE 4 ; ObjectType_Ganon
CODE:7A89   .BYTE $80 ; ObjectType_Flame
CODE:7A8A   .BYTE $80 ; ObjectType_Flame_Unkillable (0x40)
CODE:7A8B   .BYTE $80 ; ObjectType_Moldorm
CODE:7A8C   .BYTE 1 ; ObjectType_Gleeok_1_Head
CODE:7A8D   .BYTE 1 ; ObjectType_Gleeok_2_Heads
CODE:7A8E   .BYTE 1 ; ObjectType_Gleeok_3_Heads
CODE:7A8F   .BYTE 1 ; ObjectType_Gleeok_4_Heads
CODE:7A90   .BYTE 1 ; ObjectType_Gleeok_Flying_Head
CODE:7A91   .BYTE 2 ; ObjectType_Patra_1
CODE:7A92   .BYTE 2 ; ObjectType_Patra_2
CODE:7A93   .BYTE 1 ; ObjectType_WallTrap_Vert
CODE:7A94   .BYTE 1 ; ObjectType_WallTrap_Horiz
CODE:7A95   .BYTE 0 ; ObjectType_OldMan_0
CODE:7A96   .BYTE 0 ; ObjectType_OldMan_1
CODE:7A97   .BYTE 0 ; ObjectType_OldMan_2
CODE:7A98   .BYTE 0 ; ObjectType_OldMan_3
CODE:7A99   .BYTE 0 ; ObjectType_OldManItem_1
CODE:7A9A   .BYTE 0 ; ObjectType_OldMan_5 (0x50)
CODE:7A9B   .BYTE 0 ; ObjectType_OldMan_Mugger
CODE:7A9C   .BYTE 0 ; ObjectType_OldMan_7
CODE:7A9D   .BYTE $80 ; ObjectType_Octorok_Projectile
CODE:7A9E   .BYTE $80
CODE:7A9F   .BYTE $80 ; ObjectType_Homing_Fireball_1
CODE:7AA0   .BYTE 1 ; ObjectType_Homing_Fireball_2
CODE:7AA1   .BYTE 2 ; ObjectType_Lynel_Sword
CODE:7AA2   .BYTE 2
CODE:7AA3   .BYTE 4
CODE:7AA4   .BYTE 4
CODE:7AA5   .BYTE $80 ; ObjectType_Moblin_Arrow
CODE:7AA6   .BYTE 1 ; ObjectType_Goriya_Boomerang
 
Subroutine check_link_hit_by_enemy
; Check if Link was hit by an enemy. X is the enemy we're ; checking against. ; ; If Link is hit, var_6 and var_12 is set and damage is applied.
CODE:7AA7 check_link_hit_by_enemy:
CODE:7AA7 JSR set_position_for_hitbox_check ; Set var_2/var_3 to this object's X/Y position for hit checking.
CODE:7AA8 LDA #0
CODE:7AA9 STA projectile_hit_link ; Set to 0
CODE:7AAA STA var_6 ; Set to 0
CODE:7AAB STA var_9 ; Set to 0
CODE:7AAC STA var_12 ; Set to 0
CODE:7AAD LDY #0
CODE:7AAE STY var_0 ; Set to 0
CODE:7AAF LDA invincibility_frames ; We can't be hit when we're in i-frames.
CODE:7AB0 ORA clock_active ; We can't be hit by enemies if the clock is active.
CODE:7AB1 ORA enemy_stun ; We can't be hit by enemies if we're stunned.
CODE:7AB2 ORA enemy_stun,X ; We can't be hit by enemies that are stunned.
CODE:7AB3 BNE ret
 
CODE:7AC5 loc_107AC5:
CODE:7AC5 LDA walk_state_and_weapon_state
CODE:7AC6 CMP #WalkState_3_MovementLocked
CODE:7AC7 BEQ ret
CODE:7AC8 LDA held_by_like_like
CODE:7AC9 BNE ret ; We can't be hit while we're held by a like like.
CODE:7ACA LDA object_type,X
CODE:7ACB CMP #ObjectType_Octorok_Projectile
CODE:7ACC BCC not_projectile ; < ObjectType_Octorok_Projectile
CODE:7ACD LDA walk_state_and_weapon_state,X
CODE:7ACE AND #$F0
CODE:7ACF CMP #WalkState_Unknown2_10
CODE:7AD0 BNE ret
 
CODE:7AD1 not_projectile:
CODE:7AD1 LDA object_x
CODE:7AD2 CLC
CODE:7AD3 ADC #8
CODE:7AD4 STA var_4 ; Set to Link's X position + 8.
CODE:7AD5 LDA object_y
CODE:7AD6 CLC
CODE:7AD7 ADC #8
CODE:7AD8 STA var_5 ; Set to Link's Y position + 8.
CODE:7AD9 LDA #9 ; Link's hitbox size: 9 pixels
CODE:7ADA JSR check_hitbox ; In var_4/var_5: Target's X,Y position
  ; In A: Target's hitbox size
  ; Out A, var_6: 1 if hit
CODE:7ADB BEQ ret ; Branch if we aren't in this enemy's hitbox.
CODE:7ADC LDA object_type,X ; Attacks < ObjectType_Octorok_Projectile can't be deflected by shields.
CODE:7ADD CMP #ObjectType_Octorok_Projectile
CODE:7ADE BCC apply_damage_from_enemy_hit
CODE:7ADF INC projectile_hit_link ; This is set to 1 by check_link_hit_by_enemy if a projectile
  ; hits Link even if it's deflected by the shield, so it can
  ; be despawned.
CODE:7AE0 CMP #ObjectType_Homing_Fireball_2 ; Fireball_1 can be deflected by the shield. Fireball_2 can't.
CODE:7AE1 BEQ apply_damage_from_enemy_hit
CODE:7AE2 CMP #ObjectType_Unknown_Projectile_5A ; Does anything create this?
CODE:7AE3 BEQ apply_damage_from_enemy_hit
CODE:7AE4 LDA walk_state_and_weapon_state ; The shield doesn't block projectiles while we're swinging
  ; the sword.
CODE:7AE5 AND #$F0
CODE:7AE6 BNE apply_damage_from_enemy_hit
CODE:7AE7 LDA object_direction ; Compare the weapon direction with the object direction to
  ; see if the attack hits the shield.
CODE:7AE8 ORA object_direction,X
CODE:7AE9 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7AEA CMP #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7AEB BEQ shield_facing_enemy
CODE:7AEC LDA object_direction
CODE:7AED ORA object_direction,X
CODE:7AEE AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
CODE:7AEF CMP #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
CODE:7AF0 BNE apply_damage_from_enemy_hit
 
CODE:7AF1 shield_facing_enemy: ; We're facing the attacker, and this is a projectile.
CODE:7AF1 LDA object_type,X
CODE:7AF2 CMP #ObjectType_Homing_Fireball_1 ; Check if this is a projectile that the small shield can block.
CODE:7AF3 BCC deflected_by_shield
CODE:7AF4 CMP #ObjectType_Moblin_Arrow
CODE:7AF5 BCS deflected_by_shield
CODE:7AF6 LDA have_magic_shield ; Other projectiles can be deflected if we have the magic shield.
CODE:7AF7 BEQ apply_damage_from_enemy_hit
 
CODE:7AF8 deflected_by_shield:
CODE:7AF8 LDA #Sound3_ShieldTing
CODE:7AF9 STA play_sound_3 ; Play Sound3_ShieldTing
CODE:7AFA LDA #0
CODE:7AFB STA var_6
 
CODE:7AFC ret:
CODE:7AFC RTS
 
CODE:7AFD apply_damage_from_enemy_hit: ; Apply knockback after a hit.
CODE:7AFD JSR apply_knockback
  ; X is the object ID of the enemy. This is either the enemy being hit, or the enemy hitting Link.
  ; Y = 0 if we're applying knockback to Link being hit by an enemy.
  ; Y is an AttackType if we're applying knockback to the enemy ID in X being hit by one of Link's weapons.
 
  ; var_9 is the current DamageType.
 
CODE:7AFE INC var_12 ; Set var_12 when we've been hit.
CODE:7AFF LDY object_type,X ; Unused?
CODE:7B00 LDA enemy_damage,Y
CODE:7B01 PHA
CODE:7B02 AND #$F
CODE:7B03 STA var_13 ; Whole hearts
CODE:7B04 PLA
CODE:7B05 AND #$F0
CODE:7B06 STA var_14 ; Fractional hearts
 
CODE:7B4F apply_damage_from_own_fire: ; Don't play the hit sound if this is ObjectType_Whirlwind.
CODE:7B4F LDY object_type,X
CODE:7B50 CPY #ObjectType_Whirlwind
CODE:7B51 BEQ skip_play_ow
CODE:7B52 LDA #Sound0_LinkHit ; Ow
CODE:7B53 JSR add_mask_to_play_sound_0 ; Play Sound0_LinkHit.
 
CODE:7B54 skip_play_ow: ; Load ring type to reduce damage
CODE:7B54 LDY have_ring_type
CODE:7B55 BEQ skip_ring_adjustment
 
CODE:7B56 ring_damage_reduction_loop: ; Halve whole hearts
CODE:7B56 LSR var_13
CODE:7B57 ROR var_14 ; Halve fractional hearts, shifting carry in from whole hearts
CODE:7B58 DEY
CODE:7B59 BNE ring_damage_reduction_loop
 
CODE:7B5A skip_ring_adjustment: ; Clear the kill counters when we've been hit.
CODE:7B5A LDA #0
CODE:7B5B STA consecutive_kill_counter ; Set to 0 after hit
CODE:7B5C STA consecutive_ten_kill_counter ; Set to 0 after hit
CODE:7B5D STA reached_ten_kills_with_last_bomb ; Set to 0 after hit
CODE:7B5E LDA partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:7B5F CMP var_14
CODE:7B60 BCC loc_107B90
CODE:7B61 SEC
CODE:7B62 SBC var_14
CODE:7B63 STA partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:7B64 LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7B65 AND #$F
CODE:7B66 CMP var_13
CODE:7B67 BCC zero_hearts
CODE:7B68 LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7B69 SEC
CODE:7B6A SBC var_13
CODE:7B6B STA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7B6C RTS
 
CODE:7B90 loc_107B90:
CODE:7B90 LDA var_14
CODE:7B91 SEC
CODE:7B92 SBC partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:7B93 STA var_14
CODE:7B94 LDA hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7B95 AND #$F
CODE:7B96 BEQ zero_hearts
CODE:7B97 DEC hearts ; 0xF0 = max hearts, 0x0F = current hearts
CODE:7B98 LDA #$FF
CODE:7B99 STA partial_heart ; Half heart if < 0x80, and a timer for potion refills
CODE:7B9A BNE skip_ring_adjustment
 
CODE:7B9B zero_hearts: ; The player died.
CODE:7B9B LDA hearts
CODE:7B9C AND #$F0
CODE:7B9D STA hearts ; Set to 0 after death.
CODE:7B9E JSR clear_game_mode_task_and_state
CODE:7B9F STA partial_heart ; Set to 0 after death.
CODE:7BA0 STA walk_state_and_weapon_state ; Set to 0 after death.
CODE:7BA1 LDA #GameMode_JustDied
CODE:7BA2 STA game_mode ; Switch to GameMode_JustDied.
CODE:7BA3 LDA #ControllerBits_Dpad_Down
CODE:7BA4 STA object_direction ; Face down.
 
CODE:7BC1 locret_107BC1:
CODE:7BC1 RTS
 
Subroutine check_attack_boomerang
CODE:7BC2 check_attack_boomerang:
CODE:7BC2 LDA walk_state_and_weapon_state,Y
CODE:7BC3 ASL A
CODE:7BC4 BCS locret_107BC1
CODE:7BC5 STY var_0
CODE:7BC6 LDA #DamageType_Boomerang
CODE:7BC7 STA var_9 ; Set to DamageType_Boomerang.
CODE:7BC8 LDA #10
CODE:7BC9 STA var_13 ; Boomerang hitbox X size: 10
CODE:7BCA STA var_14 ; Boomerang hitbox Y size: 10
CODE:7BCB LDA object_x,Y
CODE:7BCC CLC
CODE:7BCD ADC #4
CODE:7BCE STA var_4 ; Set to object X + 4
CODE:7BCF LDA object_y,Y
CODE:7BD0 CLC
CODE:7BD1 ADC #8 ; A = object Y + 8
 
  ; fall through
 
Subroutine check_weapon_hit
CODE:7BE2 check_weapon_hit:
CODE:7BE2 STA var_5 ; var_4 = weapon X, var_5 = weapon Y
CODE:7BE3 LDA #0
CODE:7BE4 STA var_6 ; Set to 0
CODE:7BE5 LDY var_0
CODE:7BE6 LDA walk_state_and_weapon_state,Y
CODE:7BE7 BEQ ret
CODE:7BE8 JSR check_hitbox_with_specified_size
CODE:7BE9 BEQ ret ; Return if the weapon didn't hit.
CODE:7BEA CPY #AttackType_BoomerangOrMeat ; Boomerangs and meat share a slot. Firing the boomerang
  ; while meat is on the ground makes the meat disappear.
CODE:7BEB BNE loc_107C16
CODE:7BEC LDA damage_types_with_no_knockback,X
CODE:7BED AND var_9
CODE:7BEE BEQ skip_ting
CODE:7BEF JSR play_shield_ting
 
CODE:7BF0 skip_ting:
CODE:7BF0 LDA #$50
CODE:7BF1 STA walk_state_and_weapon_state,Y
CODE:7BF2 LDA damage_types_with_no_knockback,X
CODE:7BF3 AND var_9
CODE:7BF4 BNE ret
CODE:7BF5 LDA #0
CODE:7BF6 STA var_7 ; Zero damage
CODE:7BF7 LDA #16
CODE:7BF8 STA enemy_stun,X ; Stun for 16 frames
 
CODE:7C16 loc_107C16:
CODE:7C16 LDA damage_types_with_no_knockback,X
CODE:7C17 AND var_9
CODE:7C18 BNE maybe_play_shield_ting
CODE:7C19 LDA object_type,X ; Check if Gohma
CODE:7C1A CMP #ObjectType_BlueGohma
CODE:7C1B BEQ is_gohma
CODE:7C1C CMP #ObjectType_RedGohma
CODE:7C1D BNE not_gohma
 
CODE:7C1E is_gohma: ; This will JSR into apply_damage_to_enemy.
CODE:7C1E JMP apply_damage_to_gohma
 
CODE:7C1F not_gohma:
CODE:7C1F CMP #ObjectType_Zol
CODE:7C20 BEQ is_zol
CODE:7C21 CMP #ObjectType_Vire
CODE:7C22 BNE not_zol_or_vire
 
CODE:7C23 is_zol: ; Zol or Vire (enemies that split into two smaller enemies).
CODE:7C23 CPY #AttackType_BoomerangOrMeat
CODE:7C24 BEQ apply_damage_to_enemy
CODE:7C25 LDA object_direction,Y ; Except for the boomerang (which won't kill them), make
  ; Zols and Vires start moving in the direction they're
  ; hit before they split into parts.
CODE:7C26 STA object_direction,X
CODE:7C27 JMP apply_damage_to_enemy
 
CODE:7C28 not_zol_or_vire:
CODE:7C28 CMP #ObjectType_RedDarknut
CODE:7C29 BEQ check_darknut_shield
CODE:7C2A CMP #ObjectType_BlueDarknut
CODE:7C2B BNE apply_damage_to_enemy
 
CODE:7C2C check_darknut_shield: ; Check if the attack is facing the Darknut shield.
CODE:7C2C LDA object_direction,Y
CODE:7C2D ORA object_direction,X
CODE:7C2E CMP #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7C2F BEQ maybe_play_shield_ting
CODE:7C30 CMP #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
CODE:7C31 BEQ maybe_play_shield_ting
 
CODE:7C54 apply_damage_to_enemy:
CODE:7C54 LDA #Sound3_HitEnemy
CODE:7C55 STA play_sound_3 ; Play Sound3_HitEnemy
CODE:7C56 LDA enemy_health,X ; 0xF0 = Enemy health (regular sword = 0x10 damage)
CODE:7C57 CMP var_7 ; Load the attack damage for this weapon
CODE:7C58 BCC enemy_dead ; Branch if damage == enemy health
CODE:7C59 SEC
CODE:7C5A SBC var_7 ; Subtract damage from enemy health
CODE:7C5B STA enemy_health,X ; Store health after subtracting damage
CODE:7C5C BEQ enemy_dead
 
CODE:7C5D ret:
CODE:7C5D RTS
 
CODE:7C5E maybe_play_shield_ting: ; Skip shield ting for Darknuts for fire and bomb damage
CODE:7C5E LDA var_9
CODE:7C5F CMP #DamageType_Fire
CODE:7C60 BEQ ret
CODE:7C61 CMP #DamageType_Bomb
CODE:7C62 BEQ ret
CODE:7C63 JMP play_shield_ting
 
CODE:7C64 enemy_dead:
CODE:7C64 INC consecutive_kill_counter
CODE:7C65 LDA consecutive_ten_kill_counter ; Load to compare against 10
CODE:7C66 CMP #10
CODE:7C67 BCS loc_107C8F ; Branch if consecutive_ten_kill_counter >= 10
CODE:7C68 INC consecutive_ten_kill_counter
CODE:7C69 LDA consecutive_ten_kill_counter ; Load after incrementing
CODE:7C6A CMP #10
CODE:7C6B BNE loc_107C8F ; Branch if not 10 yet
CODE:7C6C LDA var_9
CODE:7C6D CMP #DamageType_Bomb
CODE:7C6E BNE loc_107C8F
CODE:7C6F INC reached_ten_kills_with_last_bomb ; This is set to 1 after killing the 10th enemy with a bomb.
 
CODE:7C8F loc_107C8F:
CODE:7C8F JSR set_enemy_killed
CODE:7C90 LDA #0
CODE:7C91 STA enemy_stun,X
 
Subroutine sub_107C96
CODE:7C96 sub_107C96:
CODE:7C96 JSR clear_knockback2 ; A = 0 when this is called.
CODE:7C97 STA invincibility_frames,X ; This is both the number of invincibility frames * 2 remaining, and used for damage palette shifting.
CODE:7C98 RTS
 
Subroutine check_attack_beam_sword_rod
CODE:7C9D check_attack_beam_sword_rod:
CODE:7C9D STY var_0 ; Store the attack type (always AttackType_BeamOrRod, 0xE)
CODE:7C9E LDA #DamageType_Rod
CODE:7C9F STA var_9 ; Set to DamageType_Rod
CODE:7CA0 LDA walk_state_and_weapon_state,Y
CODE:7CA1 LSR A
CODE:7CA2 BCS ret ; Branch if 0x01 was set
CODE:7CA3 LDA #$C
CODE:7CA4 STA var_13 ; Set to 0xC
CODE:7CA5 LDA walk_state_and_weapon_state,Y ; sword_beam_state. 0x80 set if firing the rod
CODE:7CA6 LDY #$20 ; Rod beam damage
CODE:7CA7 ASL A
CODE:7CA8 BCS damage_set ; Branch if 0x80 was set (BeamSwordOrRodState_Type_Rod)
CODE:7CA9 LDA #DamageType_Sword
CODE:7CAA STA var_9 ; Set to DamageType_Sword.
CODE:7CAB LDY #$40 ; Magic sword damage
CODE:7CAC LDA sword_type
CODE:7CAD CMP #3
CODE:7CAE BEQ damage_set ; Branch with 0x40 damage if we have the magic sword
CODE:7CAF LDY #$20 ; White sword damage
CODE:7CB0 CMP #2
CODE:7CB1 BEQ damage_set ; Branch with 0x20 damage if we have the white sword
CODE:7CB2 LDY #$10 ; Wood sword damage
 
CODE:7CB3 damage_set:
CODE:7CB3 TYA
CODE:7CB4 JSR continue_check_attack_beam_sword_rod
CODE:7CB5 LDA var_6
CODE:7CB6 BEQ ret
CODE:7CB7 TXA
CODE:7CB8 PHA
CODE:7CB9 LDX #$E
CODE:7CBA JSR loc_1F3D4
CODE:7CBB PLA
CODE:7CBC TAX
 
CODE:7CBD ret:
CODE:7CBD RTS
 
Subroutine check_attack_bomb_or_fire
CODE:7CDC check_attack_bomb_or_fire:
CODE:7CDC STY var_0 ; Y is AttackType_BombOrFire1 or AttackType_BombOrFire2.
CODE:7CDD LDA #DamageType_Fire
CODE:7CDE STA var_9 ; Set to DamageType_Fire.
CODE:7CDF LDA #$10
CODE:7CE0 STA var_7 ; Fire does 0x10 damage.
CODE:7CE1 LDA #14
CODE:7CE2 STA var_13 ; Hitbox size for fire: 14
CODE:7CE3 LDA walk_state_and_weapon_state,Y ; Y ix 0x10 or 0x11, so this is bomb_or_fire1_state or bomb_or_fire2_state.
CODE:7CE4 CMP #BombOrFireState_Type_Fire
CODE:7CE5 BCS is_fire
CODE:7CE6 CMP #BombOrFireState_BombExploding|BombOrFireState_Type_Bomb ; Check if this is an exploding bomb.
CODE:7CE7 BNE locret_107D25
CODE:7CE8 LDA #DamageType_Bomb
CODE:7CE9 STA var_9 ; Set to DamageType_Bomb.
CODE:7CEA LDA #$40
CODE:7CEB STA var_7 ; Bombs do 0x40 damage.
CODE:7CEC LDA #24
CODE:7CED STA var_13 ; Hitbox size for bombs: 24
 
CODE:7CEE is_fire:
CODE:7CEE LDA object_x,Y
CODE:7CEF CLC
CODE:7CF0 ADC #8
CODE:7CF1 STA var_4
CODE:7CF2 LDA object_y,Y
CODE:7CF3 CLC
CODE:7CF4 ADC #8
CODE:7CF5 STA var_5
CODE:7CF6 LDA var_13
CODE:7CF7 JSR check_hitbox ; In var_4/var_5: Target's X,Y position
  ; In A: Target's hitbox size
  ; Out A, var_6: 1 if hit
CODE:7CF8 BEQ locret_107D25
CODE:7CF9 JSR loc_107C16
CODE:7CFA LDA damage_types_with_no_knockback,X
CODE:7CFB AND var_9
CODE:7CFC BNE locret_107D25
CODE:7CFD JSR apply_knockback ; Apply knockback after a hit.
 
  ; X is the object ID of the enemy. This is either the enemy being hit, or the enemy hitting Link.
  ; Y = 0 if we're applying knockback to Link being hit by an enemy.
  ; Y is an AttackType if we're applying knockback to the enemy ID in X being hit by one of Link's weapons.
 
  ; var_9 is the current DamageType.
 
CODE:7D25 locret_107D25:
CODE:7D25 RTS
 
CODE:7D26   .BYTE $10 ; Melee sword damage amounts (referenced through the
  ; above pointer)
CODE:7D27   .BYTE $20
CODE:7D28   .BYTE $40
 
Subroutine check_attack_sword
CODE:7D29 check_attack_sword:
CODE:7D29 STY var_0
CODE:7D2A LDA #DamageType_Sword
CODE:7D2B STA var_9 ; Set to DamageType_Sword.
CODE:7D2C LDA walk_state_and_weapon_state,Y
CODE:7D2D CMP #2
CODE:7D2E BNE locret_107D25
CODE:7D2F LDY sword_type
CODE:7D30 LDA locret_107D25,Y ; Damage for sword melee. Note that this duplicates code
  ; elsewhere which handles this differently (beam sword), but
  ; gives the same result.
 
CODE:7D3C continue_check_attack_arrow: ; Store damage for this weapon
CODE:7D3C STA var_7
CODE:7D3D LDA object_direction
CODE:7D3E AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7D3F BEQ horizontal
CODE:7D40 LDA #12 ; Vertical sword hitbox X size: 12
CODE:7D41 STA var_13
CODE:7D42 LDA #16 ; Vertical sword hitbox X size: 16
CODE:7D43 JMP vertical
 
CODE:7D44 horizontal: ; Horizontal sword hitbox X size: 16
CODE:7D44 LDA #16
CODE:7D45 STA var_13
CODE:7D46 LDA #12 ; Horizontal sword hitbox Y size: 12
 
CODE:7D47 vertical: ; Store 12 or 16
CODE:7D47 STA var_14
CODE:7D48 JSR check_weapon_hit_2
CODE:7D49 LDA var_6
CODE:7D4A BEQ locret_107D25
CODE:7D4B JMP check_if_darknut
 
CODE:7D5F check_attack_arrow:
CODE:7D5F STY var_0
CODE:7D60 LDA walk_state_and_weapon_state,Y ; Read arrow_state (Y = 0x12).
CODE:7D61 CMP #ArrowState_Type_Unknown
CODE:7D62 BCC continue_check_attack_arrow_2 ; < 0x30
CODE:7D63 LDA #DamageType_Sword
CODE:7D64 STA var_9 ; Set to DamageType_Sword for (?).
CODE:7D65 LDA #$20 ; 0x20 damage for arrows
CODE:7D66 BNE continue_check_attack_arrow ; I'm not sure when this code path is taken.
 
CODE:7D67 continue_check_attack_arrow_2:
CODE:7D67 CMP #ArrowState_ArrowHit
CODE:7D68 BCS locret_107DCA ; Skip if the arrow has already hit
CODE:7D69 LDA #DamageType_Arrow
CODE:7D6A STA var_9 ; Set to 0x04 for arrows.
CODE:7D6B LDA #$20 ; 0x20 damage for arrows
CODE:7D6C LDY have_arrow_type
CODE:7D6D CPY #1
CODE:7D6E BEQ no_magic_arrows
CODE:7D6F ASL A ; Double damage for magic arrows (0x40)
 
CODE:7D70 no_magic_arrows:
CODE:7D70 LDY #11
CODE:7D71 STY var_13 ; Arrow hitbox size: 11
 
CODE:7D86 continue_check_attack_beam_sword_rod:
CODE:7D86 JSR check_weapon_hit_1
CODE:7D87 LDA var_6
CODE:7D88 BEQ locret_107DCA
CODE:7D89 CPY #AttackType_ArrowOrMeleeRod ; An arrow in the air, or the melee part of the rod attack.
CODE:7D8A BNE check_if_darknut
CODE:7D8B LDA object_type,X ; Check arrows vs. Pols Voice
CODE:7D8C CMP #ObjectType_PolsVoice
CODE:7D8D BNE not_pols_voice
CODE:7D8E LDA #0
CODE:7D8F STA enemy_health,X ; One hit kill with arrows vs. Pols Voice
CODE:7D90 JMP apply_damage_to_enemy
 
CODE:7D91 not_pols_voice: ; Mark the arrow hit, so we don't affect any other enemies.
CODE:7D91 LDA #ArrowState_ArrowHit
CODE:7D92 STA walk_state_and_weapon_state,Y
CODE:7D93 LDA #3
CODE:7D94 STA object_animation_frame_timer,Y
 
CODE:7DAA check_if_darknut: ; Check if Darknut
CODE:7DAA LDA object_type,X
CODE:7DAB CMP #ObjectType_RedDarknut
CODE:7DAC BEQ check_darknut_shield
CODE:7DAD CMP #ObjectType_BlueDarknut
CODE:7DAE BNE not_darknut
 
CODE:7DAF check_darknut_shield: ; Check if the Darknut was facing the opposite direction of
CODE:7DAF LDA object_direction,Y ; the attack.
CODE:7DB0 ORA object_direction,X
CODE:7DB1 CMP #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7DB2 BEQ play_shield_ting
CODE:7DB3 CMP #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
CODE:7DB4 BEQ play_shield_ting
 
CODE:7DB5 not_darknut: ; Apply knockback after a hit.
CODE:7DB5 JMP apply_knockback
  ; X is the object ID of the enemy. This is either the enemy being hit, or the enemy hitting Link.
  ; Y = 0 if we're applying knockback to Link being hit by an enemy.
  ; Y is an AttackType if we're applying knockback to the enemy ID in X being hit by one of Link's weapons.
 
  ; var_9 is the current DamageType.
 
Subroutine play_shield_ting
CODE:7DC5 play_shield_ting:
CODE:7DC5 LDA #Sound3_ShieldTing
CODE:7DC6 STA play_sound_3
 
CODE:7DCA locret_107DCA:
CODE:7DCA RTS
 
Subroutine check_weapon_hit_1
CODE:7DCB check_weapon_hit_1:
CODE:7DCB STA var_7 ; Store attack damage
CODE:7DCC LDA var_13 ; Hitbox X size
CODE:7DCD STA var_14 ; Set hitbox Y size to var_13 (this is 11 for arrows, 12 for beam sword and rod)
 
CODE:7DD1 check_weapon_hit_2:
CODE:7DD1 LDY var_0
CODE:7DD2 LDA object_direction
CODE:7DD3 AND #ControllerBits_Dpad_Down|ControllerBits_Dpad_Up
CODE:7DD4 BEQ horizontal
CODE:7DD5 LDA object_x,Y
CODE:7DD6 CLC
CODE:7DD7 ADC #6
CODE:7DD8 STA var_4 ; X + 6
CODE:7DD9 LDA object_y,Y
CODE:7DDA CLC
CODE:7DDB ADC #8
CODE:7DDC JMP vertical
 
CODE:7DDD horizontal:
CODE:7DDD LDA object_x,Y
CODE:7DDE CLC
CODE:7DDF ADC #8
CODE:7DE0 STA var_4 ; X + 8
CODE:7DE1 LDA object_y,Y
CODE:7DE2 CLC
CODE:7DE3 ADC #6
 
CODE:7DE4 vertical:
CODE:7DE4 JMP check_weapon_hit
 
Subroutine check_hitbox
; In var_4/var_5: Target's X,Y position ; In A: Target's hitbox size ; Out A, var_6: 1 if hit
CODE:7DFB check_hitbox:
CODE:7DFB STA var_13 ; Hitbox X size
CODE:7DFC STA var_14 ; Hitbox Y size
 
CODE:7DFF check_hitbox_with_specified_size:
CODE:7DFF LDA #0
CODE:7E00 STA var_6 ; Set to 0
CODE:7E01 LDY var_0
CODE:7E02 LDA var_2
CODE:7E03 SEC
CODE:7E04 SBC var_4
CODE:7E05 JSR absolute_value ; A = abs(A)
CODE:7E06 STA var_10
CODE:7E07 CMP var_13
CODE:7E08 BCS ret ; return if A >= var_13
CODE:7E09 LDA var_3
CODE:7E0A SEC
CODE:7E0B SBC var_5
CODE:7E0C JSR absolute_value ; A = abs(A)
CODE:7E0D STA var_11
CODE:7E0E CMP var_14
CODE:7E0F BCS ret ; return if A >= var_14
CODE:7E10 INC var_6
 
CODE:7E11 ret:
CODE:7E11 LDA var_6
CODE:7E12 RTS
 
Subroutine apply_knockback
; Apply knockback after a hit. ; ; X is the object ID of the enemy. This is either the enemy being hit, or the enemy hitting Link. ; Y = 0 if we're applying knockback to Link being hit by an enemy. ; Y is an AttackType if we're applying knockback to the enemy ID in X being hit by one of Link's weapons. ; ; var_9 is the current DamageType.
CODE:7E26 apply_knockback:
CODE:7E26 LDY var_0
CODE:7E27 CPX #AttackType_Sword
CODE:7E28 BCS skip_knockback_flag_check ; Branch if X isn't an object ID. Is there any case where this happens?
CODE:7E29 LDA damage_types_with_no_knockback,X
CODE:7E2A AND var_9 ; var_9 is the current DamageType flag. If this enemy ignores knockback for
  ; this damage type, stop.
CODE:7E2B BNE ret
 
CODE:7E2C skip_knockback_flag_check: ; Path for Link being attacked
CODE:7E2C LDA #ControllerBits_Dpad_Up
  ; Figure out the direction of the attack relative to what's being hit.
  ; This will be the knockback direction.
CODE:7E2D STA var_8 ; Set to 8.
CODE:7E2E LDA object_y,X
CODE:7E2F STA var_4 ; Set to object X's Y position.
CODE:7E30 LDA object_y,Y
CODE:7E31 STA var_5 ; Set to object Y's Y position.
CODE:7E32 CPY #0
CODE:7E33 BNE loc_107E51 ; Branch if not Link.
CODE:7E34 LDA object_tile_offset_whole
CODE:7E35 BEQ loc_107E51 ; Branch if on a tile.
CODE:7E36 LDA object_direction
CODE:7E37 AND #ControllerBits_Dpad_Right|ControllerBits_Dpad_Left
CODE:7E38 BNE horizontal
CODE:7E39 BEQ vertical ; Always branch
 
CODE:7E51 loc_107E51: ; Where is var_11 set?
CODE:7E51 LDA var_11
CODE:7E52 CMP #ControllerBits_Dpad_Down
CODE:7E53 BCS vertical
 
CODE:7E54 horizontal:
CODE:7E54 LDA #ControllerBits_Dpad_Left
CODE:7E55 STA var_8 ; Set to 2.
CODE:7E56 LDA object_x,X
CODE:7E57 STA var_4 ; Set to object X's X position.
CODE:7E58 LDA object_x,Y
CODE:7E59 STA var_5 ; Set to object Y's X position.
 
CODE:7E5A vertical:
CODE:7E5A LDA var_4
CODE:7E5B CMP var_5
CODE:7E5C BCS not_greater ; Branch if object X's position >= object Y's position.
CODE:7E5D LSR var_8 ; ControllerBits_Dpad_Up -> ControllerBits_Dpad_Down, or ControllerBits_Dpad_Left -> Right
 
CODE:7E5E not_greater:
CODE:7E5E CPY #0
CODE:7E5F BNE not_link ; Check if Y is Link.
CODE:7E60 LDA invincibility_frames ; Link is being hit by an enemy.
CODE:7E61 BNE ret ; Skip if Link has invincibility frames.
CODE:7E62 LDA var_8
CODE:7E63 ORA #KnockbackFlags_MaintainTileAlignment
CODE:7E64 STA object_knockback ; Set to a direction | KnockbackFlags_MaintainTileAlignment.
CODE:7E65 LDA #24
CODE:7E66 STA invincibility_frames ; Set to 24
CODE:7E67 LDA #$20
CODE:7E68 STA knockback_frames ; Set to 0x20 for Link.
CODE:7E69 CPX #AttackType_Sword ; Return if X is one of Link's own weapons.
CODE:7E6A BCS ret
CODE:7E6B LDA enemy_properties,X ; Load to check EnemyProperties_ReverseDirectionAfterHittingLink.
CODE:7E6C AND #EnemyProperties_ReverseDirectionAfterHittingLink
CODE:7E6D BNE ret
CODE:7E6E LDA object_type,X ; Check if ObjectType_Vire
CODE:7E6F CMP #ObjectType_Vire
CODE:7E70 BEQ ret
CODE:7E71 LDA object_direction,X ; Turn the enemy around after hitting Link.
CODE:7E72 JSR get_opposite_direction_and_index ; In A = direction bit. Out A = opposite direction. Out Y = direction index (0-3).
CODE:7E73 STA object_direction,X
 
CODE:7E74 ret:
CODE:7E74 RTS
 
CODE:7E75 not_link:
CODE:7E75 LDA object_direction,Y
CODE:7E76 STA var_8 ; Set var_8 to the object's direction.
CODE:7E77 LDA enemy_properties,X ; Load to check EnemyProperties_ReverseDirectionAfterHittingLink.
  ; This is the "Link hitting enemy" path. What does the 0x40
  ; flag below do?
CODE:7E78 AND #EnemyProperties_ReverseDirectionAfterHittingLink
CODE:7E79 BEQ reverse_direction_not_set
CODE:7E7A LDA var_8 ; var_8 |= AltMovementFlags_Unknown_0x40
CODE:7E7B ORA #KnockbackFlags_Unknown_0x40
CODE:7E7C STA var_8
 
CODE:7E7D reverse_direction_not_set: ; Check if this enemy is already in invincibility frames.
CODE:7E7D LDA invincibility_frames,X
CODE:7E7E BNE ret2
CODE:7E7F LDA object_type,X ; Check if Gohma
CODE:7E80 CMP #ObjectType_BlueGohma
CODE:7E81 BEQ is_gohma
CODE:7E82 CMP #ObjectType_RedGohma
CODE:7E83 BNE save_knockback
 
CODE:7E84 is_gohma:
CODE:7E84 LDA var_15
CODE:7E85 CMP #3
CODE:7E86 BEQ loc_107ECA
CODE:7E87 CMP #4
CODE:7E88 BNE ret2
 
CODE:7ECA loc_107ECA: ; Branch if Gohma's state_1 isn't 3. This is probably checking
CODE:7ECA LDA enemy_state_1,X ; whether its eye is open.
CODE:7ECB CMP #3
CODE:7ECC BNE ret2
 
CODE:7ECD save_knockback: ; Load object direction (possibly with 0x40 set)
CODE:7ECD LDA var_8
CODE:7ECE ORA #KnockbackFlags_MaintainTileAlignment ; var_8 |= KnockbackFlags_MaintainTileAlignment
CODE:7ECF STA object_knockback,X ; Set a direction, with KnockbackFlags_MaintainTileAlignment and possibly 0x40 set.
CODE:7ED0 LDA #$40
CODE:7ED1 STA knockback_frames,X ; Set to 0x40 for an enemy hit by Link.
CODE:7ED2 LDA #16
CODE:7ED3 STA invincibility_frames,X ; Set to 16
 
CODE:7ED4 ret2:
CODE:7ED4 RTS
 
CODE:7ED5 Skipped empty chunk
CODE:7FFF sram_check_byte2: .BYTE $FF