{
 "schema": 1,
 "platform": "c64",
 "game": "toki",
 "build": "Ocean type 1 cartridge, 16 banks of 8 KB (128 KB)",
 "source": "regenerator2000 live",
 "regions": {
  "exclude": [
   [
    256,
    511,
    "stack"
   ],
   [
    53248,
    57343,
    "I/O and colour RAM"
   ]
  ],
  "extra": []
 },
 "blocks": [
  {
   "start": 0,
   "end": 4,
   "type": "Code"
  },
  {
   "start": 5,
   "end": 255,
   "type": "Undefined"
  },
  {
   "start": 256,
   "end": 279,
   "type": "Code"
  },
  {
   "start": 280,
   "end": 286,
   "type": "Undefined"
  },
  {
   "start": 287,
   "end": 398,
   "type": "Code"
  },
  {
   "start": 399,
   "end": 1279,
   "type": "Undefined"
  },
  {
   "start": 1280,
   "end": 1855,
   "type": "Code"
  },
  {
   "start": 1856,
   "end": 2714,
   "type": "Undefined"
  },
  {
   "start": 2715,
   "end": 2975,
   "type": "Code"
  },
  {
   "start": 2976,
   "end": 3041,
   "type": "Undefined"
  },
  {
   "start": 3042,
   "end": 3072,
   "type": "Code"
  },
  {
   "start": 3073,
   "end": 3076,
   "type": "Undefined"
  },
  {
   "start": 3077,
   "end": 3087,
   "type": "Code"
  },
  {
   "start": 3088,
   "end": 16383,
   "type": "Undefined"
  },
  {
   "start": 16384,
   "end": 16390,
   "type": "Code"
  },
  {
   "start": 16391,
   "end": 16405,
   "type": "Undefined"
  },
  {
   "start": 16406,
   "end": 17291,
   "type": "Code"
  },
  {
   "start": 17292,
   "end": 17306,
   "type": "Undefined"
  },
  {
   "start": 17307,
   "end": 18947,
   "type": "Code"
  },
  {
   "start": 18948,
   "end": 18950,
   "type": "Undefined"
  },
  {
   "start": 18951,
   "end": 19047,
   "type": "Code"
  },
  {
   "start": 19048,
   "end": 19050,
   "type": "Undefined"
  },
  {
   "start": 19051,
   "end": 19142,
   "type": "Code"
  },
  {
   "start": 19143,
   "end": 19145,
   "type": "Undefined"
  },
  {
   "start": 19146,
   "end": 19261,
   "type": "Code"
  },
  {
   "start": 19262,
   "end": 19264,
   "type": "Undefined"
  },
  {
   "start": 19265,
   "end": 19496,
   "type": "Code"
  },
  {
   "start": 19497,
   "end": 19740,
   "type": "Undefined"
  },
  {
   "start": 19741,
   "end": 21282,
   "type": "Code"
  },
  {
   "start": 21283,
   "end": 23426,
   "type": "Undefined"
  },
  {
   "start": 23427,
   "end": 25854,
   "type": "Code"
  },
  {
   "start": 25855,
   "end": 26124,
   "type": "Undefined"
  },
  {
   "start": 26125,
   "end": 26936,
   "type": "Code"
  },
  {
   "start": 26937,
   "end": 26942,
   "type": "Undefined"
  },
  {
   "start": 26943,
   "end": 27029,
   "type": "Code"
  },
  {
   "start": 27030,
   "end": 27070,
   "type": "Undefined"
  },
  {
   "start": 27071,
   "end": 27085,
   "type": "Code"
  },
  {
   "start": 27086,
   "end": 27144,
   "type": "Undefined"
  },
  {
   "start": 27145,
   "end": 27218,
   "type": "Code"
  },
  {
   "start": 27219,
   "end": 27281,
   "type": "Undefined"
  },
  {
   "start": 27282,
   "end": 27319,
   "type": "Code"
  },
  {
   "start": 27320,
   "end": 27453,
   "type": "Undefined"
  },
  {
   "start": 27454,
   "end": 27473,
   "type": "Code"
  },
  {
   "start": 27474,
   "end": 27783,
   "type": "Undefined"
  },
  {
   "start": 27784,
   "end": 28390,
   "type": "Code"
  },
  {
   "start": 28391,
   "end": 32767,
   "type": "Undefined"
  },
  {
   "start": 32768,
   "end": 37199,
   "type": "Code"
  },
  {
   "start": 37200,
   "end": 37241,
   "type": "Undefined"
  },
  {
   "start": 37242,
   "end": 38307,
   "type": "Code"
  },
  {
   "start": 38308,
   "end": 39154,
   "type": "Undefined"
  },
  {
   "start": 39155,
   "end": 41184,
   "type": "Code"
  },
  {
   "start": 41185,
   "end": 41251,
   "type": "Undefined"
  },
  {
   "start": 41252,
   "end": 42936,
   "type": "Code"
  },
  {
   "start": 42937,
   "end": 43149,
   "type": "Undefined"
  },
  {
   "start": 43150,
   "end": 43173,
   "type": "Code"
  },
  {
   "start": 43174,
   "end": 43407,
   "type": "Undefined"
  },
  {
   "start": 43408,
   "end": 43917,
   "type": "Code"
  },
  {
   "start": 43918,
   "end": 43974,
   "type": "Undefined"
  },
  {
   "start": 43975,
   "end": 44037,
   "type": "Code"
  },
  {
   "start": 44038,
   "end": 44050,
   "type": "Undefined"
  },
  {
   "start": 44051,
   "end": 45883,
   "type": "Code"
  },
  {
   "start": 45884,
   "end": 46457,
   "type": "Undefined"
  },
  {
   "start": 46458,
   "end": 46548,
   "type": "Code"
  },
  {
   "start": 46549,
   "end": 47310,
   "type": "Undefined"
  },
  {
   "start": 47311,
   "end": 47351,
   "type": "Code"
  },
  {
   "start": 47352,
   "end": 48352,
   "type": "Undefined"
  },
  {
   "start": 48353,
   "end": 48372,
   "type": "Code"
  },
  {
   "start": 48373,
   "end": 48476,
   "type": "Undefined"
  },
  {
   "start": 48477,
   "end": 48491,
   "type": "Code"
  },
  {
   "start": 48492,
   "end": 53247,
   "type": "Undefined"
  },
  {
   "start": 53248,
   "end": 64767,
   "type": "Byte"
  },
  {
   "start": 64768,
   "end": 65535,
   "type": "Undefined"
  }
 ],
 "symbols": [
  {
   "address": 0,
   "name": "start",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 1,
   "name": "cpu_port",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2,
   "name": "stream_src",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 3,
   "name": "zpa_03",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 4,
   "name": "stream_dst",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 5,
   "name": "zpa_05",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 6,
   "name": "scroll_fine_x",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7,
   "name": "scroll_fine_y",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8,
   "name": "joy_bits",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 9,
   "name": "player_mode",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 10,
   "name": "move_step",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 11,
   "name": "mode1_horizontal",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 12,
   "name": "slope_kind",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 13,
   "name": "move_dir",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 14,
   "name": "scroll_phase",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 15,
   "name": "scroll_dir",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 16,
   "name": "zpa_10",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 17,
   "name": "zpa_11",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 18,
   "name": "sprite_count",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 19,
   "name": "sprite_bucket_max",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 20,
   "name": "obj_first",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 21,
   "name": "obj_end",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 22,
   "name": "temp_first",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 23,
   "name": "temp_end",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 24,
   "name": "player_facing",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 25,
   "name": "ride_dir",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 26,
   "name": "stand_obj",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 28,
   "name": "scroll_x",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 29,
   "name": "zpa_1D",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 30,
   "name": "scroll_y",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 31,
   "name": "zpa_1F",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 32,
   "name": "zpa_20",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 33,
   "name": "zpa_21",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 34,
   "name": "zpa_22",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 35,
   "name": "zpa_23",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 36,
   "name": "section_table_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 37,
   "name": "zpa_25",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 38,
   "name": "section_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 39,
   "name": "zpa_27",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 40,
   "name": "weapon_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 41,
   "name": "zpa_29",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 42,
   "name": "map_row_lo_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 44,
   "name": "map_row_hi_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 46,
   "name": "block_chars_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 47,
   "name": "zpa_2F",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 48,
   "name": "block_props_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 50,
   "name": "path_table_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 54,
   "name": "script_ptr_a",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 56,
   "name": "script_ptr_b",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 58,
   "name": "anim_lo_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 59,
   "name": "zpa_3B",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 60,
   "name": "anim_hi_ptr",
   "type": "ZeroPagePointer",
   "kind": "user"
  },
  {
   "address": 61,
   "name": "zpa_3D",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 64,
   "name": "view_left",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 65,
   "name": "zpa_41",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 66,
   "name": "view_top",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 67,
   "name": "zpa_43",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 68,
   "name": "view_right",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 69,
   "name": "zpa_45",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 70,
   "name": "view_bottom",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 71,
   "name": "zpa_47",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 72,
   "name": "patch_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 73,
   "name": "zpa_49",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 74,
   "name": "award_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 75,
   "name": "zpa_4B",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 76,
   "name": "player_box_left",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 77,
   "name": "player_box_left_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 78,
   "name": "player_box_right",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 79,
   "name": "player_box_right_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 80,
   "name": "player_box_top",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 81,
   "name": "player_box_top_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 82,
   "name": "player_box_bottom",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 83,
   "name": "player_box_bottom_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 84,
   "name": "player_box2_left",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 85,
   "name": "player_box2_left_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 86,
   "name": "player_box2_right",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 87,
   "name": "player_box2_right_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 88,
   "name": "player_box2_top",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 89,
   "name": "player_box2_top_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 90,
   "name": "player_box2_bottom",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 91,
   "name": "player_box2_bottom_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 92,
   "name": "path_end",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 96,
   "name": "path_axes",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 100,
   "name": "path_pos",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 107,
   "name": "sprite_more",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 108,
   "name": "hw_sprite_free_line",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 116,
   "name": "platform_list",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 124,
   "name": "nmi_save_x",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 125,
   "name": "nmi_save_y",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 126,
   "name": "sprite_overflow_queue",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 128,
   "name": "overflow_queue_2",
   "type": "ZeroPagePointer",
   "kind": "auto"
  },
  {
   "address": 143,
   "name": "sound_save_y",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 144,
   "name": "sound_queue_count",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 145,
   "name": "sound_queue",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 148,
   "name": "all_move_flag",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 223,
   "name": "music_mode",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 224,
   "name": "zpa_E0",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 225,
   "name": "zpa_E1",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 226,
   "name": "zpa_E2",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 227,
   "name": "zpa_E3",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 228,
   "name": "zpa_E4",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 229,
   "name": "zpa_E5",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 230,
   "name": "zpa_E6",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 231,
   "name": "zpa_E7",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 232,
   "name": "zpa_E8",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 233,
   "name": "zpa_E9",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 234,
   "name": "zpa_EA",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 235,
   "name": "zpa_EB",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 236,
   "name": "zpa_EC",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 237,
   "name": "zpa_ED",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 238,
   "name": "zpa_EE",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 239,
   "name": "zpa_EF",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 240,
   "name": "zpa_F0",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 243,
   "name": "temp_slot",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 244,
   "name": "zpa_F4",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 245,
   "name": "voice_script_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 246,
   "name": "zpa_F6",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 247,
   "name": "effect_script_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 248,
   "name": "zpa_F8",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 251,
   "name": "zpa_FB",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 252,
   "name": "f_00FC",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 253,
   "name": "zpa_FD",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 254,
   "name": "zpa_FE",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 255,
   "name": "zpa_FF",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 256,
   "name": "cart_copy_six",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 257,
   "name": "f_0101",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 258,
   "name": "f_0102",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 264,
   "name": "b_0108",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 287,
   "name": "cart_copy",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 337,
   "name": "b_0151",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 347,
   "name": "b_015B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 364,
   "name": "b_016C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 366,
   "name": "b_016E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 376,
   "name": "b_0178",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 398,
   "name": "r_018E",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 512,
   "name": "spr_irq_colour",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 536,
   "name": "spr_irq_height",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 560,
   "name": "spr_irq_pointer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 584,
   "name": "spr_irq_x_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 608,
   "name": "spr_irq_x_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 632,
   "name": "spr_irq_y",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 656,
   "name": "blink_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 657,
   "name": "far_column_prop",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 658,
   "name": "player_hit",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 659,
   "name": "death_countdown",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 660,
   "name": "intro_phase",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 661,
   "name": "ride_speed",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 662,
   "name": "anim_key",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 663,
   "name": "aim_dir",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 664,
   "name": "section_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 665,
   "name": "stance",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 666,
   "name": "move_mask",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 667,
   "name": "player_screen_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 668,
   "name": "a_029C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 669,
   "name": "player_screen_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 670,
   "name": "frame_bits",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 678,
   "name": "sprite_enable_masks",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 699,
   "name": "score_awards",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 714,
   "name": "pause_flag",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 715,
   "name": "shape_cache_3",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 716,
   "name": "shape_cache_1",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 717,
   "name": "shape_cache_2",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 718,
   "name": "jump_rise_steps",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 735,
   "name": "jump_fall_steps",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 744,
   "name": "screen_row_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 764,
   "name": "screen_row_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 794,
   "name": "box1_left_off",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 795,
   "name": "box1_width",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 796,
   "name": "box1_top_off",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 797,
   "name": "box1_height",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 798,
   "name": "box2_left_off",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 799,
   "name": "box2_right_off",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 800,
   "name": "box2_top_off",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 801,
   "name": "box2_height",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 802,
   "name": "sprite_off_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 803,
   "name": "sprite_off_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 804,
   "name": "scroll_handler_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 812,
   "name": "scroll_handler_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 820,
   "name": "shot_start_offsets",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 821,
   "name": "f_0335",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 840,
   "name": "shot_frame_data",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 920,
   "name": "shot_list_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 923,
   "name": "shot_list_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1015,
   "name": "box2_left_tab",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1025,
   "name": "box2_top_tab",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1035,
   "name": "box2_width_tab",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1045,
   "name": "box2_height_tab",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1070,
   "name": "award_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1073,
   "name": "award_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1076,
   "name": "gauge_tiles",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1112,
   "name": "player_anim_tables",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1256,
   "name": "transition_shapes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1257,
   "name": "f_04E9",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1260,
   "name": "transition_boxes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1261,
   "name": "f_04ED",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1262,
   "name": "f_04EE",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1263,
   "name": "f_04EF",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1280,
   "name": "load_stage_bank_records",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 1297,
   "name": "b_0511",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1328,
   "name": "j_0530",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 1363,
   "name": "b_0553",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1434,
   "name": "unpack_bank_record",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 1492,
   "name": "b_05D4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1494,
   "name": "b_05D6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1526,
   "name": "b_05F6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1591,
   "name": "b_0637",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1620,
   "name": "j_0654",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 1631,
   "name": "b_065F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1662,
   "name": "b_067E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1672,
   "name": "b_0688",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1709,
   "name": "b_06AD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1757,
   "name": "shot_flags",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1758,
   "name": "f_06DE",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1763,
   "name": "shot_x_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1764,
   "name": "f_06E4",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1766,
   "name": "s_06E6",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 1769,
   "name": "shot_x_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1770,
   "name": "f_06EA",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1775,
   "name": "shot_y_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1776,
   "name": "f_06F0",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1781,
   "name": "shot_y_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1782,
   "name": "f_06F6",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1786,
   "name": "b_06FA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1787,
   "name": "shot_path_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1788,
   "name": "f_06FC",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1790,
   "name": "j_06FE",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 1793,
   "name": "shot_path_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1794,
   "name": "b_0702",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1799,
   "name": "shot_path_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1800,
   "name": "f_0708",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1805,
   "name": "shot_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1806,
   "name": "f_070E",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1810,
   "name": "b_0712",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 1811,
   "name": "shot_list_type",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1812,
   "name": "f_0714",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1817,
   "name": "shot_frame_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1818,
   "name": "f_071A",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1823,
   "name": "shot_frame_end",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1824,
   "name": "f_0720",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1829,
   "name": "shot_anim_mask",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1830,
   "name": "f_0726",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1835,
   "name": "shot_x2_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1836,
   "name": "f_072C",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1841,
   "name": "shot_x2_hi",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 1842,
   "name": "f_0732",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1847,
   "name": "shot_y2_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1848,
   "name": "f_0738",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1851,
   "name": "f_073B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1852,
   "name": "f_073C",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1853,
   "name": "shot_y2_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1854,
   "name": "f_073E",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1855,
   "name": "f_073F",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1856,
   "name": "f_0740",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1857,
   "name": "f_0741",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1858,
   "name": "f_0742",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1859,
   "name": "cell_save_stack",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1860,
   "name": "f_0744",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1861,
   "name": "f_0745",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1862,
   "name": "f_0746",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1863,
   "name": "f_0747",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1864,
   "name": "f_0748",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1865,
   "name": "f_0749",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1866,
   "name": "f_074A",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1907,
   "name": "stream_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1908,
   "name": "f_0774",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1963,
   "name": "raster_vector",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1964,
   "name": "a_07AC",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1965,
   "name": "raster_line",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1966,
   "name": "shadow_d011",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1967,
   "name": "shadow_d016",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1968,
   "name": "shadow_d018",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1969,
   "name": "spr_x_msb",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1970,
   "name": "spr_enable",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1971,
   "name": "spr_expand",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1972,
   "name": "spr_colour",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1980,
   "name": "spr_sh_x_msb",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1981,
   "name": "spr_sh_enable",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1982,
   "name": "spr_sh_expand",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1983,
   "name": "spr_sh_colour",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1991,
   "name": "spr_pointer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 1999,
   "name": "spr_free_line",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2000,
   "name": "a_07D0",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2001,
   "name": "a_07D1",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2002,
   "name": "a_07D2",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2003,
   "name": "a_07D3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2004,
   "name": "a_07D4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2005,
   "name": "a_07D5",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2006,
   "name": "a_07D6",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2007,
   "name": "spr_xy",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2008,
   "name": "f_07D8",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 2015,
   "name": "spr_xy_b",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2023,
   "name": "spr_sh_pointer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2031,
   "name": "spr_sh_free_line",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2039,
   "name": "spr_sh_xy",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2047,
   "name": "spr_sh_xy_b",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2055,
   "name": "reuse_queue_pos",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2056,
   "name": "lspr_colour",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2080,
   "name": "lspr_height",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2104,
   "name": "lspr_pointer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2128,
   "name": "lspr_x_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2152,
   "name": "lspr_x_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2176,
   "name": "lspr_y",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2200,
   "name": "timer_frames",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2201,
   "name": "timer_minutes",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2202,
   "name": "timer_tens",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2203,
   "name": "timer_units",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2204,
   "name": "a_089C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2205,
   "name": "lives_tile",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2206,
   "name": "a_089E",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2207,
   "name": "a_089F",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2208,
   "name": "a_08A0",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2209,
   "name": "gauge_value",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2210,
   "name": "stream_pieces_left",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2211,
   "name": "stream_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2212,
   "name": "stream_bank",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2213,
   "name": "stream_block_base",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2214,
   "name": "stream_block",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2215,
   "name": "stream_current",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2216,
   "name": "stream_first_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2220,
   "name": "stream_dest_block",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2224,
   "name": "frame_mode",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2225,
   "name": "player_effect",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2226,
   "name": "player_effect_flash",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2227,
   "name": "player_third_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2228,
   "name": "a_08B4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2229,
   "name": "player_third_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2230,
   "name": "a_08B6",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2231,
   "name": "player_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2232,
   "name": "player_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2233,
   "name": "player_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2234,
   "name": "player_y_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2235,
   "name": "player_try_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2236,
   "name": "player_try_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2237,
   "name": "player_try_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2238,
   "name": "player_try_y_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2239,
   "name": "shown_buf_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2240,
   "name": "shown_buf_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2241,
   "name": "back_buf_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2242,
   "name": "back_buf_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2243,
   "name": "bg_colour0",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2244,
   "name": "bg_colour1",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2245,
   "name": "bg_colour2",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2246,
   "name": "fire_flags",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2247,
   "name": "a_08C7",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2248,
   "name": "a_08C8",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2249,
   "name": "a_08C9",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2250,
   "name": "a_08CA",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2251,
   "name": "a_08CB",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2252,
   "name": "a_08CC",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2253,
   "name": "a_08CD",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2254,
   "name": "player_effect_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2255,
   "name": "scroll_step",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2256,
   "name": "score",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2257,
   "name": "a_08D1",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2258,
   "name": "a_08D2",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2259,
   "name": "a_08D3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2260,
   "name": "a_08D4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2266,
   "name": "leader_x_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2267,
   "name": "leader_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2268,
   "name": "leader_y_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2269,
   "name": "leader_y_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2270,
   "name": "shot_delay",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2271,
   "name": "shot_pose_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2272,
   "name": "weapon_level",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2273,
   "name": "key_col_held",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2274,
   "name": "key_row_held",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2275,
   "name": "player_hit_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2276,
   "name": "a_08E4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2277,
   "name": "player_hit_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2278,
   "name": "a_08E6",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2279,
   "name": "stage",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2280,
   "name": "probe_head_prop",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2281,
   "name": "probe_feet_prop",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2282,
   "name": "player_shape_1",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2283,
   "name": "player_shape_2",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2284,
   "name": "player_shape_3",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2285,
   "name": "sprite1_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2286,
   "name": "sprite2_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2287,
   "name": "sprite3_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2288,
   "name": "sprite1_x_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2289,
   "name": "sprite2_x_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2290,
   "name": "sprite3_x_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2291,
   "name": "sprite1_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2292,
   "name": "sprite2_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2293,
   "name": "sprite3_x_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2294,
   "name": "frame_count",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2295,
   "name": "frame_flag",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2297,
   "name": "cheat_flag",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2298,
   "name": "jump_state",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2299,
   "name": "jump_counter",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2300,
   "name": "jump_start_count",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2301,
   "name": "section_scroll_flags",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2302,
   "name": "view_pinned_edges",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2303,
   "name": "transition_state",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2304,
   "name": "sprite2_beside",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2305,
   "name": "a_0901",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2306,
   "name": "anim_frame",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2307,
   "name": "a_0903",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2308,
   "name": "cell_stack_top",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2309,
   "name": "player_action",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2310,
   "name": "zone_right",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2311,
   "name": "a_0907",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2312,
   "name": "zone_left",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2313,
   "name": "a_0909",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2314,
   "name": "zone_top",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2315,
   "name": "zone_bottom",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2316,
   "name": "irq_panel_save_a",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2317,
   "name": "irq_panel_save_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2318,
   "name": "irq_panel_save_y",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2319,
   "name": "irq_panel_on_save_x",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2320,
   "name": "platform_count",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2321,
   "name": "a_0911",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2322,
   "name": "a_0912",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2323,
   "name": "player_third_on",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2324,
   "name": "body1_colour",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2325,
   "name": "body2_colour",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2326,
   "name": "third_colour",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 2327,
   "name": "pose_records",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2635,
   "name": "pose_still_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2645,
   "name": "pose_still_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2655,
   "name": "pose_stance_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2665,
   "name": "pose_stance_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2675,
   "name": "pose_vert_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2685,
   "name": "pose_vert_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2695,
   "name": "pose_horiz_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2705,
   "name": "pose_horiz_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 2715,
   "name": "stage_load",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 2722,
   "name": "b_0AA2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 2729,
   "name": "b_0AA9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 2814,
   "name": "r_0AFE",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 2815,
   "name": "stage_start",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 2853,
   "name": "b_0B25",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 2956,
   "name": "queue_sound",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 2973,
   "name": "b_0B9D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 3042,
   "name": "sound_frame",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 3046,
   "name": "b_0BE6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 3059,
   "name": "b_0BF3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 3062,
   "name": "s_0BF6",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 3066,
   "name": "b_0BFA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 3074,
   "name": "a_0C02",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3075,
   "name": "a_0C03",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3076,
   "name": "a_0C04",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3077,
   "name": "s_0C05",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 3078,
   "name": "a_0C06",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3079,
   "name": "a_0C07",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3080,
   "name": "a_0C08",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3081,
   "name": "a_0C09",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3082,
   "name": "a_0C0A",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3083,
   "name": "a_0C0B",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3084,
   "name": "f_0C0C",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 3100,
   "name": "a_0C1C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3101,
   "name": "a_0C1D",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3102,
   "name": "a_0C1E",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3103,
   "name": "a_0C1F",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 3106,
   "name": "char_colour_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 3362,
   "name": "section_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 3363,
   "name": "f_0D23",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 3378,
   "name": "block_chars",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6470,
   "name": "map_row_hi_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6526,
   "name": "block_props_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6617,
   "name": "section_records",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6817,
   "name": "anim_hi_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6864,
   "name": "anim_hi_entry_47",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 6865,
   "name": "anim_hi_entry_48",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 6883,
   "name": "anim_lo_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6885,
   "name": "anim_lo_entry_2",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 6886,
   "name": "anim_lo_entry_3",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 6949,
   "name": "anim_swap_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6964,
   "name": "script_addr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 7025,
   "name": "script_addr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 7086,
   "name": "script_data_a",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 7432,
   "name": "script_word_a",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7433,
   "name": "script_word_a_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7434,
   "name": "script_word_b",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7435,
   "name": "script_word_b_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7530,
   "name": "script_word_c",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 7531,
   "name": "script_word_c_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8110,
   "name": "script_data_b",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 8145,
   "name": "path_address_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 8158,
   "name": "path_data",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 8216,
   "name": "path_patch_2018",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8217,
   "name": "path_patch_2019",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8218,
   "name": "path_patch_201A",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8219,
   "name": "path_source_201B",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8238,
   "name": "path_source_202E",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8384,
   "name": "stage0_char_shapes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 8510,
   "name": "anim_record_shape_213E",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 8528,
   "name": "anim_record_shape_2150",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 11570,
   "name": "stage_data_2D32",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 11911,
   "name": "stage_data_2E87",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 12490,
   "name": "stage_data_30CA",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 12502,
   "name": "stage_data_30D6",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 12506,
   "name": "stage_data_30DA",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 12922,
   "name": "obj_health",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13006,
   "name": "obj_motion",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13090,
   "name": "obj_motion_alt",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13174,
   "name": "obj_motion_next",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13258,
   "name": "obj_anim_num",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13351,
   "name": "obj_phase",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13444,
   "name": "obj_move_bits",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13537,
   "name": "obj_speed",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13621,
   "name": "obj_anim_delay",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13714,
   "name": "obj_state",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13807,
   "name": "obj_kind",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13899,
   "name": "f_364B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 13900,
   "name": "obj_flags",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 13901,
   "name": "f_364D",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 13984,
   "name": "obj_dir",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14068,
   "name": "obj_off_x",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14152,
   "name": "obj_off_y",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14236,
   "name": "obj_script_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14320,
   "name": "obj_script_repeat",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14572,
   "name": "obj_x_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14612,
   "name": "obj_x_lo_slot_40",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 14613,
   "name": "obj_x_lo_slot_41",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 14665,
   "name": "obj_x_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14757,
   "name": "f_39A5",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 14758,
   "name": "obj_y_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14851,
   "name": "obj_y_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 14944,
   "name": "obj_anim_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15037,
   "name": "obj_draw_min_y",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15130,
   "name": "obj_frame_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15223,
   "name": "obj_frame_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15316,
   "name": "obj_hit_left_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15409,
   "name": "obj_hit_left_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15502,
   "name": "obj_hit_right_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15595,
   "name": "obj_hit_right_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15688,
   "name": "obj_hit_top_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15781,
   "name": "obj_hit_top_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15874,
   "name": "obj_hit_bottom_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 15967,
   "name": "obj_hit_bottom_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16059,
   "name": "f_3EBB",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 16060,
   "name": "obj_anim_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16153,
   "name": "obj_arc_state",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16154,
   "name": "f_3F1A",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 16246,
   "name": "obj_arc_counter",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16247,
   "name": "f_3F77",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 16339,
   "name": "temp_vel_x_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16348,
   "name": "temp_vel_x_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16357,
   "name": "temp_vel_y_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16366,
   "name": "temp_vel_y_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16375,
   "name": "temp_life",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 16384,
   "name": "title_entry",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 16406,
   "name": "stage_intro_start",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 16425,
   "name": "b_4029",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16442,
   "name": "j_403A",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 16452,
   "name": "b_4044",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16477,
   "name": "b_405D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16489,
   "name": "b_4069",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16508,
   "name": "j_407C",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 16514,
   "name": "read_joystick_ports",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 16532,
   "name": "r_4094",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 16533,
   "name": "intro_sprite_wait_loop",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 16567,
   "name": "b_40B7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16589,
   "name": "b_40CD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16612,
   "name": "b_40E4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16642,
   "name": "b_4102",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16658,
   "name": "carry_over_sprite_overflow",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 16665,
   "name": "b_4119",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16686,
   "name": "b_412E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16697,
   "name": "r_4139",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 16698,
   "name": "player_pose",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 16718,
   "name": "b_414E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16724,
   "name": "b_4154",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16761,
   "name": "b_4179",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16770,
   "name": "b_4182",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16797,
   "name": "b_419D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16806,
   "name": "b_41A6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16818,
   "name": "b_41B2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16822,
   "name": "b_41B6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16826,
   "name": "b_41BA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16852,
   "name": "b_41D4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16856,
   "name": "b_41D8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16872,
   "name": "b_41E8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16875,
   "name": "b_41EB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16966,
   "name": "restore_player_pos",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 16969,
   "name": "restore_player_x",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16982,
   "name": "restore_player_y",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16995,
   "name": "save_player_x",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17008,
   "name": "save_player_y",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17021,
   "name": "set_view_window",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17110,
   "name": "b_42D6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17121,
   "name": "move_prev_x_left",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17143,
   "name": "r_42F7",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17144,
   "name": "move_prev_x_right",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17166,
   "name": "r_430E",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17167,
   "name": "move_prev_y_up",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 17189,
   "name": "r_4325",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17190,
   "name": "move_prev_y_down",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 17212,
   "name": "r_433C",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17213,
   "name": "set_dir_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17222,
   "name": "set_dir_up_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17231,
   "name": "set_dir_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17240,
   "name": "set_dir_down_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17249,
   "name": "stop_scroll",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17256,
   "name": "set_dir_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17265,
   "name": "set_dir_down_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17274,
   "name": "set_dir_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17283,
   "name": "set_dir_up_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17307,
   "name": "add_score_points",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17331,
   "name": "b_43B3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17342,
   "name": "b_43BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17348,
   "name": "r_43C4",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17349,
   "name": "copy_scroll_y_row",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17365,
   "name": "scroll_y_minus_one_row",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17385,
   "name": "scroll_y_plus_one_row",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17403,
   "name": "j_43FB",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17436,
   "name": "j_441C",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17452,
   "name": "draw_column_left_of_view",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17472,
   "name": "j_4440",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17490,
   "name": "j_4452",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17518,
   "name": "j_446E",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17549,
   "name": "b_448D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17594,
   "name": "b_44BA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17632,
   "name": "f_44E0",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 17633,
   "name": "r_44E1",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 17634,
   "name": "draw_column_odd_start",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17679,
   "name": "b_450F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17745,
   "name": "b_4551",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17774,
   "name": "j_456E",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 17790,
   "name": "draw_row_x_plus1_y_minus1",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 17811,
   "name": "draw_row_x_minus1_y_minus1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17830,
   "name": "b_45A6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 17860,
   "name": "draw_bottom_row_x_plus0",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17876,
   "name": "draw_bottom_row_x_plus1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17896,
   "name": "draw_bottom_row_x_minus1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 17915,
   "name": "set_bottom_row_pointers",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 17946,
   "name": "map_row_copy_start",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18000,
   "name": "copy_row_even_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18040,
   "name": "b_4678",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18059,
   "name": "b_468B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18074,
   "name": "r_469A",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18075,
   "name": "copy_row_odd_start",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18115,
   "name": "b_46C3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18161,
   "name": "b_46F1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18175,
   "name": "b_46FF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18181,
   "name": "b_4705",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18188,
   "name": "update_view_scroll",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 18198,
   "name": "auto_scroll_horizontal",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18217,
   "name": "b_4729",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18227,
   "name": "b_4733",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18230,
   "name": "follow_player_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18246,
   "name": "b_4746",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18249,
   "name": "b_4749",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18252,
   "name": "b_474C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18255,
   "name": "b_474F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18258,
   "name": "b_4752",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18261,
   "name": "b_4755",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18264,
   "name": "b_4758",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18267,
   "name": "b_475B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18270,
   "name": "auto_scroll_vertical",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18291,
   "name": "b_4773",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18301,
   "name": "b_477D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18304,
   "name": "follow_player_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18336,
   "name": "follow_player_both",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18381,
   "name": "b_47CD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18397,
   "name": "b_47DD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18400,
   "name": "b_47E0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18403,
   "name": "b_47E3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18406,
   "name": "b_47E6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18409,
   "name": "b_47E9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18425,
   "name": "try_scroll_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18435,
   "name": "b_4803",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18441,
   "name": "b_4809",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18444,
   "name": "try_scroll_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18456,
   "name": "b_4818",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18459,
   "name": "try_scroll_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18471,
   "name": "b_4827",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18474,
   "name": "try_scroll_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18486,
   "name": "b_4836",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18489,
   "name": "try_up_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18500,
   "name": "b_4844",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18511,
   "name": "b_484F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18514,
   "name": "try_up_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18525,
   "name": "b_485D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18536,
   "name": "b_4868",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18539,
   "name": "try_down_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18550,
   "name": "b_4876",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18561,
   "name": "b_4881",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18564,
   "name": "try_down_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18575,
   "name": "b_488F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18586,
   "name": "b_489A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18589,
   "name": "scroll_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18598,
   "name": "r_48A6",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18599,
   "name": "b_48A7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18627,
   "name": "b_48C3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18656,
   "name": "scroll_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18665,
   "name": "r_48E9",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18666,
   "name": "b_48EA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18709,
   "name": "b_4915",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18722,
   "name": "b_4922",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18737,
   "name": "scroll_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18744,
   "name": "r_4938",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18745,
   "name": "b_4939",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18777,
   "name": "b_4959",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18804,
   "name": "b_4974",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18817,
   "name": "b_4981",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18832,
   "name": "scroll_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18841,
   "name": "r_4999",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18842,
   "name": "b_499A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18867,
   "name": "b_49B3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18899,
   "name": "b_49D3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18914,
   "name": "scroll_up_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18929,
   "name": "b_49F1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18947,
   "name": "r_4A03",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 18948,
   "name": "unused_jump_4A04",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18951,
   "name": "b_4A07",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 18954,
   "name": "step_up_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 18990,
   "name": "b_4A2E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19032,
   "name": "scroll_down_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19047,
   "name": "r_4A67",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 19048,
   "name": "unused_jump_4A68",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19051,
   "name": "b_4A6B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19054,
   "name": "step_down_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19084,
   "name": "b_4A8C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19118,
   "name": "scroll_down_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19124,
   "name": "b_4AB4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19142,
   "name": "r_4AC6",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 19143,
   "name": "unused_jump_4AC7",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19146,
   "name": "b_4ACA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19149,
   "name": "step_down_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19192,
   "name": "b_4AF8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19234,
   "name": "scroll_up_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19240,
   "name": "b_4B28",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19246,
   "name": "b_4B2E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19261,
   "name": "r_4B3D",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 19262,
   "name": "unused_jump_4B3E",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19265,
   "name": "b_4B41",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19268,
   "name": "step_up_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19307,
   "name": "b_4B6B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19338,
   "name": "tile_scroll_done",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19363,
   "name": "room_to_scroll_right",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19376,
   "name": "room_to_scroll_left",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19389,
   "name": "room_to_scroll_down",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19402,
   "name": "room_to_scroll_up",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19422,
   "name": "b_4BDE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19435,
   "name": "fine_y_steps",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19439,
   "name": "fine_x_steps",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19441,
   "name": "b_4BF1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19452,
   "name": "r_4BFC",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 19453,
   "name": "pin_view_top",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19464,
   "name": "pin_view_bottom",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19475,
   "name": "pin_view_left",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19486,
   "name": "pin_view_right",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19741,
   "name": "nmi_frame",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 19756,
   "name": "frame_state_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19773,
   "name": "blank_screen_exit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19778,
   "name": "frame_exit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19783,
   "name": "copy_sprite_shadows",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19786,
   "name": "b_4D4A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19866,
   "name": "wait_and_set_vic",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19873,
   "name": "b_4DA1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19878,
   "name": "apply_vic_shadows",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19931,
   "name": "patch_stage_code",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 19963,
   "name": "b_4DFB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19973,
   "name": "stage0_clear_buf",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19975,
   "name": "b_4E07",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19982,
   "name": "stage_not0",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 19986,
   "name": "stage1_patch",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20020,
   "name": "stage_not1",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20024,
   "name": "stage2_patch",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20066,
   "name": "stage2_common",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20093,
   "name": "stage2_tail",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20147,
   "name": "stage_not2",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20151,
   "name": "stage3_patch",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20188,
   "name": "patch_stage_exit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20189,
   "name": "init_round_state",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 20305,
   "name": "clear_obj_state_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20315,
   "name": "clear_06dd_table_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20357,
   "name": "find_start_record_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20418,
   "name": "skip_to_next_start_record",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20420,
   "name": "skip_record_scan_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20439,
   "name": "load_start_record",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20494,
   "name": "store_section_index",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20523,
   "name": "next_spawn_range",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20536,
   "name": "spawn_range_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20548,
   "name": "finish_round_setup",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20582,
   "name": "reserve_player_object_slots_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 20626,
   "name": "copy_sprite_shapes",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 20659,
   "name": "b_50B3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20667,
   "name": "b_50BB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20692,
   "name": "b_50D4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20700,
   "name": "b_50DC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20725,
   "name": "b_50F5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20733,
   "name": "b_50FD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20744,
   "name": "stream_cartridge_data_to_ram",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 20752,
   "name": "b_5110",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20776,
   "name": "b_5128",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20788,
   "name": "b_5134",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20840,
   "name": "start_stream_destination",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 20877,
   "name": "load_stream_source",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 20905,
   "name": "b_51A9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20942,
   "name": "b_51CE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 20945,
   "name": "stream_restore_bank_and_io",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 20955,
   "name": "copy_three_cart_entries",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 20987,
   "name": "game_init",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 20989,
   "name": "b_51FD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21010,
   "name": "b_5212",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21085,
   "name": "b_525D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21095,
   "name": "s_5267",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 21100,
   "name": "s_526C",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 21105,
   "name": "nmi_and_first_copy",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 21136,
   "name": "read_keys",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 21182,
   "name": "j_52BE",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 21188,
   "name": "b_52C4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21197,
   "name": "b_52CD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21208,
   "name": "b_52D8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21243,
   "name": "b_52FB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 21256,
   "name": "b_5308",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23427,
   "name": "scroll_draw_edge",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 23432,
   "name": "b_5B88",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23460,
   "name": "b_5BA4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23463,
   "name": "b_5BA7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23469,
   "name": "b_5BAD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23472,
   "name": "b_5BB0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23478,
   "name": "b_5BB6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23481,
   "name": "b_5BB9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23487,
   "name": "b_5BBF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23490,
   "name": "recolour_screen",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 23497,
   "name": "recolour_c800",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 23500,
   "name": "recolour_c800_0",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 23797,
   "name": "b_5CF5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 23798,
   "name": "recolour_c800_1",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 24095,
   "name": "b_5E1F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 24096,
   "name": "recolour_c800_2",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 24393,
   "name": "b_5F49",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 24396,
   "name": "recolour_c800_3",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 24729,
   "name": "r_6099",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 24730,
   "name": "recolour_cc00",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 24733,
   "name": "recolour_cc00_0",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 25030,
   "name": "b_61C6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 25031,
   "name": "recolour_cc00_1",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 25328,
   "name": "b_62F0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 25329,
   "name": "recolour_cc00_2",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 25626,
   "name": "b_641A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 25629,
   "name": "recolour_cc00_3",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 25845,
   "name": "f_64F5",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 25851,
   "name": "f_64FB",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 25854,
   "name": "r_64FE",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 25857,
   "name": "sid_effects_enabled",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25858,
   "name": "sid_busy",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25859,
   "name": "sid_scratch_voice",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25860,
   "name": "sid_scratch_value",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25861,
   "name": "voice_script_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25862,
   "name": "a_6506",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25863,
   "name": "a_6507",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25864,
   "name": "voice_repeat_duration",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25867,
   "name": "voice_pattern_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25868,
   "name": "a_650C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25869,
   "name": "a_650D",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25870,
   "name": "voice_pulse_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25871,
   "name": "a_650F",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25872,
   "name": "a_6510",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25873,
   "name": "voice_pitch_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25874,
   "name": "a_6512",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25875,
   "name": "a_6513",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25876,
   "name": "filter_sweep_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25877,
   "name": "voice_seq_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25883,
   "name": "seq_script_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25884,
   "name": "a_651C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25885,
   "name": "a_651D",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25886,
   "name": "seq_script_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25887,
   "name": "a_651F",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25888,
   "name": "a_6520",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25889,
   "name": "voice_pattern_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25892,
   "name": "voice_pattern_start_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25895,
   "name": "voice_pattern_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25898,
   "name": "voice_pattern_start_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25901,
   "name": "voice_pulse_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25904,
   "name": "voice_pulse_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25907,
   "name": "voice_pitch_table_select",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25910,
   "name": "voice_pitch_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25913,
   "name": "voice_pitch_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25916,
   "name": "voice_arp_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25922,
   "name": "voice_arp_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25928,
   "name": "filter_start_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25929,
   "name": "filter_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25930,
   "name": "filter_step_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25931,
   "name": "filter_step_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25932,
   "name": "filter_acc_init_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25933,
   "name": "filter_acc_init_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25934,
   "name": "filter_acc_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25935,
   "name": "filter_acc_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25936,
   "name": "voice_oneshot_wave_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25939,
   "name": "voice_oneshot_freq_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25942,
   "name": "voice_oneshot_wave_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25943,
   "name": "f_6557",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 25945,
   "name": "voice_oneshot_freq_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25948,
   "name": "voice_script_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25951,
   "name": "voice_script_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25954,
   "name": "voice_freq_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25957,
   "name": "voice_freq_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25960,
   "name": "voice_note",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25963,
   "name": "voice_repeat_count",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25966,
   "name": "sid_pattern_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25967,
   "name": "sid_voice_offset",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25968,
   "name": "voice_attack_decay",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25971,
   "name": "voice_sustain_release",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25974,
   "name": "voice_pitch_enabled",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25977,
   "name": "f_6579",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 25980,
   "name": "voice_arp_enabled",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25983,
   "name": "voice_filter_ctrl",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25984,
   "name": "a_6580",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25985,
   "name": "a_6581",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 25986,
   "name": "voice_oneshot_active",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25989,
   "name": "voice_freq_pending",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25992,
   "name": "voice_repeat_flag",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25995,
   "name": "voice_freq_lookup",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 25998,
   "name": "voice_transpose",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26001,
   "name": "voice_pulse_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26004,
   "name": "voice_pulse_init_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26007,
   "name": "voice_pulse_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26010,
   "name": "voice_pulse_init_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26013,
   "name": "voice_pulse_delta_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26016,
   "name": "voice_pulse_delta_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26019,
   "name": "voice_pitch_delta_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26022,
   "name": "voice_pitch_delta_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26025,
   "name": "voice_script_pos",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26028,
   "name": "voice_arp_timer",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26031,
   "name": "voice_arp_ticks",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26034,
   "name": "voice_arp_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26037,
   "name": "voice_arp_length",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26040,
   "name": "filter_temp",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26041,
   "name": "voice_oneshot_length",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26044,
   "name": "voice_oneshot_step",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26047,
   "name": "sid_fade_out_active",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26048,
   "name": "sid_fade_delay",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26049,
   "name": "sid_fade_rate",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26050,
   "name": "sid_volume",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26051,
   "name": "sid_fade_in_active",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26052,
   "name": "sid_fade_in_target",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26053,
   "name": "voice_restart_mask",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26054,
   "name": "a_65C6",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 26055,
   "name": "a_65C7",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 26056,
   "name": "sid_song_list_index",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26057,
   "name": "voice_cmd_table_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26071,
   "name": "voice_cmd_table_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26085,
   "name": "seq_cmd_table_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26091,
   "name": "seq_cmd_table_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26097,
   "name": "pattern_cmd_table_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26104,
   "name": "pattern_cmd_table_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26111,
   "name": "sid_voice_offsets",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26114,
   "name": "sid_idle_pattern",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 26125,
   "name": "sound_init",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 26151,
   "name": "b_6627",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26163,
   "name": "sid_load_song_voices",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26170,
   "name": "b_663A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26212,
   "name": "b_6664",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26218,
   "name": "r_666A",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 26219,
   "name": "sid_reset_voice_state",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26281,
   "name": "sid_player_init",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 26340,
   "name": "sid_init_voice_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26419,
   "name": "sid_clear_registers_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26497,
   "name": "sid_init_finish",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26503,
   "name": "sid_player_update",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 26509,
   "name": "sid_update_start_voices",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26513,
   "name": "sid_update_voice_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26528,
   "name": "sid_voice_active",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26536,
   "name": "sid_check_fade",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26571,
   "name": "sid_voice_run",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26633,
   "name": "sid_write_frequency",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26651,
   "name": "sid_next_voice",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26658,
   "name": "sid_update_finish",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 26664,
   "name": "sid_fade_in_step",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26699,
   "name": "r_684B",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 26700,
   "name": "tick_voice_script",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26706,
   "name": "b_6852",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26733,
   "name": "advance_voice_script",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26743,
   "name": "b_6877",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26750,
   "name": "b_687E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26787,
   "name": "b_68A3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26817,
   "name": "b_68C1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26840,
   "name": "b_68D8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26862,
   "name": "b_68EE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26897,
   "name": "voice_store_duration",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26908,
   "name": "b_691C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 26911,
   "name": "j_691F",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 26919,
   "name": "dispatch_voice_command",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26935,
   "name": "a_6937",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 26936,
   "name": "a_6938",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 26943,
   "name": "advance_voice_sequence",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 26975,
   "name": "b_695F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27008,
   "name": "b_6980",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27012,
   "name": "seq_run_command",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27028,
   "name": "a_6994",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 27029,
   "name": "a_6995",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 27071,
   "name": "seq_cmd_set_transpose",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27145,
   "name": "music_voice_step",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27151,
   "name": "b_6A0F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27181,
   "name": "b_6A2D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27217,
   "name": "a_6A51",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 27218,
   "name": "a_6A52",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 27282,
   "name": "pattern_cmd_set_control",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27310,
   "name": "b_6AAE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27454,
   "name": "voice_save_pattern_ptr",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27784,
   "name": "script_cmd_set_filter",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27838,
   "name": "music_voice_pulse_sweep",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27843,
   "name": "j_6CC3",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 27861,
   "name": "b_6CD5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27883,
   "name": "b_6CEB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27911,
   "name": "r_6D07",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 27912,
   "name": "music_voice_advance",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 27927,
   "name": "j_6D17",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 27945,
   "name": "b_6D29",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27970,
   "name": "b_6D42",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 27988,
   "name": "b_6D54",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28010,
   "name": "b_6D6A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28033,
   "name": "voice_arp_step",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28044,
   "name": "b_6D8C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28109,
   "name": "r_6DCD",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 28110,
   "name": "update_filter_sweep",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28117,
   "name": "b_6DD5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28128,
   "name": "b_6DE0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28133,
   "name": "r_6DE5",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 28134,
   "name": "j_6DE6",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 28139,
   "name": "j_6DEB",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 28157,
   "name": "b_6DFD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28178,
   "name": "b_6E12",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28222,
   "name": "sid_voice_change_check",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28224,
   "name": "b_6E40",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28256,
   "name": "b_6E60",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 28260,
   "name": "sid_voice_start_change",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28297,
   "name": "a_6E89",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 28298,
   "name": "a_6E8A",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 28311,
   "name": "a_6E97",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 28312,
   "name": "a_6E98",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 28328,
   "name": "r_6EA8",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 28329,
   "name": "sid_any_voice_active",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28336,
   "name": "sid_silence_all",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28376,
   "name": "sid_start_fade_out",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 28422,
   "name": "note_freq_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28516,
   "name": "note_freq_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28610,
   "name": "sid_oneshot_defs",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28660,
   "name": "sid_oneshot_0_wave",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28669,
   "name": "sid_oneshot_data",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28858,
   "name": "sid_seq_start_sets",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28859,
   "name": "f_70BB",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 28860,
   "name": "f_70BC",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 28861,
   "name": "f_70BD",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 28862,
   "name": "f_70BE",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 28863,
   "name": "f_70BF",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 28876,
   "name": "phrase_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28917,
   "name": "phrase_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 28958,
   "name": "pulse_program_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29060,
   "name": "pitch_program_a",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29303,
   "name": "pitch_program_b",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29367,
   "name": "arp_ptr_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29371,
   "name": "arp_pattern_0",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29377,
   "name": "arp_pattern_1",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29381,
   "name": "filter_sweep_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29572,
   "name": "pattern_ptr_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 29670,
   "name": "pattern_streams",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31765,
   "name": "song_voice_list",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31805,
   "name": "voice_script_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31806,
   "name": "voice_script_table_hi0",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31825,
   "name": "voice_scripts",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31933,
   "name": "sprite_y_buckets",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 31934,
   "name": "sprite_y_buckets_1",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32597,
   "name": "status_stage_digit",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32600,
   "name": "status_gauge",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32617,
   "name": "status_label",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32665,
   "name": "status_lives_tens",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32666,
   "name": "status_lives_digit",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32668,
   "name": "status_digit_a",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32669,
   "name": "status_digit_b",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32686,
   "name": "status_clock_minutes",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32688,
   "name": "status_clock_tens",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32689,
   "name": "status_clock_units",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 32697,
   "name": "status_score",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32704,
   "name": "panel_sprite_block",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32768,
   "name": "game_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 32769,
   "name": "f_8001",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32777,
   "name": "f_8009",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32778,
   "name": "f_800A",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32779,
   "name": "f_800B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32780,
   "name": "f_800C",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32781,
   "name": "f_800D",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32782,
   "name": "f_800E",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32783,
   "name": "f_800F",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 32784,
   "name": "new_game_reset",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 32786,
   "name": "b_8012",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 32838,
   "name": "stage_begin",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 32847,
   "name": "round_start",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 32891,
   "name": "b_807B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 32907,
   "name": "b_808B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 32912,
   "name": "b_8090",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 32983,
   "name": "b_80D7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 32998,
   "name": "b_80E6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33017,
   "name": "main_loop",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 33020,
   "name": "b_80FC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33033,
   "name": "f_8109",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33038,
   "name": "f_810E",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33043,
   "name": "f_8113",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33048,
   "name": "f_8118",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33053,
   "name": "f_811D",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33058,
   "name": "f_8122",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33063,
   "name": "f_8127",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 33076,
   "name": "wait_nmi",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 33101,
   "name": "b_814D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33113,
   "name": "j_8159",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 33118,
   "name": "b_815E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33172,
   "name": "enable_frame_nmi",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33179,
   "name": "wait_frame",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 33253,
   "name": "b_81E5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33297,
   "name": "b_8211",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33311,
   "name": "b_821F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33316,
   "name": "b_8224",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33391,
   "name": "b_826F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33397,
   "name": "update_status_line",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33403,
   "name": "b_827B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33408,
   "name": "b_8280",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33429,
   "name": "level_timer_tick",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33503,
   "name": "b_82DF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33506,
   "name": "draw_level_timer",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33536,
   "name": "flash_last_minute_colour",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33547,
   "name": "b_830B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33562,
   "name": "r_831A",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 33563,
   "name": "draw_segment_gauge",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33574,
   "name": "b_8326",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33584,
   "name": "b_8330",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33586,
   "name": "b_8332",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33607,
   "name": "draw_status_lives",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33619,
   "name": "draw_status_stage",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33629,
   "name": "draw_status_label",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 33632,
   "name": "b_8360",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33645,
   "name": "b_836D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33647,
   "name": "b_836F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33662,
   "name": "irq_panel",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 33675,
   "name": "b_838B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33773,
   "name": "new_game_defaults",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 33844,
   "name": "update_temp_objects",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 33848,
   "name": "b_8438",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33852,
   "name": "b_843C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33891,
   "name": "b_8463",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33896,
   "name": "b_8468",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33899,
   "name": "b_846B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33962,
   "name": "b_84AA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 33982,
   "name": "b_84BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34022,
   "name": "b_84E6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34025,
   "name": "b_84E9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34083,
   "name": "b_8523",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34093,
   "name": "b_852D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34134,
   "name": "b_8556",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34162,
   "name": "update_player",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34190,
   "name": "b_858E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34200,
   "name": "b_8598",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34220,
   "name": "b_85AC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34251,
   "name": "b_85CB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34262,
   "name": "b_85D6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34268,
   "name": "player_mode_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34279,
   "name": "b_85E7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34282,
   "name": "b_85EA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34298,
   "name": "b_85FA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34307,
   "name": "player_move",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34319,
   "name": "pm_air_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34355,
   "name": "b_8633",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34358,
   "name": "b_8636",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34366,
   "name": "b_863E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34369,
   "name": "pm_down_diag",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34377,
   "name": "pm_up_diag",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34392,
   "name": "pm_up_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34406,
   "name": "pm_airborne",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34418,
   "name": "pm_idle",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34437,
   "name": "pm_hit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34440,
   "name": "b_8688",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34443,
   "name": "b_868B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34446,
   "name": "b_868E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34449,
   "name": "b_8691",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34452,
   "name": "b_8694",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34455,
   "name": "b_8697",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34458,
   "name": "player_jump_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34468,
   "name": "player_jump_start",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34487,
   "name": "jump_start_state",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34516,
   "name": "player_jump_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34529,
   "name": "player_down_left",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34546,
   "name": "player_down_right",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34563,
   "name": "player_walk_right",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34573,
   "name": "walk_right_dir",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34579,
   "name": "walk_right_move",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34599,
   "name": "player_walk_left",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34609,
   "name": "walk_left_dir",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34615,
   "name": "walk_left_move",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34635,
   "name": "player_slope_step",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34645,
   "name": "slope_step_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34648,
   "name": "slope_step_one",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34654,
   "name": "slope_step_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34657,
   "name": "player_hit_step",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34681,
   "name": "r_8779",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 34682,
   "name": "player_jump_motion",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34704,
   "name": "jump_rise_sub",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34720,
   "name": "jump_rise_count",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34734,
   "name": "jump_rise_end",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34744,
   "name": "jump_fall",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34765,
   "name": "jump_fall_count",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34772,
   "name": "r_87D4",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 34773,
   "name": "player_down_enter_mode1",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34862,
   "name": "player_stop_facing",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34864,
   "name": "player_stop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34877,
   "name": "b_883D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 34880,
   "name": "player_jump_up",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 34890,
   "name": "stage_setup_tables",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34901,
   "name": "stage_copy_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34957,
   "name": "scroll_phase_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34974,
   "name": "scroll_phase_run",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 34991,
   "name": "jump_via_e1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 34994,
   "name": "build_vic_shadows",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35002,
   "name": "b_88BA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35004,
   "name": "b_88BC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35021,
   "name": "r_88CD",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 35022,
   "name": "object_arc_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35027,
   "name": "arc_vertical",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35040,
   "name": "b_88E0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35053,
   "name": "b_88ED",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35067,
   "name": "arc_peak",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35078,
   "name": "arc_fall",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35093,
   "name": "b_8915",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35100,
   "name": "r_891C",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 35101,
   "name": "object_path_step",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35137,
   "name": "r_8941",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 35138,
   "name": "path_advance",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35177,
   "name": "path_add_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35187,
   "name": "b_8973",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35205,
   "name": "path_add_x",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35215,
   "name": "b_898F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35233,
   "name": "path_finish",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35241,
   "name": "player_collide",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35264,
   "name": "collide_airborne",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35288,
   "name": "r_89D8",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 35289,
   "name": "collide_hit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35292,
   "name": "b_89DC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35295,
   "name": "b_89DF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35298,
   "name": "b_89E2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35301,
   "name": "b_89E5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35304,
   "name": "b_89E8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35307,
   "name": "b_89EB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35310,
   "name": "b_89EE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35313,
   "name": "b_89F1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35316,
   "name": "collide_ground_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35343,
   "name": "ground_x_blocked",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35346,
   "name": "ground_floor_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35386,
   "name": "ground_slope_or_fall",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35426,
   "name": "r_8A62",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 35427,
   "name": "b_8A63",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35430,
   "name": "b_8A66",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35433,
   "name": "collide_ground_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35460,
   "name": "ground_set_slope",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35470,
   "name": "air_down_left_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35511,
   "name": "air_down_left_blocked",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35517,
   "name": "air_down_right_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35558,
   "name": "air_down_right_blocked",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35561,
   "name": "air_vertical",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35567,
   "name": "air_floor_check",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35606,
   "name": "air_block_flags",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35656,
   "name": "air_commit_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35659,
   "name": "air_slope",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35662,
   "name": "air_on_object",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35704,
   "name": "air_hit_hazard",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35733,
   "name": "b_8B95",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35736,
   "name": "air_land_solid",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35770,
   "name": "air_land",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35775,
   "name": "land_and_snap",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35778,
   "name": "snap_player_to_block",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35805,
   "name": "b_8BDD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35818,
   "name": "b_8BEA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 35836,
   "name": "player_land",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 35847,
   "name": "s_8C07",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 35851,
   "name": "air_slope_check",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 35882,
   "name": "air_slope_height",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35901,
   "name": "air_slope_land",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35918,
   "name": "air_slope_set_kind",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35933,
   "name": "air_slope_commit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35936,
   "name": "ground_slope_left",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 35944,
   "name": "j_8C68",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 35972,
   "name": "ground_slope_right_two",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 35985,
   "name": "ground_slope_left_one",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36008,
   "name": "ground_slope_snap",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36011,
   "name": "ground_slope_right",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36060,
   "name": "ground_slope_commit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36063,
   "name": "air_up_right_x",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36086,
   "name": "air_up_left_x",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36109,
   "name": "air_up_x_blocked",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36112,
   "name": "air_up_check",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36128,
   "name": "air_mode1_check",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36188,
   "name": "air_start_fall",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36198,
   "name": "r_8D66",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 36199,
   "name": "player_ride_object",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36218,
   "name": "ride_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36227,
   "name": "ride_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36256,
   "name": "player_leave_object",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36258,
   "name": "j_8DA2",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 36279,
   "name": "ride_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36294,
   "name": "ride_left_probe",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36315,
   "name": "ride_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36330,
   "name": "ride_right_probe",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36351,
   "name": "ride_finish",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36370,
   "name": "ride_hit",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36399,
   "name": "hit_save_pos",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36414,
   "name": "hit_copy_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36426,
   "name": "hit_save_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36440,
   "name": "hit_copy_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36452,
   "name": "r_8E64",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 36453,
   "name": "place_player_on_object",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36487,
   "name": "r_8E87",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 36488,
   "name": "player_mode2_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36506,
   "name": "s_8E9A",
   "type": "Subroutine",
   "kind": "auto"
  },
  {
   "address": 36507,
   "name": "mode2_move",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36527,
   "name": "mode2_joy_dir",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36566,
   "name": "mode2_step_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36575,
   "name": "mode2_step_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36584,
   "name": "mode2_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36589,
   "name": "mode2_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36594,
   "name": "mode2_up_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36602,
   "name": "mode2_down_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36610,
   "name": "mode2_down_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36618,
   "name": "mode2_up_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36626,
   "name": "mode2_jump_motion",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36649,
   "name": "b_8F29",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36663,
   "name": "b_8F37",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36678,
   "name": "b_8F46",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36688,
   "name": "mode2_jump_fall",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36709,
   "name": "b_8F65",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36717,
   "name": "mode2_jump_end",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36723,
   "name": "mode2_collide",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36750,
   "name": "mode2_air_commit_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36753,
   "name": "mode2_air_right_probe",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36766,
   "name": "mode2_air_turn",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36775,
   "name": "mode2_ground",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36789,
   "name": "mode2_cancel_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36792,
   "name": "mode2_vertical",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36804,
   "name": "r_8FC4",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 36805,
   "name": "mode2_up_probe",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36824,
   "name": "mode2_commit_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36827,
   "name": "mode2_leave",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36851,
   "name": "mode2_down_probe",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36866,
   "name": "mode2_ground_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36879,
   "name": "mode2_commit_x",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36885,
   "name": "mode2_ground_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36901,
   "name": "player_mode1_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36909,
   "name": "mode1_fire_flags",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 36924,
   "name": "b_903C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36930,
   "name": "b_9042",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36943,
   "name": "b_904F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36946,
   "name": "mode1_to_collide",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 36949,
   "name": "mode1_move_vertical",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 36972,
   "name": "b_906C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 36999,
   "name": "mode1_no_move",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37003,
   "name": "r_908B",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37004,
   "name": "mode1_vertical_only",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37014,
   "name": "mode1_up_set",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37016,
   "name": "mode1_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37021,
   "name": "mode1_down_set",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37023,
   "name": "mode1_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37028,
   "name": "mode1_step_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37056,
   "name": "f_90C0",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37075,
   "name": "mode1_step_blocked",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37092,
   "name": "mode1_step_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37139,
   "name": "spr_min_free_line",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37150,
   "name": "b_911E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37158,
   "name": "b_9126",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37166,
   "name": "b_912E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37174,
   "name": "b_9136",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37182,
   "name": "b_913E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37190,
   "name": "b_9146",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37199,
   "name": "r_914F",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37200,
   "name": "path_start_from_record",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37242,
   "name": "mode1_move_horizontal",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37264,
   "name": "mode1_right",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37271,
   "name": "mode1_left",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37278,
   "name": "mode1_collide",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 37291,
   "name": "mode1_horizontal_collide",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37305,
   "name": "r_91B9",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37306,
   "name": "mode1_vertical_collide",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37311,
   "name": "f_91BF",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37327,
   "name": "mode1_up_end",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37349,
   "name": "b_91E5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37352,
   "name": "b_91E8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37355,
   "name": "mode1_down_end",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37365,
   "name": "b_91F5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37368,
   "name": "mode1_down_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37378,
   "name": "f_9202",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37383,
   "name": "mode1_step_left_8",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37404,
   "name": "mode1_step_right_8",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37423,
   "name": "mode1_start_jump",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37445,
   "name": "f_9245",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37454,
   "name": "mode1_set_dir_0B",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37458,
   "name": "mode1_set_dir_07",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37460,
   "name": "mode1_set_dir_tail",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 37475,
   "name": "f_9263",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37490,
   "name": "b_9272",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37494,
   "name": "player_step_check_first_dir",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 37506,
   "name": "f_9282",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 37529,
   "name": "b_9299",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37531,
   "name": "b_929B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37548,
   "name": "r_92AC",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37549,
   "name": "player_step_check_second_dir",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 37582,
   "name": "b_92CE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37599,
   "name": "track_stage_section",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37615,
   "name": "b_92EF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37629,
   "name": "b_92FD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37706,
   "name": "b_934A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37730,
   "name": "r_9362",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37731,
   "name": "b_9363",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37742,
   "name": "load_section_record",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37816,
   "name": "b_93B8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37825,
   "name": "b_93C1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37837,
   "name": "point_in_section",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37887,
   "name": "r_93FF",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 37888,
   "name": "block_property_at",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 37952,
   "name": "b_9440",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 37955,
   "name": "draw_screen_from_tile_map",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 38003,
   "name": "j_9473",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 38021,
   "name": "b_9485",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38167,
   "name": "b_9517",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38170,
   "name": "copy_sprites_to_tables",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 38183,
   "name": "b_9527",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38190,
   "name": "b_952E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38195,
   "name": "b_9533",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38198,
   "name": "b_9536",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38225,
   "name": "b_9551",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38253,
   "name": "b_956D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38258,
   "name": "b_9572",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38295,
   "name": "b_9597",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38299,
   "name": "b_959B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 38308,
   "name": "sprite_reuse_irq",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 38320,
   "name": "reuse_next_entry",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38328,
   "name": "reuse_hw_sprite_0",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38421,
   "name": "reuse_hw_sprite_1",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38514,
   "name": "reuse_hw_sprite_2",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38607,
   "name": "reuse_hw_sprite_3",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38700,
   "name": "reuse_hw_sprite_4",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38793,
   "name": "reuse_hw_sprite_5",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38886,
   "name": "reuse_hw_sprite_6",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 38979,
   "name": "reuse_hw_sprite_7",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 39067,
   "name": "reuse_wait_free_sprite",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 39082,
   "name": "reuse_end_of_list",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 39096,
   "name": "reuse_set_next_irq",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 39109,
   "name": "lowest_free_line",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 39155,
   "name": "player_animate",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 39185,
   "name": "b_9911",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39196,
   "name": "b_991C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39199,
   "name": "b_991F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39202,
   "name": "b_9922",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39215,
   "name": "b_992F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39231,
   "name": "b_993F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39237,
   "name": "b_9945",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39267,
   "name": "r_9963",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 39268,
   "name": "b_9964",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39303,
   "name": "b_9987",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39314,
   "name": "b_9992",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39341,
   "name": "b_99AD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39352,
   "name": "b_99B8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39368,
   "name": "b_99C8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39378,
   "name": "b_99D2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39386,
   "name": "j_99DA",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 39405,
   "name": "b_99ED",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39466,
   "name": "j_9A2A",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 39472,
   "name": "b_9A30",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39484,
   "name": "b_9A3C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39488,
   "name": "j_9A40",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 39516,
   "name": "r_9A5C",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 39517,
   "name": "b_9A5D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39551,
   "name": "b_9A7F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39563,
   "name": "b_9A8B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39571,
   "name": "b_9A93",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39574,
   "name": "b_9A96",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39653,
   "name": "b_9AE5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39660,
   "name": "b_9AEC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39667,
   "name": "b_9AF3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39703,
   "name": "b_9B17",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39720,
   "name": "b_9B28",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39722,
   "name": "b_9B2A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39794,
   "name": "b_9B72",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39844,
   "name": "b_9BA4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39851,
   "name": "j_9BAB",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 39861,
   "name": "b_9BB5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39891,
   "name": "r_9BD3",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 39892,
   "name": "b_9BD4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39915,
   "name": "b_9BEB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39923,
   "name": "b_9BF3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 39926,
   "name": "probe_player_tiles_one_column",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 39947,
   "name": "probe_one_column_x",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 39966,
   "name": "probe_player_tiles",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 39987,
   "name": "b_9C33",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40016,
   "name": "j_9C50",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 40052,
   "name": "b_9C74",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40158,
   "name": "b_9CDE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40215,
   "name": "probe_player_tiles_one_row",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 40240,
   "name": "probe_outside_map",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 40252,
   "name": "player_probe_tiles_and_platforms",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 40289,
   "name": "probe_columns_from_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40381,
   "name": "probe_far_column",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40471,
   "name": "j_9E17",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 40474,
   "name": "platform_scan_next",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40536,
   "name": "probe_return",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40537,
   "name": "probe_no_platform",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40542,
   "name": "probe_reuse_last_platform",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 40553,
   "name": "player_probe_previous_tiles",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 40591,
   "name": "b_9E8F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40709,
   "name": "set_idle_aim",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 40732,
   "name": "b_9F1C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40734,
   "name": "b_9F1E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40738,
   "name": "b_9F22",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40754,
   "name": "b_9F32",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40764,
   "name": "b_9F3C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40766,
   "name": "b_9F3E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40770,
   "name": "place_player_sprites",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 40831,
   "name": "b_9F7F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40863,
   "name": "b_9F9F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40891,
   "name": "b_9FBB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 40896,
   "name": "player_sprite_coords",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 40944,
   "name": "b_9FF0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41083,
   "name": "b_A07B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41105,
   "name": "clamp_sprite_y",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 41113,
   "name": "b_A099",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41119,
   "name": "b_A09F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41123,
   "name": "r_A0A3",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 41124,
   "name": "place_third_sprite",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 41181,
   "name": "b_A0DD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41252,
   "name": "slot_blink_timer",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 41264,
   "name": "b_A130",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41271,
   "name": "b_A137",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41278,
   "name": "b_A13E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41287,
   "name": "b_A147",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41294,
   "name": "b_A14E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41301,
   "name": "b_A155",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41330,
   "name": "b_A172",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41332,
   "name": "b_A174",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41336,
   "name": "update_objects",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 41356,
   "name": "b_A18C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41377,
   "name": "j_A1A1",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 41406,
   "name": "b_A1BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41412,
   "name": "b_A1C4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41419,
   "name": "b_A1CB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41434,
   "name": "b_A1DA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41466,
   "name": "b_A1FA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41493,
   "name": "b_A215",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41513,
   "name": "j_A229",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 41554,
   "name": "b_A252",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41557,
   "name": "b_A255",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41603,
   "name": "b_A283",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41652,
   "name": "b_A2B4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41675,
   "name": "b_A2CB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41712,
   "name": "b_A2F0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41715,
   "name": "b_A2F3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41735,
   "name": "j_A307",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 41772,
   "name": "b_A32C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41790,
   "name": "b_A33E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41801,
   "name": "b_A349",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41815,
   "name": "b_A357",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41837,
   "name": "b_A36D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41840,
   "name": "b_A370",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41890,
   "name": "b_A3A2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41908,
   "name": "b_A3B4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 41919,
   "name": "object_sprites_and_hits",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 42042,
   "name": "j_A43A",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42061,
   "name": "b_A44D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42065,
   "name": "b_A451",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42070,
   "name": "b_A456",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42073,
   "name": "b_A459",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42168,
   "name": "b_A4B8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42205,
   "name": "b_A4DD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42212,
   "name": "b_A4E4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42250,
   "name": "b_A50A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42252,
   "name": "b_A50C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42268,
   "name": "b_A51C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42278,
   "name": "b_A526",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42288,
   "name": "b_A530",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42295,
   "name": "j_A537",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42300,
   "name": "b_A53C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42301,
   "name": "b_A53D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42303,
   "name": "b_A53F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42310,
   "name": "b_A546",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42314,
   "name": "j_A54A",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42333,
   "name": "b_A55D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42343,
   "name": "b_A567",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42346,
   "name": "b_A56A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42353,
   "name": "b_A571",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42415,
   "name": "b_A5AF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42418,
   "name": "j_A5B2",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42518,
   "name": "b_A616",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42528,
   "name": "b_A620",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42531,
   "name": "b_A623",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42544,
   "name": "b_A630",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42574,
   "name": "b_A64E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42580,
   "name": "j_A654",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42632,
   "name": "b_A688",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42635,
   "name": "j_A68B",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42649,
   "name": "j_A699",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42657,
   "name": "b_A6A1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42736,
   "name": "b_A6F0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42759,
   "name": "b_A707",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42786,
   "name": "j_A722",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42792,
   "name": "b_A728",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42795,
   "name": "b_A72B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42801,
   "name": "j_A731",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 42817,
   "name": "b_A741",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42830,
   "name": "b_A74E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42874,
   "name": "b_A77A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42877,
   "name": "b_A77D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 42913,
   "name": "j_A7A1",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 43112,
   "name": "obj_flags_handler_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 43121,
   "name": "obj_flags_handler_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 43130,
   "name": "obj_kind_reaction_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 43140,
   "name": "obj_kind_reaction_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 43150,
   "name": "object_run_type_handler",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43174,
   "name": "object_type_reset_group",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43224,
   "name": "object_reset_to_next_frame",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43232,
   "name": "object_reset_motion",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43258,
   "name": "object_type_launch_arc",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43266,
   "name": "object_start_rise_arc",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43293,
   "name": "object_reset_tail",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43325,
   "name": "object_type_noop",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43326,
   "name": "object_type_activate_pair",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43373,
   "name": "object_type_poke_stage_ram",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43393,
   "name": "object_type_start_spawner",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43408,
   "name": "object_phase_dispatch",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43429,
   "name": "jump_apply_dir_and_speed",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43432,
   "name": "jump_phase1_nudge_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43435,
   "name": "jump_phase2_flag_countdown",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43438,
   "name": "jump_phase3_start_arc",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43441,
   "name": "phase4_wait_flag7",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43458,
   "name": "phase5_substate_dispatch",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43471,
   "name": "phase5_substate2_countdown",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43517,
   "name": "return_a9fd",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43518,
   "name": "phase5_substate3_countdown",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43549,
   "name": "return_aa1d",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43550,
   "name": "phase5_substate0_wait_flag7",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43568,
   "name": "phase5_substate1_block_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43577,
   "name": "phase5_substate1_probe_block",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43617,
   "name": "phase3_start_arc",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43627,
   "name": "start_arc_next_substate",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43640,
   "name": "return_aa78",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43641,
   "name": "phase3_land_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43694,
   "name": "phase2_flag_countdown",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43731,
   "name": "return_aad3",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43732,
   "name": "phase2_no_timer_bits",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43743,
   "name": "phase2_set_flags_a6",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43748,
   "name": "return_aae4",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43749,
   "name": "phase2_wiggle_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43785,
   "name": "phase2_step_dir_0e",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43796,
   "name": "phase2_step_dir_0d",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43807,
   "name": "phase2_wiggle_finish",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43832,
   "name": "apply_dir_and_speed",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43849,
   "name": "phase1_nudge_y",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43878,
   "name": "phase1_pull_back_y",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43891,
   "name": "return_ab73",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 43892,
   "name": "slope_aim_dir",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 43905,
   "name": "b_AB81",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 43908,
   "name": "b_AB84",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 43915,
   "name": "b_AB8B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 43918,
   "name": "object_trigger_player_in_range",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 43975,
   "name": "set_object_hitbox",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 44038,
   "name": "object_timer_trigger",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 44051,
   "name": "compute_trial_box_edges",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 44078,
   "name": "b_AC2E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44111,
   "name": "update_char_block_slots",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 44141,
   "name": "slots_scan_start",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44155,
   "name": "b_AC7B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44160,
   "name": "slots_next",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44164,
   "name": "slot_active",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44222,
   "name": "slot_deactivate",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44230,
   "name": "slot_on_screen",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44310,
   "name": "slot_save_draw_1_cell",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44357,
   "name": "slot_save_draw_2_cells",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44416,
   "name": "slot_after_draw",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44429,
   "name": "slot_step_sound_check",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44443,
   "name": "slot_advance_frame",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44473,
   "name": "slot_frame_wrap_to_zero",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44475,
   "name": "slot_store_frame",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44508,
   "name": "slot_path_restart",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44510,
   "name": "slot_path_read_step",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44512,
   "name": "slot_apply_path_step",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44590,
   "name": "slot_save_draw_4_cells",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 44688,
   "name": "restore_saved_cells",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 44693,
   "name": "b_AE95",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44789,
   "name": "r_AEF5",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 44790,
   "name": "restore_one_cell_record",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 44808,
   "name": "b_AF08",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44812,
   "name": "restore_two_cell_record",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 44846,
   "name": "b_AF2E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44849,
   "name": "b_AF31",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44852,
   "name": "player_fire",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 44873,
   "name": "r_AF49",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 44874,
   "name": "b_AF4A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44899,
   "name": "b_AF63",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44907,
   "name": "b_AF6B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44921,
   "name": "b_AF79",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44943,
   "name": "b_AF8F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44949,
   "name": "b_AF95",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44953,
   "name": "b_AF99",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44963,
   "name": "b_AFA3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44967,
   "name": "b_AFA7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44985,
   "name": "b_AFB9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44993,
   "name": "b_AFC1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44997,
   "name": "b_AFC5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 44999,
   "name": "b_AFC7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45015,
   "name": "j_AFD7",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 45021,
   "name": "b_AFDD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45044,
   "name": "b_AFF4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45053,
   "name": "b_AFFD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45055,
   "name": "b_AFFF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45063,
   "name": "b_B007",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45191,
   "name": "r_B087",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45192,
   "name": "j_B088",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 45199,
   "name": "b_B08F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45419,
   "name": "j_B16B",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 45437,
   "name": "b_B17D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45467,
   "name": "b_B19B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45471,
   "name": "b_B19F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45482,
   "name": "b_B1AA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45486,
   "name": "b_B1AE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45490,
   "name": "b_B1B2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45494,
   "name": "b_B1B6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45498,
   "name": "b_B1BA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45509,
   "name": "b_B1C5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45513,
   "name": "b_B1C9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45517,
   "name": "b_B1CD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45519,
   "name": "b_B1CF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45535,
   "name": "b_B1DF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45537,
   "name": "j_B1E1",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 45548,
   "name": "b_B1EC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45559,
   "name": "object_run_script_handler",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 45575,
   "name": "object_script_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 45586,
   "name": "j_B212",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 45614,
   "name": "b_B22E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45615,
   "name": "b_B22F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45628,
   "name": "b_B23C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45657,
   "name": "step_object_by_script",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45672,
   "name": "b_B268",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45677,
   "name": "apply_object_direction",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45716,
   "name": "b_B294",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45719,
   "name": "b_B297",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45722,
   "name": "move_object_left",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45734,
   "name": "r_B2A6",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45735,
   "name": "move_object_right",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45748,
   "name": "move_object_up_right",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45760,
   "name": "b_B2C0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45772,
   "name": "r_B2CC",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45773,
   "name": "move_object_down_right",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45785,
   "name": "b_B2D9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45797,
   "name": "r_B2E5",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45798,
   "name": "move_object_down_left",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45810,
   "name": "b_B2F2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45827,
   "name": "r_B303",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45828,
   "name": "move_object_up_left",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45840,
   "name": "b_B310",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 45857,
   "name": "r_B321",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45858,
   "name": "move_object_up",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45870,
   "name": "r_B32E",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45871,
   "name": "move_object_down",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 45883,
   "name": "r_B33B",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 45884,
   "name": "script_cmd_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 45919,
   "name": "script_cmd_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 45954,
   "name": "script_cmd2_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 45985,
   "name": "script_cmd2_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 46016,
   "name": "object_hop_at_player",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 46203,
   "name": "object_trigger_player_on_side",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 46259,
   "name": "object_walk_land_stop",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 46273,
   "name": "object_walk_land_bounce",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 46276,
   "name": "object_land_bounce",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 46458,
   "name": "advance_object_animation",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 46503,
   "name": "reselect_object_animation_frame",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 46514,
   "name": "b_B5B2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 46517,
   "name": "b_B5B5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 47311,
   "name": "player_effect_tick",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 47342,
   "name": "r_B8EE",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 47343,
   "name": "b_B8EF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 47352,
   "name": "weapon_record_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 47357,
   "name": "weapon_record_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 48353,
   "name": "irq_panel_on",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48358,
   "name": "b_BCE6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 48477,
   "name": "store_score_digits",
   "type": "code",
   "kind": "user"
  },
  {
   "address": 48480,
   "name": "b_BD60",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 48502,
   "name": "stage_spawn_arc_object",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 48608,
   "name": "stage_arc_object_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 48689,
   "name": "stage_place_part_objects",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 48930,
   "name": "stage3_bf22",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 48931,
   "name": "stage3_bf23",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 48932,
   "name": "stage3_bf24",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 48933,
   "name": "stage3_bf25",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 49150,
   "name": "stage2_tail_bffe",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 49151,
   "name": "stage2_tail_bfff",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 49152,
   "name": "charset_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 50176,
   "name": "charset_chars_80",
   "type": "Field"
  },
  {
   "address": 50303,
   "name": "charset_char_8F_last",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 50304,
   "name": "charset_cleared",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 51072,
   "name": "charset_chars_F0",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 51200,
   "name": "screen_buffer_c800",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 52040,
   "name": "c800_after_playfield",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 52216,
   "name": "sprite_pointers_c800",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 52224,
   "name": "screen_buffer_cc00",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 53064,
   "name": "cc00_after_playfield",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 53184,
   "name": "cc00_blank_row",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 53248,
   "name": "sprite_shapes_40_4f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 54272,
   "name": "sprite_shapes_50_5f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 55296,
   "name": "sprite_shapes_60_6f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 56320,
   "name": "sprite_shapes_70_7f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 57344,
   "name": "sprite_shapes_80_8f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 58368,
   "name": "sprite_shapes_90_9f",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 59392,
   "name": "sprite_shapes_a0_af",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 60416,
   "name": "sprite_shapes_b0_bf",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 61440,
   "name": "sprite_shapes_c0_cf",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 62464,
   "name": "sprite_shapes_d0_df",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 63488,
   "name": "sprite_shapes_e0_ef",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64512,
   "name": "sprite_shapes_f0_ff",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64768,
   "name": "stage_page_fd00",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65024,
   "name": "between_stage_page",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65280,
   "name": "sprite_shape_block_1",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65344,
   "name": "sprite_shape_block_2",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65408,
   "name": "sprite_shape_block_3",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65470,
   "name": "saved_page_base",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65471,
   "name": "saved_page_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65474,
   "name": "label_chars",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65479,
   "name": "label_flag",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65525,
   "name": "last_label_chars",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65530,
   "name": "hw_vectors",
   "type": "Field",
   "kind": "user"
  }
 ],
 "comments": [
  {
   "address": 0,
   "type": "line",
   "text": "Address 0 is the 6510's data direction register for the port at $01 (cpu_port). No game code reads or writes it; the label only marks the first address of the memory image."
  },
  {
   "address": 1,
   "type": "line",
   "text": "The 6510's on-chip port, which sets the memory map. The game writes $35 (RAM everywhere, I/O visible: the normal state), $37 while it reads the cartridge ROM at $8000 (the stream loader, stage_start, copy_sprite_shapes, game_init and the cartridge copies among them) and $00 (all RAM) while it stores into RAM under I/O: the stream loader at $5138 and game_init's start-up copy to $D000-$D07F through s_526C ($526E). nmi_frame saves it and restores it on exit."
  },
  {
   "address": 2,
   "type": "line",
   "text": "Low byte of the cartridge source pointer ($03 is the high byte; the pointer lies in $8000-$9FFF) of the background data stream that stream_cartridge_data_to_ram copies, 63 bytes a call, into RAM. While load_stage_bank_records builds the stream tables it holds instead the destination block number of the stream being recorded ($0532, $053B), and stage_start first sets the pair to $D000 ($0B2E)."
  },
  {
   "address": 3,
   "type": "line",
   "text": "High byte of stream_src, the cartridge source pointer of the background data stream ($80-$9F while in use)."
  },
  {
   "address": 4,
   "type": "line",
   "text": "Low byte of the RAM destination pointer ($05 is the high byte) that the stream loader stores into. start_stream_destination sets it to the stream's block number times 64 plus $C000; every call then adds 64."
  },
  {
   "address": 5,
   "type": "line",
   "text": "High byte of stream_dst, the RAM destination pointer of the background data stream ($C0 and up)."
  },
  {
   "address": 6,
   "type": "line",
   "text": "Fine horizontal scroll, 0 to 7: set_view_window subtracts it from 7 and adds the result to scroll_x times 8. $88C1 combines it with $10 into $07AF."
  },
  {
   "address": 7,
   "type": "line",
   "text": "Fine vertical scroll, 0 to 7: set_view_window subtracts it from 7 and adds the result to scroll_y times 8. $88C8 combines it with $10 into $07AE."
  },
  {
   "address": 8,
   "type": "line",
   "text": "The joystick bits, written once a frame by update_player: the low four bits of CIA 1 port A (or port B when A reads $7F). Bit 0 is up, bit 1 down, bit 2 left, and bit 3 right, with 0 meaning pressed; $0F means nothing is pressed. The player code that update_player runs (from $8603, and also $8EAF, $905F, $917A, and player_fire's aim code at $AF4F, $AF79 and $B16B) compares it with $07 (right), $0B (left), $0D (down), $0E (up), and combinations such as $05, $06, $09, and $0A. The 'ldx $08' the listing shows at $06E3 is a leftover operand byte of the stage loader inside the shot_x_lo table, not a read."
  },
  {
   "address": 9,
   "type": "line",
   "text": "Which handler update_player runs through player_mode_step: 0, 1, or 2. The setup at $500A sets 2 when bit 7 of the stage record's byte is set; init_round_state ($4EF3) and level_timer_tick ($82C3) set 0, and the other writes are in the player code. Mode 0 is walking and jumping: player_mode_step ($85DC) sets fire_flags and runs $8603 and $89A9, which read joy_bits; $08FA is zero on the ground and non-zero in the air. Mode 1 runs $9025 and then $919E: with $0B at 0, $9055 reads joy_bits for up, down, left, and right and sets the action number $0905 to 6; with $0B non-zero, $917A reads only left and right and sets $0905 to 5. It is entered at $8A2F, $8B09, $881D, and $8D4B. Mode 2 runs $8E88, which sets $0905 to 7, turns the eight joystick directions into the direction code $0D, and moves the player through $42E1, $42F8, $430F, and $4326; it is entered at $8B37 when the tile check finds bit 6 (value $40). Mode 0 is restored at seven places, the last when the player is hit ($A632)."
  },
  {
   "address": 10,
   "type": "line",
   "text": "Pixels the player moves in one step: always 2. Every writer stores 2: new_game_defaults, the walk routines, the mode 1 entries (ground_floor_check, air_mode1_check, player_down_enter_mode1), mode1_start_jump and mode1_set_dir_tail. $42F8 and $4326 add it to player_try_x and player_try_y, $42E1 and $430F subtract it."
  },
  {
   "address": 11,
   "type": "line",
   "text": "In mode 1 (player_mode = 1): 0 means the player moves vertically (mode1_move_vertical runs), non-zero means horizontally (mode1_move_horizontal). Mode 1 is entered with it at 1 from ground_floor_check and air_floor_check, and at 0 from air_mode1_check and player_down_enter_mode1. Outside mode 1 it is also written: 1 by player_down_left/right and $9B3B, 5 by the slope steps at $8CA6 and $8CD7, 0 at $9B0E. player_pose reads it to choose the frame; set_idle_aim and the aim code at $B16B read it too."
  },
  {
   "address": 12,
   "type": "line",
   "text": "Kind of slope the player stands on: 0 none, 1 or 2 on a slope. air_slope_land sets 1 when bit 2 of $0291 is set and 2 otherwise; ground_set_slope sets it to bits 2 and 3 of $0291 shifted down (1 for bit 2, 2 for bit 3). player_land, jump_start_state, mode1_start_jump, mode1_set_dir_tail, init_round_state and the mode 0 returns at $92A6 and $92D7 clear it. While it is non-zero the ground steps go through the slope routines (ground_slope_left/right, player_slope_step), which move the player vertically as well."
  },
  {
   "address": 13,
   "type": "line",
   "text": "Direction code of the player's current step, in the joystick pattern: $07 right, $0B left, $0E up, $0D down, $05 down-right, $06 up-right, $09 down-left, $0A up-left. $FF means no step (set by player_stop, pm_idle, air_slope_land, init_round_state and the no-move paths of modes 1 and 2) and $FE the landing state set by player_land. Bit 3 clear is a step to the right, bit 2 clear to the left; the collision routines pick the block probe from these bits."
  },
  {
   "address": 14,
   "type": "line",
   "text": "Where the screen redraw for a one-tile scroll has got to: $FF is idle, 0 lets scroll_draw_edge draw, and 1 is set by $4B8A when the tile step happens. $888D counts it down and acts on 1 and 0."
  },
  {
   "address": 15,
   "type": "line",
   "text": "Direction of the pending one-tile scroll for scroll_draw_edge: 0 up, 1 up-right, 2 right, 3 down-right, 4 down, 5 down-left, 6 left, 7 up-left ($FF none). Set by the routines at $433D-$438B ($FF with scroll_phase when idle); $888D uses it to pick a routine from the table at $0324/$032C."
  },
  {
   "address": 16,
   "type": "line",
   "text": "Which character screen is shown: 0 is the buffer at $C800, 1 the buffer at $CC00. tile_scroll_done flips it each time the view has moved one whole tile; build_vic_shadows turns it into the $D018 value ($21 or $31) and recolour_screen takes its colours from the buffer it names. Set to 1 by new_game_defaults."
  },
  {
   "address": 17,
   "type": "line",
   "text": "The previous value of $10: tile_scroll_done copies $10 here before flipping it. The scroll copy routines (the handlers of scroll_phase_step, from $5323) test it to know which buffer they copy from. Cleared by new_game_defaults."
  },
  {
   "address": 18,
   "type": "line",
   "text": "How many logical sprite entries the tables at $0808-$0880 hold: place_player_sprites sets it, object_sprites_and_hits adds to it (never past $16)."
  },
  {
   "address": 19,
   "type": "line",
   "text": "The highest position used so far in sprite_y_buckets ($7CBD)."
  },
  {
   "address": 20,
   "type": "line",
   "text": "Index of the first stage object update_objects and object_sprites_and_hits look at. update_objects moves it past objects retired at the front. Loaded at $93A0 from byte $17 of the record at the pointer $26 (0 in the play snapshot)."
  },
  {
   "address": 21,
   "type": "line",
   "text": "One past the last stage object: the loops over the stage's objects stop here. Loaded at $93A5 from byte $18 of the record at the pointer $26 ($1A in the play snapshot)."
  },
  {
   "address": 22,
   "type": "line",
   "text": "Index of the first of the nine short-lived objects of the pool that update_temp_objects runs. Loaded at $4F4B from byte $18 of a record found through the word table at $0D22 and the byte at $0C06 (it is $4C in the play snapshot)."
  },
  {
   "address": 23,
   "type": "line",
   "text": "temp_first + 9, one past the pool, set at $5062."
  },
  {
   "address": 24,
   "type": "line",
   "text": "The player's facing and last direction code, in the same pattern as move_dir: $0B, $09 or $0A (bit 3 set) face left and $07, $05 or $06 (bit 3 clear) face right; $0E (up) and $0D (down) are stored too, and since they have bit 3 set the facing tests treat them as left. player_animate and player_pose read it to choose the frames, the shot code reads it for the aim, and the walk, jump and mode routines store the step direction in it. new_game_defaults sets it to 7."
  },
  {
   "address": 25,
   "type": "line",
   "text": "Direction of motion of the object the player stands on, in the joystick pattern ($0E up, $0D down, $0B left, $07 right). apply_dir_and_speed copies it from the object (obj_dir); phase1_nudge_y, phase3_land_check and phase5_substate1_block_check set it to $0D. update_player resets it to $FF every frame, and player_ride_object moves the player accordingly. The probes read it too ($0D means the platform is already known)."
  },
  {
   "address": 26,
   "type": "line",
   "text": "Number of the object the player stands on (set by platform_scan_next), or $FF when none. A non-negative value makes the movement code carry the player with the object and skip the floor test; ride_finish and player_jump_start use it to clear the flag that platform_scan_next set in the object (bit 7 of obj_flags)."
  },
  {
   "address": 28,
   "type": "line",
   "text": "Left edge of the screen in 8-pixel character columns (16 bits, high byte at $1D). set_view_window multiplies it by 8."
  },
  {
   "address": 29,
   "type": "line",
   "text": "High byte of scroll_x ($1C)."
  },
  {
   "address": 30,
   "type": "line",
   "text": "Top edge of the screen in 8-pixel character rows (16 bits, high byte at $1F). set_view_window multiplies it by 8."
  },
  {
   "address": 31,
   "type": "line",
   "text": "High byte of scroll_y ($1E)."
  },
  {
   "address": 32,
   "type": "line",
   "text": "Low byte of the map column the row copy routines work on (16 bits with $21): scroll_x plus 40 for the new right-hand edge, scroll_x minus 1 for the left, and scroll_x, scroll_x minus 1 or scroll_x plus 1 for the top and bottom rows. map_row_copy_start halves it to index the row of map blocks. The horizontal scroll steps also use it to hold the new scroll_x ($48CB, $490D)."
  },
  {
   "address": 33,
   "type": "line",
   "text": "High byte of the map column in $20."
  },
  {
   "address": 34,
   "type": "line",
   "text": "Low byte of the map row the copy routines work on (16 bits with $23): scroll_y, scroll_y minus 1 or scroll_y plus 1 for the redraw of a row, scroll_y plus 21 for the bottom row. map_row_copy_start halves it to pick the row pointer."
  },
  {
   "address": 35,
   "type": "line",
   "text": "High byte of the map row in $22."
  },
  {
   "address": 36,
   "type": "line",
   "text": "Low byte of a pointer ($25 is the high byte) set to $0D22 by stage_setup_tables: the table of section record addresses, two bytes a section. Only stage_setup_tables reads it through this pointer (to load section_ptr with the first entry); the other code reads the table by absolute address, indexed by section_index (or, in init_round_state, by the start section number at $0C06)."
  },
  {
   "address": 37,
   "type": "line",
   "text": "High byte of section_table_ptr ($0D)."
  },
  {
   "address": 38,
   "type": "line",
   "text": "Low byte of the pointer to the record of the section the player is in ($27 is the high byte), loaded from the table at $0D22. load_section_record, update_view_scroll and the room_to_scroll tests read the section's zone and limits through it."
  },
  {
   "address": 39,
   "type": "line",
   "text": "High byte of section_ptr."
  },
  {
   "address": 40,
   "type": "line",
   "text": "Low byte of the pointer to the current weapon record ($29 is the high byte). player_fire reads it: from offset 0, two bytes per aim direction (aim_dir times 2) point to the shot's path; offsets $14 and $15 are the reload times for $08DE and $08DF, then $16-$19 the timer, frame-list limit, frame-list type and mask of a shot; the two-shot weapon reads a second path pointer $1A bytes further on. finish_round_setup sets it to $B9C9, and update_char_block_slots sets it back to $B9C9 (the bytes at $B8F8 and $B8FD) when its timer $08CD runs out and it clears the weapon level $08E0."
  },
  {
   "address": 41,
   "type": "line",
   "text": "High byte of weapon_ptr."
  },
  {
   "address": 42,
   "type": "line",
   "text": "Pointer (low byte $2A, high $2B) to the table of low bytes of the addresses of the map rows; ($2C) holds the high bytes, and the map row index (y / 2) selects the entry. Together with $2C, $2E, $30, $32, $34, $36, $38, $3A, $3C and $3E it is one of eleven stage pointers that stage_setup_tables copies from the 22 bytes at $0C0C."
  },
  {
   "address": 44,
   "type": "line",
   "text": "Pointer (low byte $2C, high $2D) to the table of high bytes of the addresses of the map rows; see map_row_lo_ptr ($2A)."
  },
  {
   "address": 46,
   "type": "line",
   "text": "Pointer (low byte $2E, high $2F) to the table of map blocks: four screen characters for each block number (the two upper characters, then the two lower), which the screen drawing code copies. Points to $0D32 in the saved snapshot."
  },
  {
   "address": 47,
   "type": "line",
   "text": "High byte of block_chars_ptr."
  },
  {
   "address": 48,
   "type": "line",
   "text": "Pointer (low byte $30, high $31) to the table of block properties, one byte a block number: block_property_at and the terrain probes read it (bit 0 solid, bit 1 harmful, bit 5 'enter mode 1', bits 2 and 3 slopes, as the player routines test them)."
  },
  {
   "address": 50,
   "type": "line",
   "text": "Pointer (low byte $32, high $33) to the table of path addresses that path_advance indexes with obj_arc_state. The next two bytes, $34 and $35, are the stage pointer loaded from $0C16/$0C17; no code reads them in the listing."
  },
  {
   "address": 54,
   "type": "line",
   "text": "Pointer (low byte $36, high $37) to stage data that object_script_step uses to find an object's movement script. The word at $38 is the second such pointer."
  },
  {
   "address": 56,
   "type": "line",
   "text": "Second pointer (low byte $38, high $39) used by object_script_step to find an object's movement script; see script_ptr_a ($36)."
  },
  {
   "address": 58,
   "type": "line",
   "text": "Pointer (low byte $3A, high $3B) to a table of low bytes of the addresses of the animation data blocks of the stage, indexed by animation number. stage_start sets it from $0C1C/$0C1D and the routine at $06E6 fills the table while the stage loads; advance_object_animation and reselect_object_animation_frame read it."
  },
  {
   "address": 59,
   "type": "line",
   "text": "High byte of anim_lo_ptr."
  },
  {
   "address": 60,
   "type": "line",
   "text": "Pointer (low byte $3C, high $3D) to the table of high bytes of the addresses of the animation data blocks; the partner of anim_lo_ptr ($3A). stage_start sets it from $0C1E/$0C1F. The word at $3E (from $0C20) is read by no code in the listing."
  },
  {
   "address": 61,
   "type": "line",
   "text": "High byte of anim_hi_ptr."
  },
  {
   "address": 64,
   "type": "line",
   "text": "Left edge of the visible stage in pixels (16 bits, high byte at $41), set by set_view_window; pin_view_left and pin_view_right round it down to a multiple of 8."
  },
  {
   "address": 65,
   "type": "line",
   "text": "High byte of view_left ($40)."
  },
  {
   "address": 66,
   "type": "line",
   "text": "Top edge of the visible stage in pixels (16 bits, high byte at $43), set by set_view_window; pin_view_top and pin_view_bottom round it down to a multiple of 8."
  },
  {
   "address": 67,
   "type": "line",
   "text": "High byte of view_top ($42)."
  },
  {
   "address": 68,
   "type": "line",
   "text": "Right edge of the visible stage in pixels (16 bits, high byte at $45): view_left + $12F."
  },
  {
   "address": 69,
   "type": "line",
   "text": "High byte of view_right ($44)."
  },
  {
   "address": 70,
   "type": "line",
   "text": "Bottom edge of the visible stage in pixels (16 bits, high byte at $47): view_top + $9F."
  },
  {
   "address": 71,
   "type": "line",
   "text": "High byte of view_bottom ($46)."
  },
  {
   "address": 72,
   "type": "line",
   "text": "Low byte of a pointer ($49 is the high byte) that patch_stage_code and the per-stage patches set for the stage code they patch: $000A for stage 0 and $1FC8 for stage 1. No code in the listing reads it; the stage code loaded at run time presumably does."
  },
  {
   "address": 73,
   "type": "line",
   "text": "High byte of patch_ptr."
  },
  {
   "address": 74,
   "type": "line",
   "text": "Low byte of the pointer ($4B is the high byte) to the five digits of a score award: add_score_points sets it from the tables at $042E and $0431 and adds the digits to the score at $08D0-$08D4."
  },
  {
   "address": 75,
   "type": "line",
   "text": "High byte of award_ptr."
  },
  {
   "address": 76,
   "type": "line",
   "text": "Left edge of the player's hit box 1 (16 bits, high byte at $4D): player_x plus the offset $031A. Box 1 follows the body; the offsets $031A-$031D change with the player's pose."
  },
  {
   "address": 77,
   "type": "line",
   "text": "High byte of player_box_left ($4C), the left edge of hit box 1."
  },
  {
   "address": 78,
   "type": "line",
   "text": "Right edge of the player's hit box 1 (16 bits, high byte $4F): player_box_left plus the width $031B. Built by object_sprites_and_hits and compared with the objects' hit boxes."
  },
  {
   "address": 79,
   "type": "line",
   "text": "High byte of player_box_right ($4E)."
  },
  {
   "address": 80,
   "type": "line",
   "text": "Top edge of the player's hit box 1 (16 bits, high byte $51): player_y plus the offset $031C."
  },
  {
   "address": 81,
   "type": "line",
   "text": "High byte of player_box_top ($50)."
  },
  {
   "address": 82,
   "type": "line",
   "text": "Bottom edge of the player's hit box 1 (16 bits, high byte $53): player_box_top plus the height $031D. The contact routine at $A5B2 compares an object's top with it."
  },
  {
   "address": 83,
   "type": "line",
   "text": "High byte of player_box_bottom ($52)."
  },
  {
   "address": 84,
   "type": "line",
   "text": "Left edge of the player's hit box 2, which belongs to the third sprite (16 bits, high byte $55): player_third_x plus $031E. Box 2 is tested first for objects whose $3427 byte is below 2."
  },
  {
   "address": 85,
   "type": "line",
   "text": "High byte of player_box2_left ($54)."
  },
  {
   "address": 86,
   "type": "line",
   "text": "Right edge of hit box 2 (16 bits, high byte $57): player_third_x plus $031F (not player_box2_left plus it)."
  },
  {
   "address": 87,
   "type": "line",
   "text": "High byte of player_box2_right ($56)."
  },
  {
   "address": 88,
   "type": "line",
   "text": "Top edge of hit box 2 (16 bits, high byte $59): player_third_y plus $0320."
  },
  {
   "address": 89,
   "type": "line",
   "text": "High byte of player_box2_top ($58)."
  },
  {
   "address": 90,
   "type": "line",
   "text": "Bottom edge of hit box 2 (16 bits, high byte $5B): player_third_y plus $0321 (not player_box2_top plus it)."
  },
  {
   "address": 91,
   "type": "line",
   "text": "High byte of player_box2_bottom ($5A)."
  },
  {
   "address": 92,
   "type": "line",
   "text": "Four bytes, one for each path slot (the tables are four bytes apart; the slot number is obj_arc_counter, $3F76,x, of the object): the last offset of the path data that path_advance may read. When it falls below path_pos the path is over and path_finish runs."
  },
  {
   "address": 96,
   "type": "line",
   "text": "Four bytes, one for each path slot: which axes the path steps along. path_advance adds one word of path data to the object's X for 0, to its Y for 1, and an X word followed by a Y word for 2 or more."
  },
  {
   "address": 100,
   "type": "line",
   "text": "One byte for each path slot (the tables $5C, $60 and $64 are four bytes apart): the offset of the next word in the path data that path_advance reads. It steps by 2, or by 4 when both axes move. When the word read holds $80 in its low byte the read restarts at offset 0, so path_pos becomes 2 (or 4). Only path_advance reads or writes it."
  },
  {
   "address": 107,
   "type": "line",
   "text": "Set by copy_sprites_to_tables to the sort-list position of the last sprite it copied when it stopped at hardware slot 7, and to 0 when it reached the end of the list (also written at $4F12 and read at $4112). When it is non-zero, wait_nmi points the raster interrupt at $95A4, to show the sprites left over: sprite_reuse_irq tries the hardware sprites in turn from the one after the sprite it used last, and gives each left-over sprite the next one whose free line has passed."
  },
  {
   "address": 108,
   "type": "line",
   "text": "Eight bytes, one for each hardware sprite: the raster line from which the sprite is free to show another logical sprite. nmi_frame copies them from $07EF-$07F6 each frame; the reuse routines of sprite_reuse_irq compare them with the raster line and set a sprite's byte to the new sprite's Y plus its height."
  },
  {
   "address": 116,
   "type": "line",
   "text": "Eight bytes: the numbers of the objects that update_objects found this frame with bits 3 and 4 of obj_state set, the ones platform_scan_next tests as something to stand on. The count is in $0910. platform_scan_next walks the list to find what the player stands on."
  },
  {
   "address": 124,
   "type": "line",
   "text": "The X register saved by nmi_frame on every frame update (frame_mode $08B0 positive: the full update at 2 or more, and the VIC-shadow-only update at 1); apply_vic_shadows restores it before the RTI."
  },
  {
   "address": 125,
   "type": "line",
   "text": "The Y register saved by nmi_frame; apply_vic_shadows restores it before the RTI."
  },
  {
   "address": 126,
   "type": "line",
   "text": "Queue of the logical sprites left over after copy_sprites_to_tables filled the hardware sprites, in top-to-bottom order and ended by $FF. carry_over_sprite_overflow builds it from sprite_y_buckets once a frame when sprite_more is set; sprite_reuse_irq walks it. With at most 22 entries and 7 or 8 of them on hardware sprites it ends by $8D, but nothing limits its index, and entries filed again after object_sprites_and_hits reaches its limit (it does not store sprite_count then) can make it longer."
  },
  {
   "address": 128,
   "type": "line",
   "text": "More of sprite_overflow_queue, which starts at $7E; carry_over_sprite_overflow counts its index up with no limit until it meets the closing $7F of the sort list, so the queue runs on past here (normally ending by $8D). It holds sprite numbers while there are many left-over sprites."
  },
  {
   "address": 143,
   "type": "line",
   "text": "queue_sound keeps the caller's Y register here while it works and gives it back on return."
  },
  {
   "address": 144,
   "type": "line",
   "text": "Number of sound effects waiting in sound_queue ($91-$93), at most 3. queue_sound adds one, sound_frame plays them from the last and counts it down; round_start and read_keys clear it when they restart the sound."
  },
  {
   "address": 145,
   "type": "line",
   "text": "Three bytes: the sound effect numbers queued by queue_sound at $91 plus sound_queue_count. sound_frame plays them in turn through $6633 and empties the queue."
  },
  {
   "address": 148,
   "type": "line",
   "text": "Bit 7 makes update_objects set move_mask to $FF, so every object moves this frame; otherwise move_mask is the one bit of frame_bits chosen by frame_count, and an object moves only when that bit is set in its obj_move_bits byte. The main loop sets it to $80 before the first frame of a round ($80F7); wait_frame then overwrites it every frame with bit 5 of the state of the object in $08CC (the stage-cleared test). The bytes from $95 to $DE are not used by any code in the listing."
  },
  {
   "address": 223,
   "type": "line",
   "text": "Sound mode: 0 while the game plays sound effects, $FF while it plays music instead. read_keys flips it on SPACE ($52E6): at $FF it silences the SID and starts the player with X = 6 (sid_player_init), at 0 it clears the queue and runs sound_init; round_start does the same by its value ($807E). While it is set queue_sound adds nothing and sound_frame skips the queued effects but still runs sid_player_update; level_timer_tick, air_hit_hazard, ride_hit and the hit code at $A645 start a fade-out ($6ED8, A = $25) only when it is set."
  },
  {
   "address": 224,
   "type": "line",
   "text": "Parameter for the stage-intro code: set to 0 when the game ends ($4051) and to 9 at $5259; $524F stores it in $0C04 before the code at $0C05 is called."
  },
  {
   "address": 225,
   "type": "line",
   "text": "General scratch byte of the whole game. Main roles: first terrain-probe result (in the row probes the block at the left column of the player's box, at its top or under its feet; in the column probes the top block of the column at its left or right edge), merged with $E2 and $E3 by the movement code; low byte of the map row address in the map and screen copies; low byte of a destination pointer in the record unpackers; low byte of the handler address scroll_phase_step takes from $0324 and jumps through; a counter or temporary in many short routines."
  },
  {
   "address": 226,
   "type": "line",
   "text": "General scratch byte. Second terrain-probe result: the next block down in the column probes when the box is tall enough, or the next block to the right in the row probes when it is wide enough (both copies of $E1 otherwise); high byte of the map row address ($E1/$E2) in the map copies; high byte of the scroll handler address; temporary elsewhere."
  },
  {
   "address": 227,
   "type": "line",
   "text": "General scratch byte. Third terrain-probe result (the block at the right or lower edge); with $E4 a 16-bit pointer: a screen address in the shot-cell drawing and draw_screen_from_tile_map, the block character source in the screen column copies, a cartridge source address in the record unpackers."
  },
  {
   "address": 228,
   "type": "line",
   "text": "General scratch byte. High byte of the pointer $E3/$E4; probe_player_tiles and probe_player_tiles_one_column also store 3 here with $E2 and $E3 at the edge of the screen, but nothing reads it as a probe result; temporary elsewhere."
  },
  {
   "address": 229,
   "type": "line",
   "text": "Low byte of a 16-bit scratch word used as a pointer or an X position: the screen destination in the screen column copies (the block character source in draw_screen_from_tile_map), the colour RAM address in the shot-cell drawing, the source in unpack_bank_record, the animation data pointer in advance_object_animation, and an edge of the player's box in the terrain probes (the right edge in probe_player_tiles, the left edge in the others and in compute_trial_box_edges)."
  },
  {
   "address": 230,
   "type": "line",
   "text": "High byte of the 16-bit scratch word in $E5."
  },
  {
   "address": 231,
   "type": "line",
   "text": "Low byte of the working X position of an object (16 bits with $E8) in the object update, movement and script routines, loaded from obj_x_lo and obj_x_hi at $A215; also the frame list pointer in slot_on_screen and a counter in the loaders."
  },
  {
   "address": 232,
   "type": "line",
   "text": "High byte of the working X position in $E7; also a loop index in the loaders."
  },
  {
   "address": 233,
   "type": "line",
   "text": "Low byte of the working Y position of an object (16 bits with $EA), loaded from obj_y_lo and obj_y_hi; the frame definition pointer in the shot-slot drawing; the row counter of the screen column copies."
  },
  {
   "address": 234,
   "type": "line",
   "text": "High byte of the working Y position in $E9, or of the pointer in the shot-slot drawing."
  },
  {
   "address": 235,
   "type": "line",
   "text": "Temporary: the map block column that block_property_at computes (X / 16), the slot number kept across the shot-slot drawing, the object number in path_advance, and the high byte of a Y position in the terrain probes."
  },
  {
   "address": 236,
   "type": "line",
   "text": "Temporary: the map block row that block_property_at computes (Y / 16), the path slot number in path_advance, and the low byte of the right edge of the player's box in platform_scan_next."
  },
  {
   "address": 237,
   "type": "line",
   "text": "Temporary: high byte of the right edge of the player's box ($EC/$ED) in the platform scan and terrain probes; a counter in the loaders."
  },
  {
   "address": 238,
   "type": "line",
   "text": "Temporary: low byte of the player box's Y edge ($EE/$EF) in compute_trial_box_edges and platform_scan_next."
  },
  {
   "address": 239,
   "type": "line",
   "text": "Temporary: high byte of the Y edge in $EE; the cartridge directory index in the stage loaders; the map column (scroll_x / 2) in draw_screen_from_tile_map."
  },
  {
   "address": 240,
   "type": "line",
   "text": "Flag and temporary. $FF while object_sprites_and_hits works on the short-lived objects, 0 for the stage objects; the entry marker of the terrain probes ($FF from the one-row entry at $9D17, 0 from $9D3C); the map row in draw_screen_from_tile_map; the first byte of the section data in the record loaders."
  },
  {
   "address": 243,
   "type": "line",
   "text": "The pool slot (0 to 8) that update_temp_objects is working on; it also indexes the velocity bytes. player_pose uses it for the extent index of the third sprite."
  },
  {
   "address": 244,
   "type": "line",
   "text": "Keeps the Y register across the call to add_score_points in the shot-hit code (b_A6F0 and the contact routine at $A5EB)."
  },
  {
   "address": 245,
   "type": "line",
   "text": "Low byte of the pointer ($F6 is the high byte) to the script or pattern data of the voice that the sound engine is working on (music note stream or pattern, and the effect scripts); the sound routines read the bytes through it with Y."
  },
  {
   "address": 246,
   "type": "line",
   "text": "High byte of voice_script_ptr ($F5)."
  },
  {
   "address": 247,
   "type": "line",
   "text": "Low byte of the pointer ($F8 is the high byte) to a voice's sequence in the tune that sid_player_init starts, copied from $651B/$651E by advance_voice_sequence (called only from sid_init_voice_loop); its bytes below $F0 choose the phrase that goes into voice_script_ptr ($F5), and higher bytes are commands. Sound effects do not use it."
  },
  {
   "address": 248,
   "type": "line",
   "text": "High byte of effect_script_ptr ($F7)."
  },
  {
   "address": 251,
   "type": "line",
   "text": "Temporary of the sound engine: the control register value that pattern_cmd_set_control reads from the script. When its bit 3 (test) is set it is written to the voice's control register as it is and then with bit 3 cleared; otherwise it is written once."
  },
  {
   "address": 252,
   "type": "line",
   "text": "Active flag of music voice 0 (one byte for each voice, indexed by the voice number: $FC, $FD, $FE). sid_player_init sets them to 1, sid_silence_all clears them, and the update loops skip a voice whose flag is 0."
  },
  {
   "address": 253,
   "type": "line",
   "text": "Active flag of sound voice 1 (music, or an effect that sid_reset_voice_state started on it); see $FC."
  },
  {
   "address": 254,
   "type": "line",
   "text": "Active flag of sound voice 2 (music, or an effect that sid_reset_voice_state started on it); see $FC."
  },
  {
   "address": 255,
   "type": "line",
   "text": "The voice counter of the sound engine: the update and initialisation loops count it from 2 down to 0 and use it as the index X of the per-voice tables."
  },
  {
   "address": 256,
   "type": "line",
   "text": "Copy directory entries 0 to 5 with cart_copy: X takes the values $00, $08 ... $28 (it starts from $F8 in $EF and adds 8 before each call, counting six in $F0); A is not used."
  },
  {
   "address": 287,
   "type": "line",
   "text": "Copy one entry of the cartridge directory into RAM. Selects bank 0 ($80 to the Ocean bank register $DE00), reads the entry at $8009+X (source bank, source address, destination, length), then switches to the source bank and copies."
  },
  {
   "address": 512,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: colour of each logical sprite entry (bit 7 means double size), copied from lspr_colour ($0808). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 536,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: height in lines, copied from lspr_height ($0820). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 560,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: sprite pointer value, copied from lspr_pointer ($0838). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 584,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: X low byte, copied from lspr_x_lo ($0850). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 608,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: X high byte, copied from lspr_x_hi ($0868). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 632,
   "type": "line",
   "text": "Table of 24 bytes, one for each logical sprite entry: Y, copied from lspr_y ($0880). wait_frame copies the six logical sprite tables here ($8224) after carry_over_sprite_overflow has queued the left-over sprites, and sprite_reuse_irq reads this copy when it gives hardware sprites to the queued entries, so the raster interrupt works on a list that the next frame's sprite code does not touch while it runs. Nothing else reads it."
  },
  {
   "address": 656,
   "type": "line",
   "text": "Blink timer of object $08CC, run once a frame by slot_blink_timer: a positive value counts down with bit 6 of the object's $35EF byte set; 0 underflows to $81, which counts down with that bit cleared (the top bits come from $08CB), and $80 goes back to 0 with the bit set. Only slot_blink_timer writes it, so from 0 it cycles 0, $81, $80 and sets the bit one frame in three."
  },
  {
   "address": 657,
   "type": "line",
   "text": "Property byte of the block in the probe's far column (player_try_x plus $1F), stored by probe_far_column, which probe_player_tiles_one_row ($9D17) and player_probe_tiles_and_platforms reach through probe_columns_from_y; probe_outside_map stores 0 when the probe is outside the map. mode1_up_end calls $9D17 before testing it for non-zero. Bits 2 and 3 mean a slope to ground_slope_or_fall, ground_set_slope, the ground_slope_* routines and air_block_flags (air_slope_land tests bit 2); air_slope_check tests bits 0 and 3, mode1_down_end bit 4 and player_animate bit 0."
  },
  {
   "address": 658,
   "type": "line",
   "text": "Non-zero while the player is hit or dying. The value is set to 1 at $8B7A and $8E14 (the tile check finds bit 1, harmful) and to $FF at $82C9 and $A638, and cleared at $4F04 by init_round_state at the start of each round. While it is set, player_animate ($98F3) shows a fixed shape, player_fire ($AF34) does nothing, and $89A9 restores the previous position."
  },
  {
   "address": 659,
   "type": "line",
   "text": "After the player is hit, player_hit_step sets it to $19 once the falling player has reached the bottom of the screen; the main loop then counts it down on each frame on which no sound voice is active (sid_any_voice_active) and calls round_start when it reaches 0 ($8122). Also used as the 20-frame wait after round_start's setup ($80E1). init_round_state sets it to 0."
  },
  {
   "address": 660,
   "type": "line",
   "text": "State of the between-stage screens. $FF (set by wait_frame when a stage is cleared) runs the sprite sequence at $4095; 0 shows the stage card and waits for fire; after fire it becomes 1, which makes stage_intro_start add one to the lives counter $089D and go to stage_begin. Cleared by new_game_reset."
  },
  {
   "address": 661,
   "type": "line",
   "text": "Speed in pixels of the object the player rides: apply_dir_and_speed copies obj_speed here, phase1_nudge_y sets 1. ride_down sends the player off the object (player_leave_object) when it is 7 or more."
  },
  {
   "address": 662,
   "type": "line",
   "text": "The animation key the player's current animation was started for: player_action ($0905) ORed with a direction bit (bit 3 of the facing or move direction, or bit 2 from bit 1). player_animate compares the new key with it at $994F, $9A48 and $9BBF; when they differ, or $0903 is non-zero, it stores the new key and restarts the counters $0901 and $0903 at 0."
  },
  {
   "address": 663,
   "type": "line",
   "text": "Aim direction of the player's shots, 0 to 9: 0 up (facing right), 1 up-right, 2 right, 3 down-right, 4 down (facing right), 5 down (facing left), 6 down-left, 7 left, 8 up-left, 9 up (facing left). Written by player_fire ($AF34, including $B1CF), set_idle_aim ($9F05), and reserve_player_object_slots_loop (2, at $507E); read by player_fire to place the shot with the offsets at $0334, by set_idle_aim ($9F11) and by $4154 and $4182."
  },
  {
   "address": 664,
   "type": "line",
   "text": "Number of the stage section that holds the player. Set from the stage record at $500E, and changed by track_stage_section ($92DF) when the player moves into the next or previous section; the record address is in ($26). Also written at $884C."
  },
  {
   "address": 665,
   "type": "line",
   "text": "Stance flag in mode 0: $FF after player_stop or a step with down held (player_down_left and player_down_right enter walk_*_move with $FF), 1 where the mode 1 exit code at $929B sets it, and 0 after a plain walk step (walk_left_dir, walk_right_dir) and from pm_idle, jump_start_state, ground_slope_or_fall, player_leave_object and $A784. player_pose, set_idle_aim and player_fire ($AF6F) choose the frame and aim from it."
  },
  {
   "address": 666,
   "type": "line",
   "text": "The bit mask object updates AND with an object's $3484 byte to decide whether it moves this frame: $FF when bit 7 of $94 is set, otherwise the single bit $029E[frame_count AND 7]."
  },
  {
   "address": 667,
   "type": "line",
   "text": "The player's X on screen in sprite coordinates (16 bits, high byte $029C): player_x minus view_left plus $20, worked out by player_sprite_coords and written to sprite 0's X at $40A7. update_view_scroll compares it with zone_left and zone_right."
  },
  {
   "address": 668,
   "type": "line",
   "text": "High byte of player_screen_x ($029B)."
  },
  {
   "address": 669,
   "type": "line",
   "text": "The player's Y on screen in sprite coordinates, written to sprite 0's Y at $81C2. update_view_scroll compares it with zone_top and zone_bottom."
  },
  {
   "address": 670,
   "type": "line",
   "text": "Eight bytes, $01, $02, $04, $08, $10, $20, $40, $80: one bit for each value 0 to 7. update_objects picks move_mask from it by the low three bits of frame_count, and copy_sprites_to_tables uses it as the bit of each hardware sprite slot."
  },
  {
   "address": 678,
   "type": "line",
   "text": "Table indexed by a sprite count: $00, $01, $03, $07, $0F, $1F, $3F, $7F, $FF, the sprite-enable mask with that many sprites on."
  },
  {
   "address": 699,
   "type": "line",
   "text": "Three score awards of five decimal digits each, for the award classes 0 to 2 that add_score_points adds to the score at $08D0-$08D4: $02BB holds 0,0,0,1,0 (10 points), $02C0 holds 0,0,0,5,0 (50) and $02C5 holds 0,0,1,0,0 (100), read as plain digits, so 10, 50 and 100 points if the five digits are the whole score."
  },
  {
   "address": 714,
   "type": "line",
   "text": "Non-zero while the game is paused. read_keys flips it between 0 and $FF when RUN/STOP is pressed, and while it is non-zero the main loop only scans the keyboard (it repeats $80FC)."
  },
  {
   "address": 715,
   "type": "line",
   "text": "The shape number last copied into the third sprite's block at $FF80; copy_sprite_shapes copies a new shape only when player_shape_3 differs from it."
  },
  {
   "address": 716,
   "type": "line",
   "text": "The shape number last copied into the first player sprite's block at $FF00; compared with player_shape_1 by copy_sprite_shapes."
  },
  {
   "address": 717,
   "type": "line",
   "text": "The shape number last copied into the second player sprite's block at $FF40; compared with player_shape_2 by copy_sprite_shapes."
  },
  {
   "address": 718,
   "type": "line",
   "text": "Table of 17 bytes: pixels risen in one frame of a jump or arc, indexed by the jump counter (limited to 16): 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 6. player_jump_motion subtracts the entry from player_try_y (mode2_jump_motion adds it) and from the counter, so the rise slows toward the top; object_arc_step uses it for objects."
  },
  {
   "address": 735,
   "type": "line",
   "text": "Table of 9 bytes: pixels fallen in one frame, indexed by the fall counter, which rises by one to a limit of 8: 0, 1, 1, 2, 2, 3, 4, 5, 6. The air routines (air_down_left_x, air_down_right_x, jump_fall, mode2_jump_fall, arc_fall) and object_arc_step index it, so a fall speeds up."
  },
  {
   "address": 744,
   "type": "line",
   "text": "Table of 20 bytes: the low byte of the offset of each character row of the playfield in the screen buffer (row times 40: $00, $28, $50, $78 and on to $F8 for row 19). slot_on_screen adds the offset to the screen buffer address."
  },
  {
   "address": 764,
   "type": "line",
   "text": "Table of 20 bytes: the high byte of the row offsets in screen_row_lo (0 for rows 0 to 6, 1 for rows 7 to 12, 2 for rows 13 to 19). The ten bytes $0310-$0319 after it are not read by any code in the listing."
  },
  {
   "address": 794,
   "type": "line",
   "text": "Offset from player_x to the left edge of the player's hit box 1 (player_box_left = player_x + this). Set with the pose by player_animate and the transition code (from bytes 4-7 of the animation tables or $04EC)."
  },
  {
   "address": 795,
   "type": "line",
   "text": "Width of the player's hit box 1: player_box_right = player_box_left + this. The terrain probes read a second column only when it is above $10."
  },
  {
   "address": 796,
   "type": "line",
   "text": "Offset from player_y to the top of hit box 1 (player_box_top = player_y + this). track_stage_section also adds it to player_y; the terrain probes and compute_trial_box_edges add it to player_try_y."
  },
  {
   "address": 797,
   "type": "line",
   "text": "Height of hit box 1: player_box_bottom = player_box_top + this. The terrain probes use it to find the lower edge."
  },
  {
   "address": 798,
   "type": "line",
   "text": "Offset from player_third_x to the left edge of hit box 2 (the third sprite). player_pose loads it from the table at $03F7, indexed by the first byte of the frame record."
  },
  {
   "address": 799,
   "type": "line",
   "text": "Offset from player_third_x to the right edge of hit box 2 (object_sprites_and_hits adds it to player_third_x, not to the left edge); player_pose loads it from the table at $040B."
  },
  {
   "address": 800,
   "type": "line",
   "text": "Offset from player_third_y to the top of hit box 2; player_pose loads it from the table at $0401."
  },
  {
   "address": 801,
   "type": "line",
   "text": "Height of hit box 2; player_pose loads it from the table at $0415."
  },
  {
   "address": 802,
   "type": "line",
   "text": "Offset added to the X of the player's first sprite in player_sprite_coords (24 in the saved state). player_animate sets it from byte 1 of each animation table, and player_down_enter_mode1 sets it to $12. player_pose adds it to the third sprite's position too."
  },
  {
   "address": 803,
   "type": "line",
   "text": "Offset added to the Y of the player's first sprite in player_sprite_coords; set from byte 2 of the animation tables and cleared by player_down_enter_mode1. player_pose adds it to the third sprite's position."
  },
  {
   "address": 804,
   "type": "line",
   "text": "Eight bytes: the low bytes of the addresses of the eight routines scroll_phase_step jumps to, indexed by scroll_dir. Each routine ($5323, $542C, $5535, $564A, $5753, $585C, $5965, $5A7A) copies the rows of the other character screen buffer into the buffer being built, moved one character in that direction (the first, for scroll_dir 0, moves every row down one row), and picks its direction of copy by $11."
  },
  {
   "address": 812,
   "type": "line",
   "text": "Eight bytes: the high bytes of the addresses of the scroll copy routines; see scroll_handler_lo ($0324). The values are $53 to $5A."
  },
  {
   "address": 820,
   "type": "line",
   "text": "Table of ten pairs of bytes, one pair for each aim direction (aim_dir 0 to 9): the X and Y offsets that player_fire adds to player_third_x and player_third_y to find where a shot starts. The result is rounded down to a multiple of 8; the two-shot weapon (b_B08F) then sets its low bits to 3 in the first slot and 4 in the second. The Y bytes are at $0335, $0337 and on."
  },
  {
   "address": 821,
   "type": "line",
   "text": "The Y offsets of shot_start_offsets: the odd bytes of the ten pairs $0334-$0347, read by player_fire for the aim direction. "
  },
  {
   "address": 840,
   "type": "line",
   "text": "Appearance data of the player's shots, drawn by the shot-slot routines. Three frame lists of word pointers: $0348 (4 entries, pointing to $0350, $0355, $035A, $0355), $035F (2 entries: $0363, $0368) and $036D (6 entries: $0379 three times, $0388, $0390 twice). Each frame definition is: draw case (0 one cell, 2 a 2x2 block), colour, X offset 8 or $10, Y offset 8 or $10, then the characters: $F5 in colours 1, 7 and 5 at $0350-$035E, $F4 in colours 1 and 7 at $0363-$036C, $F6, $F7 and $F8 in colour $0F at $0379-$0387, and the 2x2 blocks $F7-$FA at $0388 and $FB-$FE at $0390. $0398 and $039B select a list."
  },
  {
   "address": 920,
   "type": "line",
   "text": "Low bytes of the addresses of the three frame lists of shot_frame_data ($5F, $6D, $48): slot_on_screen picks one with the shot type in $0713,x. The high bytes follow at $039B."
  },
  {
   "address": 923,
   "type": "line",
   "text": "High bytes of the three frame lists (all $03), then the bytes $039E to $03F6, which no code in the listing reads."
  },
  {
   "address": 1015,
   "type": "line",
   "text": "Table indexed by the first byte of the player's frame record (the third sprite's shape class), which runs 1 to 10 in the records, so the ten entries are $03F8-$0401: the left offset of hit box 2. player_pose copies the entry to box2_left_off ($031E)."
  },
  {
   "address": 1025,
   "type": "line",
   "text": "Table indexed like box2_left_tab (1 to 10, so the entries are $0402-$040B): the top offset of hit box 2, copied to box2_top_off ($0320)."
  },
  {
   "address": 1035,
   "type": "line",
   "text": "Table indexed like box2_left_tab (1 to 10, so the entries are $040C-$0415): the width of hit box 2, copied to box2_width ($031F)."
  },
  {
   "address": 1045,
   "type": "line",
   "text": "Table indexed like box2_left_tab (1 to 10, so the entries are $0416-$041F): the height of hit box 2, copied to box2_height ($0321). The bytes $0420-$042D after it are not read by any code in the listing."
  },
  {
   "address": 1070,
   "type": "line",
   "text": "Three bytes: the low bytes of the addresses of the score awards of classes 0 to 2 ($BB, $C0, $C5), which add_score_points puts in award_ptr ($4A). The high bytes follow at $0431."
  },
  {
   "address": 1073,
   "type": "line",
   "text": "Three bytes: the high bytes of the score award addresses (all $02); see award_ptr_lo ($042E). The awards themselves are at $02BB."
  },
  {
   "address": 1076,
   "type": "line",
   "text": "The partial tiles of the energy gauge: draw_segment_gauge takes the boundary cell from here by the low two bits of the value ($D5, $DA, $D9, $D8; $D5 is also the empty cell). The 32 bytes after them, $0438-$0457, are the two animation tables of action 7 (mode 2), at $0438 and $0448 (see player_anim_tables)."
  },
  {
   "address": 1112,
   "type": "line",
   "text": "The player's animation tables, chosen by player_animate by action and facing: $0458, $046C, $04AC, $04B6, $04C0 and $04CA for actions below 5, $0480, $0490 and $04A0 for actions 5 and 6 (also used by the transitions), and $0438 and $0448 for action 7. A table starts with the length of its shape list; bytes 1 and 2 are the sprite offsets $0322 and $0323, byte 3 the second-sprite flag $0900, bytes 4 to 7 the hit box offsets $031A-$031D, and from byte 8 come pairs of shape numbers (player_shape_1, player_shape_2) that the frame index $0902 steps through two at a time."
  },
  {
   "address": 1256,
   "type": "line",
   "text": "Shape numbers for the player's transition sequences (state $08FF): player_animate loads player_shape_1 from $04E8,x and player_shape_2 from $04E9,x for the state."
  },
  {
   "address": 1257,
   "type": "line",
   "text": "Shape numbers for the transition sequences read as $04E9,x, one byte after those at $04E8: player_shape_2 for the state."
  },
  {
   "address": 1260,
   "type": "line",
   "text": "Four bytes for each transition step, indexed by four times ((the state AND $3F) minus 2): the hit box offsets that go to $031A-$031D (left offset, width, top offset, height) while the transition plays. States 2 and $42 use $04EC-$04EF, states 4 and $44 use $04F4-$04F7; $04F0-$04F3 is not used."
  },
  {
   "address": 1261,
   "type": "line",
   "text": "The second byte of each four-byte entry of transition_boxes: box1_width ($031B)."
  },
  {
   "address": 1262,
   "type": "line",
   "text": "The third byte of each four-byte entry of transition_boxes: box1_top_off ($031C)."
  },
  {
   "address": 1263,
   "type": "line",
   "text": "The fourth byte of each four-byte entry of transition_boxes: box1_height ($031D). The last entry read is at $04F4, so $04F7 is the last byte used; $04F8-$04FF are not read."
  },
  {
   "address": 1280,
   "type": "line",
   "text": "Loads the object records for the current stage from the cartridge bank. Sets the bank register $DE00 to $80, copies 64 bytes from the pointer at $0C07 into $0100, then walks the records in groups of 3 bytes: for each it runs unpack_bank_record and the routine at $06E6 once per entry (stepping $EF by 2), builds the offset table at $0773 and the index lists at $08AC/$08A8, and stops when a record's first byte has bit 7 set, clearing the border colour $D020 on exit. The stage number $08E7 selects start pointers from tables at $811D/$8122. Role as the stage object-list loader is inferred from the tables it fills."
  },
  {
   "address": 1434,
   "type": "line",
   "text": "Bank-switched record unpacker (likely a level/screen data loader; A = object definition number taken from the stage list at $0100 (names at $05A1)). Writes $87 to $DE00, reads a 16-bit pointer from $8000+2*A into $E3/$E4 (top 3 bits select the bank $87-$8E, address folded into $8000-$9FFF), then copies the records into the buffer at ($E1): groups of 5 bytes, followed by word entries with the destination address added to a stored offset, then a second table of 5-byte records whose 4-byte sub-entries have $08A6 added to one byte. At the end it stores the next pointer into the table at $0773/$0774 indexed by $08A3 (incremented twice) and sets $DE00 and $E5/$E6 for the following block. Uses $E1-$E9. NOTE: the routine runs on past $06DC into zero bytes in the snapshot, so the tail is not visible; called by a jsr at $0560."
  },
  {
   "address": 1441,
   "type": "line",
   "text": "Definition numbers for the object definition table (the A given to unpack_bank_record), named from the section headings in Euan's older notes of the cartridge banks, matched by byte position; a name with ? means the record lies inside that heading's section but not at its start, so it may be one of several records of that creature or object. 00 Gate of Moornah, a record of its own at $806E; 01-1B: 01 Falling platform (Wedge shape); 02 Unknown; 03 Pike projectile; 04 Webstamite projectile; 05 Pike - standard; 06 Pike - incline?; 07 Shartoesi; 08 Shartoesi?; 09 Herbamo; 0A Killer Harnas; 0B Flying Shardu; 0C Coin; 0D Thorpedo; 0E Blastums - Going left; 0F Blastums - Going right; 10 Kalgatrobe; 11 Kalgatrobe; 12 Webstamite; 13 Webstamite?; 14 Geeshergam; 15 Boloragog; 16 Neptuna; 17 Rambacha; 18 Mortoise; 19 Shoshanu; 1A Gabranha small; 1B Gabranha small?"
  },
  {
   "address": 1446,
   "type": "line",
   "text": "Definition numbers, continued (names from Euan's older notes, matched by position; ? = inside that heading's section, not at its start; 24 and 25 point to one record). 1C-36: 1C Cupper; 1D Flying Shardu small; 1E Canon ball / bomb; 1F Horizontal moving platform; 20 Horizontal moving platform; 21 Pike - incline; 22 Pike - incline; 23 Key; 24 Lava burst; 25 Lava burst; 26 Raktura; 27 Ice platform; 28 Timagon; 29 Raktura / Timagon flame splash; 2A Timagon?; 2B Galator; 2C Galator?; 2D Galator?; 2E Galator?; 2F Mogulvar; 30 ZARZAMOTH; 31 1 Up; 32 Raktura / Timagon flame splash?; 33 KATYEROWS; 34 KATYEROWS?; 35 Catecormos; 36 Bashtar"
  },
  {
   "address": 1473,
   "type": "line",
   "text": "Reads the first byte of an object definition record into $E7 and $E9: the number of animation frames. A record is three bytes (frame count, then a 16-bit pointer to the object's sprite shapes with the bank in its top 3 bits), then for each frame a 5-byte header followed by as many 2-byte offsets as the header's first byte, then the box and part lists, ended by a first byte with bit 7 set ($FF in bank 7). The layout was checked against the bank 7 record at $8182 and matches the section layout in Euan's older notes."
  },
  {
   "address": 1492,
   "type": "line",
   "text": "Copies one frame header, 5 bytes, from ($E5) to the buffer at ($E1). The header is the part count, then four box size bytes ($18,$15,$18,$15 for the falling platform, definition 01). X ends up holding the first byte, the number of 2-byte offsets that follow. Both pointers then step 5."
  },
  {
   "address": 1526,
   "type": "line",
   "text": "Copies a 2-byte offset of a frame header into the buffer and adds the buffer address ($E1/$E2) to it, which turns the stored distance into an address of the frame's part list in RAM. Repeats X times, each time stepping both pointers by 2."
  },
  {
   "address": 1620,
   "type": "line",
   "text": "Second pass over the record, after all frame headers: each list starts with a byte whose bit 7 is set at the end ($FF in bank 7) or with the hitbox x offset. A set bit 7 jumps to the tail at b_06AD. Otherwise the list is 5 bytes (hit box left and top offsets, then right and bottom offsets, all from the object's X and Y as set_object_hitbox adds them, then the number of parts) followed by that many 4-byte parts."
  },
  {
   "address": 1662,
   "type": "line",
   "text": "Copies one 4-byte part: relative x offset, relative y offset, sprite colour, then the sprite shape number with the base shape number $08A6 added, so every shape number in the record is relative to where the record's shapes were loaded. Euan's older notes call the fourth byte 'sprite selection'."
  },
  {
   "address": 1709,
   "type": "line",
   "text": "End of the record: stores the 16-bit pointer from the record's bytes 1 and 2 (the stream of sprite shapes to be copied by the background loader) into the list at $0773 and $0774 indexed by $08A3, selects the cartridge bank named by its top 3 bits and forms the address in $E5/$E6, then advances $08A3 by 2."
  },
  {
   "address": 1757,
   "type": "line",
   "text": "Flag byte of each of the six player shot slots (one byte each for slots 0 to 5): bit 7 set means the slot is in use. player_fire sets it to $80 when it creates a shot; update_char_block_slots runs the active slots; slot_deactivate and the hit test of shots against objects (b_A6A1) clear it, and the round setup (clear_06dd_table_loop, $4F5B) clears all six. The slots share this address area with the stage loader, which has finished by the time they are used."
  },
  {
   "address": 1758,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_flags. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1763,
   "type": "line",
   "text": "Low bytes of the left edge (X) of the six shot slots; the high bytes are at shot_x_hi ($06E9). player_fire starts it on a multiple of 8 (plus 3 or 4 for the two-shot weapon), and slot_apply_path_step adds the path step to it, which need not be a multiple of 8; slot_active compares it with the view. The saved snapshot shows leftover loader code here (the slots are empty)."
  },
  {
   "address": 1764,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_x_lo. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1766,
   "type": "line",
   "text": "Stage-load helper called by the record loader load_stage_bank_records for each entry (from $0563). It selects cartridge bank 0, takes the list at ($0C09) with its last index in $0C0B, and looks in it for the definition number in $F0; for each hit it steps over as many frames as ($3C) holds at that index, each a 5-byte header plus 2 bytes per offset, in the record just unpacked at $EA/$ED, and stores the resulting address in the tables ($3A) and ($3C) at that index. The loaders are used only while a stage loads; in play $06DD-$0742 holds the shot slot tables."
  },
  {
   "address": 1769,
   "type": "line",
   "text": "High bytes of the X positions of the six shot slots ($06E3)."
  },
  {
   "address": 1770,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_x_hi. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1775,
   "type": "line",
   "text": "Low bytes of the top edge (Y) of the six shot slots; the high bytes are at shot_y_hi ($06F5). player_fire starts it on a multiple of 8 (plus 3 or 4 for the two-shot weapon), and the path steps then move it."
  },
  {
   "address": 1776,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_y_lo. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1781,
   "type": "line",
   "text": "High bytes of the Y positions of the six shot slots ($06EF)."
  },
  {
   "address": 1782,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_y_hi. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1787,
   "type": "line",
   "text": "Low bytes of the pointer to each shot's path, the list of 4-byte position steps for its aim direction, taken from the weapon record at ($28); the high bytes are at $0701."
  },
  {
   "address": 1788,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_path_lo. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1793,
   "type": "line",
   "text": "High bytes of the shot path pointers ($06FB)."
  },
  {
   "address": 1799,
   "type": "line",
   "text": "Offset of the next 4-byte step in each shot's path; slot_apply_path_step advances it. A step starting with $80 ends the path: the offset goes back 4 (when the animation mask $0725 is non-zero) or to 0."
  },
  {
   "address": 1800,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_path_pos. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1805,
   "type": "line",
   "text": "Frames a shot slot has left: slot_active counts it down and clears the slot when it reaches zero. player_fire loads it from the weapon record."
  },
  {
   "address": 1806,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_timer. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1811,
   "type": "line",
   "text": "Which frame list a shot slot draws (an index into shot_list_lo and shot_list_hi, $0398/$039B), from the weapon record."
  },
  {
   "address": 1812,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_list_type. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1817,
   "type": "line",
   "text": "Offset in the frame list of each shot slot: slot_advance_frame adds 2 and wraps it at shot_frame_end ($071F)."
  },
  {
   "address": 1818,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_frame_pos. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1823,
   "type": "line",
   "text": "End of the frame list of each shot slot: the limit that shot_frame_pos wraps at."
  },
  {
   "address": 1824,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_frame_end. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1829,
   "type": "line",
   "text": "Animation mask of each shot slot: the slot steps its frame and its path only on frames where frame_count AND the mask is zero; a non-zero mask also makes the frame offset wrap to $0A and the path go back one step at its end, and slot_step_sound_check then queues sound $18 for it when the sound queue is empty."
  },
  {
   "address": 1830,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_anim_mask. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1835,
   "type": "line",
   "text": "Low bytes of the right edge of each shot slot's box: X plus the frame's offset (8, or $10 for a 2x2 block). The hit test of shots against objects (b_A6A1) uses the left edge ($06E3/$06E9) and this. The high bytes are at $0731."
  },
  {
   "address": 1836,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_x2_lo. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1841,
   "type": "line",
   "text": "High bytes of the right edges of the shot boxes ($072B)."
  },
  {
   "address": 1842,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_x2_hi. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1847,
   "type": "line",
   "text": "Low bytes of the bottom edge of each shot slot's box: Y plus the frame's offset (8, or $10 for a 2x2 block). The high bytes are at $073D."
  },
  {
   "address": 1848,
   "type": "line",
   "text": "Entry 1 (slots 1 to 5) of shot_y2_lo. The two-shot weapon (b_B08F) fills a slot and the next one in the same call, so it writes this table at an offset of one."
  },
  {
   "address": 1851,
   "type": "line",
   "text": "Reached as $073B,x by restore_saved_cells: the first of four saved characters of a record on the saved-background stack, counted back from the record's end X (see cell_save_stack at $0743)."
  },
  {
   "address": 1852,
   "type": "line",
   "text": "Reached as $073C,x by restore_saved_cells: the second saved character of a four-cell record, counted from the end of the record (see cell_save_stack)."
  },
  {
   "address": 1853,
   "type": "line",
   "text": "Also reached as $073D,x by restore_saved_cells: the third saved character of a four-cell record (the first of a two-cell record), counted from the end of the record. As a shot table it is shot_y2_hi: the first entry of the high bytes of the bottom edges of the shot boxes."
  },
  {
   "address": 1854,
   "type": "line",
   "text": "Reached as $073E,x by restore_saved_cells: the last saved character of a record (the only one of a one-cell record), counted from the end of the record (see cell_save_stack)."
  },
  {
   "address": 1855,
   "type": "line",
   "text": "Reached as $073F,x by restore_saved_cells: the tag of a record counted from the end (0 one cell, 1 two cells, 2 a 2x2 block), see cell_save_stack."
  },
  {
   "address": 1856,
   "type": "line",
   "text": "Reached as $0740,x by restore_saved_cells: the high byte of the screen address of a record, counted from the end of the record (see cell_save_stack)."
  },
  {
   "address": 1857,
   "type": "line",
   "text": "Reached as $0741,x by restore_saved_cells: the low byte of the screen address of a record, counted from the end (cell_save_stack). The colour RAM address has the same low byte."
  },
  {
   "address": 1858,
   "type": "line",
   "text": "Reached as $0742,x by restore_saved_cells: the high byte of the colour RAM address of a record, the last byte of the record (cell_save_stack)."
  },
  {
   "address": 1859,
   "type": "line",
   "text": "The saved-background stack, $0743-$0772: when a shot slot draws over the playfield, slot_save_draw_1_cell, _2_cells and _4_cells push a record with the old characters, a tag (0 one cell, 1 two cells, 2 a 2x2 block), the screen address high and low bytes and the colour RAM address high byte (5, 6 or 8 bytes), and bump the top index $0904. restore_saved_cells pops them and puts the characters and their colours back. The records are laid out so that the characters come first and the tag, address and colour bytes last. The notes on $0744-$074A describe the record at index 0; a later record starts at the index in $0904."
  },
  {
   "address": 1860,
   "type": "line",
   "text": "Second byte of a record on cell_save_stack: the second old character of a two-cell or four-cell record, or the 0 tag of a one-cell record."
  },
  {
   "address": 1861,
   "type": "line",
   "text": "Third byte of a record on cell_save_stack: the screen address high byte of a one-cell record, the tag (1) of a two-cell record, or the third old character of a four-cell record."
  },
  {
   "address": 1862,
   "type": "line",
   "text": "Fourth byte of a record on cell_save_stack: the screen address low byte of a one-cell record, the screen address high byte of a two-cell record, or the fourth old character of a four-cell record."
  },
  {
   "address": 1863,
   "type": "line",
   "text": "Fifth byte of a record on cell_save_stack: the colour RAM address high byte of a one-cell record, the screen address low byte of a two-cell record, or the tag (2) of a four-cell record."
  },
  {
   "address": 1864,
   "type": "line",
   "text": "Sixth byte of a record on cell_save_stack: the colour RAM address high byte of a two-cell record, or the screen address high byte of a four-cell record."
  },
  {
   "address": 1865,
   "type": "line",
   "text": "Seventh byte of a record on cell_save_stack: the screen address low byte of a four-cell record."
  },
  {
   "address": 1866,
   "type": "line",
   "text": "The rest of cell_save_stack, $074A-$0772: the colour RAM address high byte of a four-cell record is the eighth byte, and records pushed later by slot_save_draw_1_cell and the others follow from the index in $0904. With six shot slots at 8 bytes each the stack holds at most 48 bytes."
  },
  {
   "address": 1907,
   "type": "line",
   "text": "Table of stream pieces, two bytes each (lo, hi), $0773-$07AA: load_stage_bank_records builds it, load_stream_source reads it at $08A3. The high byte holds the cartridge bank in its top 3 bits (bank $87 + that value) and the address in $8000-$9FFF in its low 5 bits; the first byte at that address is the number of 63-byte pieces to copy. A zero high byte ends the list of a stream. The low bytes are the even offsets, the high bytes the odd ones. The first entry of each stream is found through $08A8,y."
  },
  {
   "address": 1908,
   "type": "line",
   "text": "The odd bytes of stream_table, from the high byte of the first entry on to $07AA (55 bytes): cartridge bank in the top 3 bits and address bits in the low 5 bits. A zero ends the list of one stream; $08A8,y gives the index where each stream's list begins."
  },
  {
   "address": 1963,
   "type": "line",
   "text": "The raster interrupt that nmi_frame installs on each full-update frame (copy_sprite_shadows, frame_mode 2 or more): handler $07AB/$07AC into $FFFE, line $07AD into $D012. wait_nmi sets irq_panel ($837E) at line $D5, or sprite_reuse_irq ($95A4) at the earliest free sprite line when sprite_more ($6B) is set; round_start sets $BCE1 at line $DE."
  },
  {
   "address": 1964,
   "type": "line",
   "text": "High byte of the handler address of the next raster interrupt (the low byte is raster_vector at $07AB). round_start sets $BCE1 here; wait_nmi sets $837E (irq_panel) or $95A4 (sprite_reuse_irq)."
  },
  {
   "address": 1965,
   "type": "line",
   "text": "Raster line of the next interrupt, which copy_sprite_shadows writes to $D012 each frame: $D5 for irq_panel, $DE after round_start, or the earliest free line of the hardware sprites ($9113) when sprite_more asks for sprite_reuse_irq."
  },
  {
   "address": 1966,
   "type": "line",
   "text": "Value for $D011 that apply_vic_shadows writes each frame: $10 combined with scroll_fine_y ($07), set by build_vic_shadows."
  },
  {
   "address": 1967,
   "type": "line",
   "text": "Value for $D016 that apply_vic_shadows writes each frame: $10 combined with scroll_fine_x ($06) (multicolour text, 38 columns), set by build_vic_shadows."
  },
  {
   "address": 1968,
   "type": "line",
   "text": "Value for $D018 that apply_vic_shadows writes each frame: $21 when the screen buffer in $10 is 0 and $31 when it is 1, set by build_vic_shadows."
  },
  {
   "address": 1969,
   "type": "line",
   "text": "Image of the X high bits ($D010) for the sprites in the tables at $07B4-$07E6."
  },
  {
   "address": 1970,
   "type": "line",
   "text": "Image of the sprite-enable mask ($D015) for the sprites in the tables at $07B4-$07E6."
  },
  {
   "address": 1971,
   "type": "line",
   "text": "Image of the sprite expand mask for the sprites in the tables at $07B4-$07E6. The main loop copies it to $07BE ($818E), and nmi_frame writes that to $D017 and $D01D ($4D7C, $4D7F)."
  },
  {
   "address": 1972,
   "type": "line",
   "text": "Sprite colours of the hardware sprite table (the table's first group: colours, then pointers at $07C7, free-lines at $07CF, and X and Y pairs at $07D7), filled by copy_sprites_to_tables and place_third_sprite."
  },
  {
   "address": 1980,
   "type": "line",
   "text": "Copy of spr_x_msb ($07B1) made by wait_nmi for the interrupt: nmi_frame writes it to $D010 (the X high bits of the eight hardware sprites)."
  },
  {
   "address": 1981,
   "type": "line",
   "text": "Copy of spr_enable ($07B2) made by wait_nmi: nmi_frame writes it to the sprite-enable register $D015."
  },
  {
   "address": 1982,
   "type": "line",
   "text": "Copy of spr_expand ($07B3) made by wait_nmi: nmi_frame writes it to both expand registers $D017 and $D01D."
  },
  {
   "address": 1983,
   "type": "line",
   "text": "Eight bytes, a copy of spr_colour ($07B4) made by wait_nmi: nmi_frame writes them to the sprite colour registers $D027-$D02E."
  },
  {
   "address": 1991,
   "type": "line",
   "text": "Sprite pointer values (shape block numbers) of the hardware sprite table."
  },
  {
   "address": 1999,
   "type": "line",
   "text": "For each slot of the hardware sprite table, a line below the sprite: Y + $16 (Y + $2B for a double-size one) from copy_sprites_to_tables, Y + $15 for slot 0 from place_third_sprite. Probably the line from which the slot can be reused."
  },
  {
   "address": 2000,
   "type": "line",
   "text": "Free line of hardware sprite slot 1 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2001,
   "type": "line",
   "text": "Free line of hardware sprite slot 2 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2002,
   "type": "line",
   "text": "Free line of hardware sprite slot 3 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2003,
   "type": "line",
   "text": "Free line of hardware sprite slot 4 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2004,
   "type": "line",
   "text": "Free line of hardware sprite slot 5 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2005,
   "type": "line",
   "text": "Free line of hardware sprite slot 6 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2006,
   "type": "line",
   "text": "Free line of hardware sprite slot 7 (see spr_free_line at $07CF, which is slot 0): the line below the sprite from which the slot can show another sprite. The routine at $9113 takes the smallest of the eight to choose the raster line of sprite_reuse_irq."
  },
  {
   "address": 2007,
   "type": "line",
   "text": "X and Y of each slot of the hardware sprite table, two bytes per slot (X at the even offsets, Y at the odd ones)."
  },
  {
   "address": 2008,
   "type": "line",
   "text": "Y of slot 0 and the X and Y pairs of slots 1 to 3 of the hardware sprite table (the continuation of spr_xy, $07D7-$07DE). place_third_sprite writes slot 0 when it shows the third sprite; copy_sprites_to_tables writes the others, and slot 0 too when place_third_sprite left it free."
  },
  {
   "address": 2015,
   "type": "line",
   "text": "The X and Y pairs of slots 4 to 7 of the hardware sprite table (the second half of spr_xy, $07DF-$07E6); wait_nmi copies them to $07FF-$0806."
  },
  {
   "address": 2023,
   "type": "line",
   "text": "Eight bytes, a copy of spr_pointer ($07C7) made by wait_nmi: nmi_frame writes them to the sprite pointers at $CBF8 and $CFF8 (both screens)."
  },
  {
   "address": 2031,
   "type": "line",
   "text": "Eight bytes, a copy of spr_free_line ($07CF) made by wait_nmi: nmi_frame copies them to hw_sprite_free_line ($6C-$73)."
  },
  {
   "address": 2039,
   "type": "line",
   "text": "Eight bytes, the X and Y pairs of slots 0 to 3, copied from spr_xy by wait_nmi: nmi_frame writes them to $D000-$D007."
  },
  {
   "address": 2047,
   "type": "line",
   "text": "Eight bytes, the X and Y pairs of slots 4 to 7, copied from spr_xy_b by wait_nmi: nmi_frame writes them to $D008-$D00F. The byte after it, $0807, is the position that sprite_reuse_irq starts from."
  },
  {
   "address": 2055,
   "type": "line",
   "text": "Index minus one at which sprite_reuse_irq starts to walk sprite_overflow_queue: carry_over_sprite_overflow stores $FF, so the walk starts with the first queued sprite."
  },
  {
   "address": 2056,
   "type": "line",
   "text": "Colour of each logical sprite entry (one byte each, up to $16 entries). Bit 7 means the sprite is double size."
  },
  {
   "address": 2080,
   "type": "line",
   "text": "Height in lines of each logical sprite entry: $15 or, with colour bit 7, $2A."
  },
  {
   "address": 2104,
   "type": "line",
   "text": "Sprite pointer value of each logical sprite entry. place_player_sprites puts $FC and $FD here for the player's first two sprites; the third sprite's $FE goes straight into hardware slot 0 (place_third_sprite) and is not in this list."
  },
  {
   "address": 2128,
   "type": "line",
   "text": "X low byte on screen of each logical sprite entry."
  },
  {
   "address": 2152,
   "type": "line",
   "text": "X high byte on screen of each logical sprite entry."
  },
  {
   "address": 2176,
   "type": "line",
   "text": "Y on screen of each logical sprite entry. place_player_sprites adds an entry only for Y $1A to $D3; object_sprites_and_hits adds one for Y below $D5 and not above the object's own limit in $3ABD."
  },
  {
   "address": 2200,
   "type": "line",
   "text": "Frame countdown of the level clock: level_timer_tick counts it down from $19 (25) and ticks the seconds each time it reaches 0. init_round_state sets $19."
  },
  {
   "address": 2201,
   "type": "line",
   "text": "Minutes digit of the level clock, counted down by level_timer_tick; 4 at the start of a round. draw_level_timer shows it at $7FAE, and the clock turns to its warning colour when it is 0 (flash_last_minute_colour)."
  },
  {
   "address": 2202,
   "type": "line",
   "text": "Tens-of-seconds digit of the level clock (3 at the start of a round, so the clock starts at 4:30), counted down from 5 after each minute."
  },
  {
   "address": 2203,
   "type": "line",
   "text": "Units-of-seconds digit of the level clock, counted down from 9."
  },
  {
   "address": 2204,
   "type": "line",
   "text": "Set to 2 by new_game_reset. The untraced code at $4007 counts it down (dec $089C at $400B): while it stays non-negative it goes on at $802B, otherwise back to game_start at $8000. Probably the number of continues left; nothing in the traced code reads it."
  },
  {
   "address": 2205,
   "type": "line",
   "text": "The lives counter as a status-line tile code: $C1 plus the number of lives (the digit tile for 0 is $C1). new_game_defaults sets $C6, the stage intro adds one, the item handler at $A7B9 adds one for every 20 items collected ($08A0), and round_start takes one off at every round, ending the game when the result is below $C1. update_status_line shows it at $7F9A (draw_status_lives)."
  },
  {
   "address": 2206,
   "type": "line",
   "text": "Digit tile (initially $C1, the tile for 0) shown by update_status_line at $7F9C beside the lives; new_game_defaults sets it. It is the tens digit of the items-collected count: the collect-item handler at $A7B9 adds one when $089F wraps, and sets it back to $C1 when the twentieth item adds a life ($A7E5)."
  },
  {
   "address": 2207,
   "type": "line",
   "text": "Digit tile (initially $C1, the tile for 0) shown by update_status_line at $7F9D; the second digit of the pair that starts at $089E."
  },
  {
   "address": 2208,
   "type": "line",
   "text": "Count of items collected towards an extra life. Cleared by new_game_defaults. The item handler at $A7B9 (obj_flags handler 0, not traced) adds one with each item, alongside the digit tiles $089E/$089F; at 20 it adds a life to lives_tile ($089D) and resets the count to 0 and both digits to $C1."
  },
  {
   "address": 2209,
   "type": "line",
   "text": "Value shown by the segment gauge in the status line: track_stage_section takes the low 5 bits of the health of object $08CC into it, and draw_segment_gauge shows it as whole cells (value / 4) and one partial cell. 0 at the start of a round."
  },
  {
   "address": 2210,
   "type": "line",
   "text": "Number of 63-byte pieces left in the current background stream chunk: load_stream_source loads it from the first byte at the chunk's cartridge address, and stream_cartridge_data_to_ram counts it down, moving to the next chunk at 0."
  },
  {
   "address": 2211,
   "type": "line",
   "text": "Index (step 2) into stream_table ($0773) of the chunk being streamed. load_stage_bank_records uses it first as the write position while it builds the table."
  },
  {
   "address": 2212,
   "type": "line",
   "text": "The cartridge bank register value ($87 to $8E) of the chunk being streamed; load_stream_source writes it to $DE00 and here, and stream_cartridge_data_to_ram selects it again for each piece."
  },
  {
   "address": 2213,
   "type": "line",
   "text": "Number added to the destination block of every stream recorded by load_stage_bank_records ($0535): stage_start sets it to $40 before the call. j_0530 copies the sum to $08A6."
  },
  {
   "address": 2214,
   "type": "line",
   "text": "The stream's destination block number plus stream_block_base, which load_stage_bank_records builds at $0538; the record unpacker (b_067E) adds it to a byte of every four-byte sub-entry it copies."
  },
  {
   "address": 2215,
   "type": "line",
   "text": "Number (0 to 3) of the background stream last started: the low two bits of section_scroll_flags. load_section_record compares the bits with it to see whether a new stream must start, and stores the new number here when they differ ($93C1); round_start ($80C5) and the stream loader ($511E) set it too."
  },
  {
   "address": 2216,
   "type": "line",
   "text": "Four bytes: the index into stream_table where the list of each of the four streams begins. stream_cartridge_data_to_ram takes the one for the stream number in Y ($5122) and passes it in X to start_stream_destination. load_stage_bank_records uses $08A8 as a running count while it builds the lists and leaves it 0."
  },
  {
   "address": 2220,
   "type": "line",
   "text": "Four bytes: the destination block number of each of the four streams. start_stream_destination multiplies it by 64 and adds $C000 to get stream_dst."
  },
  {
   "address": 2224,
   "type": "line",
   "text": "Tells nmi_frame what to do this frame: negative leaves at once, 0 blanks the screen (blank_screen_exit), 1 skips the sprite copy (wait_and_set_vic) and 2 or more runs the full update (copy_sprite_shadows). round_start sets 0 while it works and $7F ($80F0) just before the main loop starts; wait_frame sets 1 when a stage is cleared ($81BE); nmi_and_first_copy and the code at $4102 set $FF."
  },
  {
   "address": 2225,
   "type": "line",
   "text": "Non-zero while a timed player effect runs (see player_effect_tick). The item handler at $0BBE (obj_flags handler 2, not traced) sets it to $FF and its timer $08CE to $E0; player_effect_tick clears it when $08CE runs out, and init_round_state clears it."
  },
  {
   "address": 2226,
   "type": "line",
   "text": "Bit 7 flashes at the end of the player effect (see player_effect_tick); player_pose reads it."
  },
  {
   "address": 2227,
   "type": "line",
   "text": "X position of the player's third sprite in the stage (16 bits, high byte at $08B4), set by player_pose from player_x and an offset in the frame record."
  },
  {
   "address": 2228,
   "type": "line",
   "text": "High byte of player_third_x ($08B3)."
  },
  {
   "address": 2229,
   "type": "line",
   "text": "Y position of the player's third sprite in the stage (16 bits, high byte at $08B6), set by player_pose."
  },
  {
   "address": 2230,
   "type": "line",
   "text": "High byte of player_third_y ($08B5)."
  },
  {
   "address": 2231,
   "type": "line",
   "text": "The player's X position in the stage in pixels (16 bits, high byte at $08B8)."
  },
  {
   "address": 2232,
   "type": "line",
   "text": "High byte of player_x ($08B7). Read and written wherever the player's X is used or moved: player_pose, save and restore_player_x, load_start_record, the movement code, the section probe at $930A, the sprite position at $9FC8, object_sprites_and_hits and the saved position code (hit_save_pos)."
  },
  {
   "address": 2233,
   "type": "line",
   "text": "The player's Y position in the stage in pixels (16 bits, high byte at $08BA)."
  },
  {
   "address": 2234,
   "type": "line",
   "text": "High byte of player_y ($08B9). Read and written wherever the player's Y is used or moved: player_pose, save and restore_player_y, load_start_record, the movement code ($9ADC, $9AFC, $9B51, $9B7B), the section probe at $9319, the sprite position at $A016, object_sprites_and_hits and the saved position code (hit_save_y)."
  },
  {
   "address": 2235,
   "type": "line",
   "text": "The player's trial X ($08BC is the high byte): save_player_x copies player_x here, the movement code steps it (move_prev_x_left and _right, the mode 1 steps, ride_left and ride_right), the tile probes test the tiles there, and restore_player_x copies it to player_x when the step is allowed."
  },
  {
   "address": 2236,
   "type": "line",
   "text": "High byte of player_try_x ($08BB)."
  },
  {
   "address": 2237,
   "type": "line",
   "text": "The player's trial Y ($08BE is the high byte): save_player_y copies player_y here, the movement and jump code steps it (move_prev_y_up and _down and others), the tile probes test the tiles there, and restore_player_y copies it to player_y when the move is allowed."
  },
  {
   "address": 2238,
   "type": "line",
   "text": "High byte of player_try_y ($08BD)."
  },
  {
   "address": 2239,
   "type": "line",
   "text": "Low byte of the address of the character screen buffer that is shown (the high byte is in $08C0): 0. draw_screen_from_tile_map draws the whole playfield into the buffer it points to."
  },
  {
   "address": 2240,
   "type": "line",
   "text": "High byte of the shown character screen buffer: $CC when new_game_defaults runs, with $10 at 1. tile_scroll_done swaps it with $08C2 each time the view moves a tile. slot_on_screen adds it to the row offset when it draws shot cells."
  },
  {
   "address": 2241,
   "type": "line",
   "text": "Low byte of the address of the character screen buffer that is being built for the next scroll step (high byte $08C2): 0. The row and column copy routines write into it."
  },
  {
   "address": 2242,
   "type": "line",
   "text": "High byte of the buffer being built: $C8 when new_game_defaults runs; swapped with $08C0 by tile_scroll_done. The draw routines add it to the offsets they compute."
  },
  {
   "address": 2243,
   "type": "line",
   "text": "The stage's background colour 0, copied from $0C03 by stage_setup_tables; apply_vic_shadows writes it to $D021 each frame."
  },
  {
   "address": 2244,
   "type": "line",
   "text": "The stage's background colour 1, copied from $0C04; written to $D022 each frame."
  },
  {
   "address": 2245,
   "type": "line",
   "text": "The stage's background colour 2, copied from $0C05; written to $D023 each frame."
  },
  {
   "address": 2246,
   "type": "line",
   "text": "The fire state of the player. Bit 6 is the fire button copied by update_player (1 means not pressed, 0 pressed) and bit 7 means the player is shooting. In mode 0 player_mode_step sets $40 when fire is not pressed, otherwise $00 while $08FA is non-zero and $80 when it is zero; player_fire also sets $80 when it starts a shot on the ground in mode 0 (a shot in the air or in mode 1 or 2 leaves it). In mode 1 player_mode1_step sets $80 while fire is pressed and $40 otherwise; in mode 2 player_mode2_step keeps only bit 6. While bit 7 is set set_idle_aim ($9F05) is skipped and, in mode 1, the movement handler at $9055 returns at once."
  },
  {
   "address": 2247,
   "type": "line",
   "text": "Bit 0 of the map column of the cell the row copy starts at (0 even, 1 odd): selects the even or odd path of the copy and which half of each 2x2 block is used. The draw routines set it from $1C, and init_round_state clears it."
  },
  {
   "address": 2248,
   "type": "line",
   "text": "Bit 0 of the map row of the cell being copied (0 even, 1 odd): selects the upper or lower pair of characters of each block. Set from scroll_y, scroll_y plus or minus 1, or scroll_y plus $15 (the bottom row) by the row and column copy routines."
  },
  {
   "address": 2249,
   "type": "line",
   "text": "Zeroed by draw_screen_from_tile_map before it starts ($9445); no code in the listing reads it."
  },
  {
   "address": 2250,
   "type": "line",
   "text": "Zeroed by draw_screen_from_tile_map together with $08C9 ($9448); no code in the listing reads it either."
  },
  {
   "address": 2251,
   "type": "line",
   "text": "While non-zero, track_stage_section shows the health of object $08CC in the gauge instead of running update_view_scroll. The low six bits are counted down by slot_blink_timer (on two calls in three, as $0290 cycles), which the main loop calls only while they are non-zero; the top two bits are kept. Its $80 store, for a borrow from 0, is therefore not reached. round_start clears it. Nothing in the listing sets it to a non-zero start value."
  },
  {
   "address": 2252,
   "type": "line",
   "text": "Number of the object that stands for the stage's goal: bit 5 of its obj_state means the stage is cleared (wait_frame), the Commodore-key cheat sets its state to $FF, and its health is what the gauge shows when $08CB is non-zero. store_section_index reads it from the stage data of each section."
  },
  {
   "address": 2253,
   "type": "line",
   "text": "Countdown of the weapon power-up: update_char_block_slots decrements it on every second frame while the weapon level $08E0 is non-zero, and ends the power-up at 0 (level cleared, default weapon record restored)."
  },
  {
   "address": 2254,
   "type": "line",
   "text": "Ticks left in the player effect: player_effect_tick decrements it on every second frame and ends the effect when it reaches zero. Item handler 2 at $0BBE (see obj_flags_handler_lo) starts it at $E0 when it sets player_effect."
  },
  {
   "address": 2255,
   "type": "line",
   "text": "Pixels the view moves in one scroll step. update_view_scroll sets it to 2 on every call, and scroll_up and scroll_down raise it to 4 when the player is $2C or more pixels outside the zone on that side."
  },
  {
   "address": 2256,
   "type": "line",
   "text": "The score: five digit tiles, most significant first, $08D0-$08D4 ($C1 is the digit 0: new_game_defaults fills them with $C1). add_score_points adds an award digit by digit; update_status_line copies them to $7FB9-$7FBD."
  },
  {
   "address": 2257,
   "type": "line",
   "text": "Second digit of the score (see $08D0)."
  },
  {
   "address": 2258,
   "type": "line",
   "text": "Third digit of the score (see $08D0)."
  },
  {
   "address": 2259,
   "type": "line",
   "text": "Fourth digit of the score (see $08D0)."
  },
  {
   "address": 2260,
   "type": "line",
   "text": "Fifth (least significant) digit of the score (see $08D0). The bytes $08D5-$08D9 after it are not used by any code in the listing."
  },
  {
   "address": 2266,
   "type": "line",
   "text": "Low byte of the X position of the last object before a follower that has bit 7 of obj_flags set (the 'leader'): update_objects stores it for followers at $A1A9, and followers add their own offset ($36F4) to it. The high byte is at $08DB."
  },
  {
   "address": 2267,
   "type": "line",
   "text": "High byte of leader_x_lo ($08DA)."
  },
  {
   "address": 2268,
   "type": "line",
   "text": "Low byte of the Y position of the leader object; followers add their own Y offset ($3748) to it. The high byte is at $08DD."
  },
  {
   "address": 2269,
   "type": "line",
   "text": "High byte of leader_y_lo ($08DC)."
  },
  {
   "address": 2270,
   "type": "line",
   "text": "Delay between player shots: update_player counts it down unless bit 7 is set, and player_fire makes a shot only when bit 7 is set, then reloads it from byte $14 of the weapon record."
  },
  {
   "address": 2271,
   "type": "line",
   "text": "Countdown set from byte $15 of the weapon record when a shot is made: while it is not negative and the effect flash (bit 7 of $08B2) is off, player_pose adds 10 to the third sprite's shape (the firing frame) and decrements it. While the flash is on, player_pose adds 20 instead and leaves it alone."
  },
  {
   "address": 2272,
   "type": "line",
   "text": "Level of the weapon power-up: 0 for the default. Below 3 a fire makes one shot (level 1 takes 2 hit points off an object instead of 1); 3 or more makes two shots and plays sound $20. update_char_block_slots clears it when $08CD runs out. Nothing in the listing raises it."
  },
  {
   "address": 2273,
   "type": "line",
   "text": "The CIA 1 column byte of the key that read_keys last acted on, so that a key held down is not read again; it is cleared when no key is found."
  },
  {
   "address": 2274,
   "type": "line",
   "text": "The CIA 1 row select value of the key that read_keys last acted on (see $08E1)."
  },
  {
   "address": 2275,
   "type": "line",
   "text": "Low byte of player_hit_x: the X position where the player was last hit (16 bits with $08E4), which hit_save_pos stores. The stage start is read from the stage record into the same bytes, and find_start_record_loop compares them with the start records to choose where the player restarts."
  },
  {
   "address": 2276,
   "type": "line",
   "text": "High byte of player_hit_x ($08E3)."
  },
  {
   "address": 2277,
   "type": "line",
   "text": "Low byte of player_hit_y: the Y position where the player was last hit (16 bits with $08E6); see $08E3."
  },
  {
   "address": 2278,
   "type": "line",
   "text": "High byte of player_hit_y ($08E5)."
  },
  {
   "address": 2279,
   "type": "line",
   "text": "The stage, 0 to 4: zeroed by game_start, incremented at $81B1 when a stage is cleared."
  },
  {
   "address": 2280,
   "type": "line",
   "text": "Property byte of the map block at the player's head, from player_probe_previous_tiles; air_mode1_check tests its bit 4 before the player can enter mode 1."
  },
  {
   "address": 2281,
   "type": "line",
   "text": "Property byte of the map block at the player's feet, from player_probe_previous_tiles; player_down_enter_mode1 and air_mode1_check test its bit 4."
  },
  {
   "address": 2282,
   "type": "line",
   "text": "Shape number of the player's first sprite. place_player_sprites skips the sprite when it is 0, but copy_sprite_shapes loops on itself at $50BB while it is 0, so 0 would hang it there. Its data is loaded to $FF00 at $50BB; set by $98F3 and player_pose."
  },
  {
   "address": 2283,
   "type": "line",
   "text": "Shape number of the player's second sprite (0 for none), whose data is loaded to $FF40 at $50DC."
  },
  {
   "address": 2284,
   "type": "line",
   "text": "Shape number of the player's third sprite, set by player_pose; its data is loaded to $FF80 at $509C."
  },
  {
   "address": 2285,
   "type": "line",
   "text": "Screen Y of the player's first body sprite (sprite coordinates), from player_sprite_coords after clamp_sprite_y; the sprite is drawn only if it lies from $1A to $D3."
  },
  {
   "address": 2286,
   "type": "line",
   "text": "Screen Y of the player's second body sprite: sprite1_y plus $15, or the same as sprite1_y when $0900 is set (the sprite then lies beside the first)."
  },
  {
   "address": 2287,
   "type": "line",
   "text": "Screen Y of the player's third sprite (the part drawn from player_third_y)."
  },
  {
   "address": 2288,
   "type": "line",
   "text": "Low byte of the screen X of the player's first body sprite (the high byte is at $08F3)."
  },
  {
   "address": 2289,
   "type": "line",
   "text": "Low byte of the screen X of the second body sprite (high byte $08F4): the same as sprite1_x_lo, or $18 more when $0900 is set."
  },
  {
   "address": 2290,
   "type": "line",
   "text": "Low byte of the screen X of the third sprite (high byte $08F5)."
  },
  {
   "address": 2291,
   "type": "line",
   "text": "High byte of the screen X of the first body sprite ($08F0)."
  },
  {
   "address": 2292,
   "type": "line",
   "text": "High byte of the screen X of the second body sprite ($08F1)."
  },
  {
   "address": 2293,
   "type": "line",
   "text": "High byte of the screen X of the third sprite ($08F2)."
  },
  {
   "address": 2294,
   "type": "line",
   "text": "Frame counter: the main loop adds one each time round ($80F9), wait_frame sets it to 0 when a stage is cleared. Its low bits time blinking and flashing, and update_objects uses its low three bits to pick one bit of frame_bits; an object moves in the frames where that bit is set in its own mask in $3484 ($FF every frame, $55 or $AA every other frame, $11, $22, $44 or $88 one frame in four, $42 two frames in eight, $01 one in eight)."
  },
  {
   "address": 2295,
   "type": "line",
   "text": "Set by the frame's interrupt, cleared by the main loop: the main loop runs once for each time it changes."
  },
  {
   "address": 2297,
   "type": "line",
   "text": "Cleared by game_start ($8037). update_player ($8588) increments it, and the background colour ($D021), on every frame that joystick 2 is held up with fire while joystick 1 is held down with fire. While it is non-zero and stage is below 4, read_keys ($5308) answers the Commodore key alone (column 7 reads $DF) by storing $FF in obj_state of the object number in $08CC. The main loop tests bit 5 of that byte after wait_frame ($81A5) and, when it is set, increments stage ($81B1) and goes on to the next stage: a hidden stage skip."
  },
  {
   "address": 2298,
   "type": "line",
   "text": "Vertical state of a jump or fall: 0 on the ground, $FF while rising, 1 while falling (mode1_set_dir_tail starts a fall with 1); $FF is also set when the player is hit and when time runs out. player_jump_motion and its siblings work on player_try_y with it and jump_counter."
  },
  {
   "address": 2299,
   "type": "line",
   "text": "Counter of a jump or fall. While the player rises it holds the rise left: a jump starts it at jump_start_count ($08FC), or from mode 1 at $10, and other rises start it at $30 ($8B3E), $20 ($A5E1), jump_start_count plus $10 ($8FE4-$8FE9), or jump_start_count plus $A0 ($A78B-$A791); each frame player_jump_motion subtracts the $02CE entry it indexes (limited to 16) from it and from player_try_y, and when it would reach 0 the fall begins (jump_state 1, counter 0). While falling it indexes the $02DF table and rises by one up to 8."
  },
  {
   "address": 2300,
   "type": "line",
   "text": "The value that jump_start_state copies to jump_counter when a jump starts: $38 (set by finish_round_setup), the total rise before the fall."
  },
  {
   "address": 2301,
   "type": "line",
   "text": "Scroll mode of the current section, copied from byte $16 of the section record by load_section_record. Read by update_view_scroll: bit 7 clear, the section scrolls horizontally by itself; bit 7 set and bit 6 clear, vertically by itself; both set, the view only follows the player. Bit 5 gives the direction of the automatic scroll (set: right or down, clear: left or up). Bits 0 to 3 run the background stream: bits 0 and 1 are the stream number (compared with stream_current $08A7), bit 2 is set while a stream runs and bit 3 asks for a new one. load_section_record sets them, and stream_cartridge_data_to_ram, load_stream_source and the code at $80C9 test and clear them."
  },
  {
   "address": 2302,
   "type": "line",
   "text": "Edges of the section that the view has reached: bit 0 top, bit 1 bottom, bit 2 left, bit 3 right. update_view_scroll stores the edge when a one-axis scroll toward it has no room left; every scroll step then clears the bit of the opposite edge. load_section_record clears it."
  },
  {
   "address": 2303,
   "type": "line",
   "text": "Non-zero while the player is in a transition between modes: player_fire does nothing, player_mode1_step goes straight to mode1_collide, and player_animate plays the frames at $04E8 and the boxes at $04EC for it, rewriting it as it steps ($9AE8, $9AEF). player_down_enter_mode1 sets $44, mode1_up_end sets 2, and the code at $9AF3 and $9B3D sets $80. mode1_collide clears a negative value; round_start, ground_floor_check, air_mode1_check and $9B8A also clear it."
  },
  {
   "address": 2304,
   "type": "line",
   "text": "Flag from the player's animation tables: non-zero puts the second body sprite 24 pixels to the right of the first, zero puts it 21 lines below (player_sprite_coords); player_pose also uses it to pick the mode 1 records in mode 0. Cleared by player_down_enter_mode1, and by player_animate while the player is hit."
  },
  {
   "address": 2305,
   "type": "line",
   "text": "Hold counter of the player's animation (with $0296 and $0903): player_animate counts it up while the action and facing stay the same and $0903 is 0, and does not count while bit 7 of move_dir $0D is set. It is reset to 0 when the state or facing changes, when $0903 is non-zero, and when it reaches its limit (3, 4 or 6 in the three animation routines, so it cycles). init_round_state clears it; the fire path ($B1E6) sets it to $FF."
  },
  {
   "address": 2306,
   "type": "line",
   "text": "Index of the current frame in the player's animation table: player_animate steps it by 2 and wraps it at the table length; player_pose uses it to pick the third sprite's offsets. player_fire sets $FE when a shot starts on the ground in mode 0 or in mode 1 with $0B non-zero, and 0 or 2 in mode 1 with $0B zero; player_land, init_round_state and $9B8D also set $FE. A negative value takes the first entry."
  },
  {
   "address": 2307,
   "type": "line",
   "text": "Restart request for the player's animation (with $0296 and $0901): while it is non-zero, player_animate restarts the animation, clearing $0901, and clears it. Set by player_fire ($80 on the ground in mode 0, $FE in mode 1 with $0B non-zero), the mode 1 fire code ($FF at $9039), jump_start_state, the code at $8DB3, mode1_up_end (1) and reserve_player_object_slots_loop (8)."
  },
  {
   "address": 2308,
   "type": "line",
   "text": "Top of the saved-background stack cell_save_stack: the index where the next record goes, 0 when the stack is empty. The save routines add 5, 6 or 8; restore_saved_cells pops until it is 0; init_round_state clears it."
  },
  {
   "address": 2309,
   "type": "line",
   "text": "The action number of the player, which player_animate ($98F3) reads together with the facing flag $18. The movement code writes 1, 3, 4, 5, 6 and 7: 4 by player_stop; 5 by mode 1's horizontal movement and by mode 0 code for pressing down, slopes and floors; 6 by mode 1's vertical movement and on entering mode 1; 7 in mode 2; and 3 for jumps and falls."
  },
  {
   "address": 2310,
   "type": "line",
   "text": "Right edge of the follow zone (16 bits, high byte $0907), in the sprite coordinates of player_screen_x. Loaded from bytes 2 and 3 of the section record."
  },
  {
   "address": 2311,
   "type": "line",
   "text": "High byte of zone_right ($0906)."
  },
  {
   "address": 2312,
   "type": "line",
   "text": "Left edge of the zone in which the player can stand without the view following (16 bits, high byte $0909), in the sprite coordinates of player_screen_x. Loaded from bytes 0 and 1 of the section record by load_section_record."
  },
  {
   "address": 2313,
   "type": "line",
   "text": "High byte of zone_left ($0908)."
  },
  {
   "address": 2314,
   "type": "line",
   "text": "Top edge of the follow zone, in the sprite coordinates of player_screen_y. Loaded from byte 4 of the section record."
  },
  {
   "address": 2315,
   "type": "line",
   "text": "Bottom edge of the follow zone, in the sprite coordinates of player_screen_y. Loaded from byte 5 of the section record."
  },
  {
   "address": 2316,
   "type": "line",
   "text": "The A register saved by irq_panel, which it restores before the RTI."
  },
  {
   "address": 2317,
   "type": "line",
   "text": "The X register saved by irq_panel."
  },
  {
   "address": 2318,
   "type": "line",
   "text": "The Y register saved by irq_panel."
  },
  {
   "address": 2319,
   "type": "line",
   "text": "The X register saved by irq_panel_on, which loads it back at the end of the interrupt."
  },
  {
   "address": 2320,
   "type": "line",
   "text": "Number of objects in platform_list ($74): update_objects clears it and counts the objects with bits 3 and 4 of obj_state set; platform_scan_next walks that many entries."
  },
  {
   "address": 2321,
   "type": "line",
   "text": "Set to $FF by init_round_state ($4F21); no code in the listing reads it."
  },
  {
   "address": 2322,
   "type": "line",
   "text": "Set to $FF by init_round_state ($4F24), next to $0911; no code in the listing reads it."
  },
  {
   "address": 2323,
   "type": "line",
   "text": "Non-zero when place_third_sprite shows the third sprite. Written in several places by the player routines."
  },
  {
   "address": 2324,
   "type": "line",
   "text": "Colour of the player's first body sprite; reserve_player_object_slots_loop sets 8 at the start of a round and place_player_sprites puts it in the logical sprite table."
  },
  {
   "address": 2325,
   "type": "line",
   "text": "Colour of the player's second body sprite (8 at the start of a round)."
  },
  {
   "address": 2326,
   "type": "line",
   "text": "Colour of the player's third sprite: 8 at the start of a round; player_pose sets $0E while the effect flash is on. place_third_sprite writes it to hardware sprite slot 0."
  },
  {
   "address": 2327,
   "type": "line",
   "text": "Frame records read by player_pose, $0917-$0A4A. A record begins with the shape number of the third sprite, which is also the index into the hit box tables at $03F7-$0415, followed by four-byte entries: a signed 16-bit X offset and a signed 16-bit Y offset of the third sprite from the player, one entry for each animation frame (picked by anim_frame). The records for mode 1 also hold the body sprite shape numbers at bytes 9 and 10. The pointer tables at $0A4B-$0A9A point into these records. Fixed records are used without a table: $095D (facing right) and $0962 (left) for a player in the air in mode 0, and $0A29 (right) and $0A3A (left) in mode 2."
  },
  {
   "address": 2635,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): low bytes of the addresses of the frame records for a standing player in mode 0 ($0299 = 0, $0900 = 0). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2645,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): high bytes for the standing player (all $09; see pose_still_lo, $0A4B). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2655,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): low bytes of the frame record addresses for the player in mode 0 when stance ($0299) is non-zero ($FF after player_stop or a step with down held, 1 after the mode 1 exit); a 0 entry would make player_pose fall back to a fixed record, but none is 0 (entries 0, 4, 5 and 9 hold $01, with high byte $00). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2665,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): high bytes for mode 0 with stance ($0299) non-zero (see pose_stance_lo, $0A5F); entries 0, 4, 5 and 9 are $00. player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2675,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): low bytes of the frame record addresses in mode 1 when the player moves vertically ($0B = 0). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2685,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): high bytes for mode 1 vertical movement (see pose_vert_lo, $0A73). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2695,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): low bytes of the frame record addresses in mode 1 when the player moves horizontally ($0B non-zero), and in mode 0 when $0900 is non-zero. player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2705,
   "type": "line",
   "text": "Table of 10 bytes indexed by aim_dir ($0297): high bytes for mode 1 horizontal movement (see pose_horiz_lo, $0A87). player_pose reads the pair of tables and puts the address in $E1/$E2."
  },
  {
   "address": 2715,
   "type": "line",
   "text": "Load a set from the cartridge directory: copy entry X, then X+8, X+16 and on, until an entry whose flag bit 5 marks it packed; that one is unpacked in place by bank 0's unpacker at $8DA2, which returns to the caller (an entry with flag bit 7 would end the routine without unpacking; none has it). stage_start passes X from the per-stage table in bank 0 at $8127 ($88, $A0, $B8, $D0, $E8); game_init calls it with $80 and $60."
  },
  {
   "address": 2815,
   "type": "line",
   "text": "Start a stage: bring the cartridge into view ($01 = $37, bank 0), load the stage's set with stage_load, load directory entries 6 and 7, copy a page of bank 13 to $FD00, read the stage's record in bank 5 into $08E3-$08E6, point $3A and $3C at the tables named in the unpacked block's header ($0C1C, $0C1E), then hide the cartridge again."
  },
  {
   "address": 2956,
   "type": "line",
   "text": "Queue sound effect number A: unless $DF is non-zero, and while fewer than three effects are waiting, store it at $91 + $90 and add one to $90. Y is preserved (via $8F). sound_frame plays the queue."
  },
  {
   "address": 3042,
   "type": "line",
   "text": "Once a frame, from irq_panel: unless $DF is set, play each sound effect queued in $91 onward ($90 counts them) through $6633, then run the sound driver at $6787."
  },
  {
   "address": 3062,
   "type": "line",
   "text": "Fills sprite_y_buckets ($7CBD-$7D2C, 112 bytes) with $FF, which marks every position empty. finish_round_setup calls it."
  },
  {
   "address": 3074,
   "type": "line",
   "text": "Byte 1 of the stage block, which is loaded from $0C01 (saved value $38). game_init stores 7 here at $5245 at power-on, when $0C01 onward still holds the start-up stream (directory entries 12-15) it has just unpacked, before it calls the routine at $0C05; the stage block replaces it later. Nothing reads it in play."
  },
  {
   "address": 3075,
   "type": "line",
   "text": "Background colour 0 of the stage ($D021): stage_setup_tables copies this byte to bg_colour0. At power-on game_init also stores $8C here ($524A), into the start-up stream that the stage block later replaces."
  },
  {
   "address": 3076,
   "type": "line",
   "text": "Background colour 1 of the stage ($D022): copied to bg_colour1 by stage_setup_tables. At power-on game_init stores the value of zero-page $E0 here ($524F), into the start-up stream that the stage block later replaces."
  },
  {
   "address": 3077,
   "type": "line",
   "text": "Background colour 2 of the stage ($D023): copied to bg_colour2 by stage_setup_tables. At power-on, before any stage block is loaded, game_init calls a routine of the start-up stream that starts here ($5254)."
  },
  {
   "address": 3078,
   "type": "line",
   "text": "Number of the last section of the stage: track_stage_section stops looking for the next section at this index. init_round_state reads the record of this last section to get its byte $18 into temp_first ($16)."
  },
  {
   "address": 3079,
   "type": "line",
   "text": "Low byte of a pointer (high byte at $0C08) into the cartridge bank 0 to the 64 bytes of stream records that load_stage_bank_records copies to $0100."
  },
  {
   "address": 3080,
   "type": "line",
   "text": "High byte of the pointer at $0C07."
  },
  {
   "address": 3081,
   "type": "line",
   "text": "Low byte of a pointer (high byte at $0C0A) to the list of animation ids of the stage that the helper at $06E6 searches. The list's last index is in $0C0B."
  },
  {
   "address": 3082,
   "type": "line",
   "text": "High byte of the pointer at $0C09."
  },
  {
   "address": 3083,
   "type": "line",
   "text": "Index of the last entry of the list at ($0C09), used as the start of the backward search in the helper at $06E6."
  },
  {
   "address": 3084,
   "type": "line",
   "text": "The 22 bytes $0C0C-$0C21 are the stage's eleven table pointers; stage_setup_tables copies them to $2A-$3F (map_row_lo_ptr, map_row_hi_ptr, block_chars_ptr, block_props_ptr, path_table_ptr, $34, script_ptr_a, script_ptr_b, anim_lo_ptr, anim_hi_ptr and $3E). The values of the saved state are $190E, $1946, $0D32, $197E, $1FD1, $1FD6, $1B34, $1B71, $1AE3, $1AA1 and $1B25."
  },
  {
   "address": 3100,
   "type": "line",
   "text": "Low byte of the word that stage_start copies to anim_lo_ptr ($3A). It is also part of the table at $0C0C that stage_setup_tables copies."
  },
  {
   "address": 3101,
   "type": "line",
   "text": "High byte of the word at $0C1C (anim_lo_ptr)."
  },
  {
   "address": 3102,
   "type": "line",
   "text": "Low byte of the word that stage_start copies to anim_hi_ptr ($3C)."
  },
  {
   "address": 3103,
   "type": "line",
   "text": "High byte of the word at $0C1E (anim_hi_ptr). The bytes $0C20 and $0C21 hold the last pointer, copied to $3E."
  },
  {
   "address": 3106,
   "type": "line",
   "text": "Colour of each character code, 256 bytes, indexed by the character (screen code) found in the screen buffers. recolour_screen copies the entry for every one of the 840 playfield characters into colour RAM. Only the low nibble reaches colour RAM, and a value of 8 or more turns on multicolour for that character, since the playfield runs in multicolour text mode ($D016 bit 4)."
  },
  {
   "address": 3362,
   "type": "line",
   "text": "Table of section record addresses: one word for each section of the stage (eight words, $0D22-$0D31, in the saved state: $19D9, $19F2, $1A0B and on, each 25 bytes on). store_section_index indexes it with section_index times 2, track_stage_section with the next and the previous section's index times 2, and init_round_state with the last section's ($0C06); stage_setup_tables reads the first word through $24. The low byte is here, the high byte at $0D23."
  },
  {
   "address": 3363,
   "type": "line",
   "text": "The high byte of the first section address, then the rest of the table (see section_table). From $0D32 on come the map blocks, four characters each, which block_chars_ptr points to."
  },
  {
   "address": 3378,
   "type": "line",
   "text": "The map block table: four screen characters for each block number (upper left, upper right, lower left, lower right), pointed to by block_chars_ptr ($2E). The first three blocks are blank; most later ones hold runs of consecutive character numbers, but many repeat character $16 or one character or pair, and blocks at $0E66-$0E77 are blank again. The table's length depends on the stage."
  },
  {
   "address": 6470,
   "type": "line",
   "text": "Map row address table, high bytes: 56 entries $1946-$197D, one for each row of the stage map. map_row_hi_ptr ($2C) points here in the saved state and stage_setup_tables copies the pointer from $0C0E. The low bytes are the 56 bytes at $190E; a row starts at hi:lo, so the first rows are $0E9E, $0ECD, $0EFC, 47 bytes (one row of 47 blocks) apart (later rows are 19, 25 or 59 bytes apart: rows differ in length), and the last high byte is $18. Only the first 56 bytes belong to this table; the bytes that follow are block_props_table."
  },
  {
   "address": 6526,
   "type": "line",
   "text": "Map block properties, one byte for each block number: 91 bytes $197E-$19D8 in the saved state, matching the 91 four-character blocks of block_chars ($0D32-$0E9D). block_props_ptr ($30) points here. Bit 0 solid, bit 1 harmful, bits 2 and 3 slopes, bit 5 enter mode 1, as block_property_at and the terrain probes test them. The saved state holds only the values $00, $01, $03, $04, $05, $10, $11, $20 and $30."
  },
  {
   "address": 6617,
   "type": "line",
   "text": "The eight section records of the stage, 25 bytes each, $19D9-$1AA0: section_table ($0D22) holds their addresses ($19D9, $19F2, $1A0B and on, 25 bytes apart). Each record begins with the follow zone (zone_left, zone_right, zone_top, zone_bottom) and the view limits that update_view_scroll reads through section_ptr ($26), and holds the flags byte at offset $16 (section_scroll_flags); the rest of the 25 bytes is not decoded here."
  },
  {
   "address": 6817,
   "type": "line",
   "text": "High bytes of the addresses of the stage's animation data blocks, 66 entries $1AA1-$1AE2 indexed by animation number; anim_hi_ptr ($3C) points here in the saved state. The low bytes are the 66 bytes of anim_lo_table at $1AE3. In the saved state the blocks lie at $20E0-$2876 (high bytes $20 to $28)."
  },
  {
   "address": 6864,
   "type": "line",
   "text": "Entry 47 of anim_hi_table in the saved state ($22: animation 47 is at $220A). stage3_patch writes $C0 here and the type-8 object handler at $A82A writes $60, and each also writes the next byte (entry 48, $1AD1) with $00 or $01, so the pair is a 16-bit value ($00C0 or $0160) rather than two table entries. What reads it is not established."
  },
  {
   "address": 6865,
   "type": "line",
   "text": "Second byte of the pair written with $1AD0: stage3_patch stores $00 here and the object handler at $A82A stores $01 (so the pair is $00C0 or $0160, little-endian). In the saved state it is entry 48 of anim_hi_table ($22)."
  },
  {
   "address": 6883,
   "type": "line",
   "text": "Low bytes of the addresses of the stage's animation data blocks, 66 entries $1AE3-$1B24, indexed by animation number; anim_lo_ptr ($3A) points here. The partner of anim_hi_table. stage3_patch overwrites entries 2 and 3 (at $1AE5 and $1AE6)."
  },
  {
   "address": 6885,
   "type": "line",
   "text": "Entry 2 of anim_lo_table (saved state $F0, giving animation 2 the address $21F0). stage3_patch stores $10 here and $04 in the next byte, $1AE6."
  },
  {
   "address": 6886,
   "type": "line",
   "text": "Entry 3 of anim_lo_table (saved state $FD, animation 3 at $21FD). stage3_patch stores $04 here after $10 in $1AE5. Nothing else in the listing writes or reads it by address."
  },
  {
   "address": 6949,
   "type": "line",
   "text": "Fifteen bytes $1B25-$1B33, the stage's eleventh table, which $3E points to (stored by stage_setup_tables from $0C20): the hit reactions 0 and 1 ($A8FA, $A8D8) replace an object's obj_anim_num with the entry at that index, so it maps an animation number to the animation the object switches to when hit. The saved values are $22 to $37."
  },
  {
   "address": 6964,
   "type": "line",
   "text": "Low bytes of the addresses of the object movement scripts: 61 entries $1B34-$1B70, the table that script_ptr_a ($36) points to. object_script_step loads the pair (script_ptr_a, script_ptr_b) into $E3/$E4 and then reads the script byte at ($E3) + obj_script_pos ($379C,x). The high bytes are script_addr_hi."
  },
  {
   "address": 7025,
   "type": "line",
   "text": "High bytes of the addresses of the object movement scripts: 61 entries $1B71-$1BAD, the table that script_ptr_b ($38) points to; the low bytes are script_addr_lo. In the saved state the scripts lie between $1BAE and $1FD0 (high bytes $1B to $1F)."
  },
  {
   "address": 7086,
   "type": "line",
   "text": "Object movement script bytes, first part, $1BAE-$1FAD (1024 bytes in the saved state). A byte below $80 is a command number: object_script_step looks it up in script_cmd_lo/hi at $B33C/$B35F and runs it; a byte with bit 7 set is a move (low four bits the direction, next byte the repeat count). Three words inside this area are rewritten by the stage patches: $1D08 and $1D0A (stage2_patch, then the handler at $A7F3) and $1D6A (stage2_common)."
  },
  {
   "address": 7432,
   "type": "line",
   "text": "Low byte of a 16-bit word (high byte $1D09) in an object script, probably an X position in pixels. The saved stage 0 bytes are $0B and $FD. stage2_patch stores $00A0 (160) here when section_index is below 2; the type-7 object handler at $A7F3 later stores $0140 (320), at the same moment it clears two map blocks (row pointer entry $13, columns 40 and 41) that stage2_patch had filled with block $36. It reads as a gate that opens; that is inferred."
  },
  {
   "address": 7433,
   "type": "line",
   "text": "High byte of script_word_a: stage2_patch stores $00, the type-7 object handler at $A7F3 stores $01."
  },
  {
   "address": 7434,
   "type": "line",
   "text": "Low byte of a second 16-bit word in the same script (high byte $1D0B), written together with script_word_a: stage2_patch stores $00A0, the type-7 object handler at $A7F3 stores $01F0 (496)."
  },
  {
   "address": 7435,
   "type": "line",
   "text": "High byte of script_word_b ($00 from stage2_patch, $01 from the handler at $A7F3). The script bytes after it, up to $1D69, are not decoded."
  },
  {
   "address": 7530,
   "type": "line",
   "text": "Low byte of a 16-bit word inside another script command (saved value $8724). stage2_patch (through stage2_common) stores $00 here and in $1D6B, for every section of stage 2. What the word controls is not established."
  },
  {
   "address": 7531,
   "type": "line",
   "text": "High byte of script_word_c ($87 in the saved state); stage2_common stores $00. The script bytes that follow, up to $1FAD, are not decoded."
  },
  {
   "address": 8110,
   "type": "line",
   "text": "Object movement script bytes, second part, $1FAE-$1FD0 (35 bytes); see script_data_a for the byte format."
  },
  {
   "address": 8145,
   "type": "line",
   "text": "Table of path data addresses that path_table_ptr ($32) points to, indexed by obj_arc_state: the bytes $1FD2-$1FDD hold six words, $1FDE, $201F, $2040, $2070, $20B0 and $2098. $1FD1 itself is $07 in the saved state. The pointer at $34 (copy of $0C16) is $1FD6, so the last four words are also the table that script command 22 ($B722) reads through ($34) at $B72D to find the record of an object it sets up; whether those four are also paths is not established."
  },
  {
   "address": 8158,
   "type": "line",
   "text": "Path data read by path_advance, from $1FDE: signed 16-bit words (low byte first) that are added to an object's X or Y position, step by step; a low byte of $80 sends the path back to its start. The first path ($1FDE-$201E) steps -2 four times, -1 three times, 0 twice, 1 three times, 2 eight times, then the same back down, an arc. From $2040 the area also holds the object records that script command 22 finds through ($34) ($2040, $2070, $2098, $20B0), so where the path data ends is not established. The saved state is the first stage; stage1_patch rewrites bytes $2018-$201A."
  },
  {
   "address": 8216,
   "type": "line",
   "text": "Low byte of a path data word ($2018-$2019). stage1_patch stores $00 here and in $201A and copies the byte at $202E into $2019, so in stage 1 the word at $2018 reads zero when $202E holds 0, as it does in the saved state. The saved stage 0 holds $FE, $FF, which is a step of -2."
  },
  {
   "address": 8217,
   "type": "line",
   "text": "High byte of the word at $2018. stage1_patch first loads it from $202E (saved value $00) and then, in the same routine, stores $00 at $2018 and $201A."
  },
  {
   "address": 8218,
   "type": "line",
   "text": "Byte $201A of the path data: stage1_patch stores $00 here (saved value $FE, the low byte of a -2 step)."
  },
  {
   "address": 8219,
   "type": "line",
   "text": "Byte of the path data read by stage1_patch and copied to $2E87 (saved value $FF). It is the high byte of a -2 step in the saved state."
  },
  {
   "address": 8238,
   "type": "line",
   "text": "Byte of the path data read by stage1_patch and copied to $2019 (saved value $00)."
  },
  {
   "address": 8384,
   "type": "line",
   "text": "Thirty-two bytes, the pixel rows of four characters (eight bytes each). When the stage is 0, patch_stage_code copies them to $C780-$C79F, which are the shapes of characters $F0 to $F3 in the character set at $C000, unless bit 5 of $35A8 is set, in which case it fills $C780-$C79F with $00 instead. Other stages leave $C780 as loaded."
  },
  {
   "address": 8510,
   "type": "line",
   "text": "Last (ninth) byte of the nine-byte frame record at $2136, the first frame of animation 13 ($2117): the saved state holds $BC, which patch_stage_code writes for stage 0 (it also writes $C1 to $2150). The same byte of the neighbouring records ($212D, $213F) holds $54 and $53, so it looks like a shape number (inferred)."
  },
  {
   "address": 8528,
   "type": "line",
   "text": "Last (ninth) byte of the frame record at $2148, which animation 12 ($2122) uses for its second and third frames; set to $C1 by patch_stage_code for stage 0 (with $BC at $213E). Looks like a shape number (inferred)."
  },
  {
   "address": 11570,
   "type": "line",
   "text": "One byte in the data block at $2D00-$2D4F, which looks like pairs of nibbles. stage1_patch stores $08 here (saved value $EB, the stage 0 byte). No routine in the listing reads it by address."
  },
  {
   "address": 11911,
   "type": "line",
   "text": "One byte inside a run of $55/$AA patterned bytes. stage1_patch copies the byte at $201B into it (saved value $55). No routine in the listing reads it by address."
  },
  {
   "address": 12490,
   "type": "line",
   "text": "A byte of a patterned data area at $30C0 that falls into 8-byte groups. stage2_tail stores $B7 here, $BC at $30D6 and $BD at $30DA (saved values $55, $02 and $55). No routine in the listing reads them by address; what they are is not established."
  },
  {
   "address": 12502,
   "type": "line",
   "text": "Byte patched to $BC by stage2_tail (saved value $02); see stage_data_30CA."
  },
  {
   "address": 12506,
   "type": "line",
   "text": "Byte patched to $BD by stage2_tail (saved value $55); see stage_data_30CA."
  },
  {
   "address": 12922,
   "type": "line",
   "text": "Hit points in the low five bits; the top three bits are kept when hit points are taken off, and the byte goes to add_score_points, whose top two bits choose the award class. Player shots take 1 hit point off (2 at weapon_level 1, $A707-$A71A), and the player landing on the object from a jump takes 2 off ($A5F9-$A60B, when bit 4 of obj_kind is set); see object_sprites_and_hits. track_stage_section shows the low five bits of object $08CC in gauge_value."
  },
  {
   "address": 13006,
   "type": "line",
   "text": "Motion byte of each stage object, chosen in update_objects ($A283). $00-$7F: number of a movement script (index into the script address tables at $36/$38), run by object_script_step ($B207) with the position in obj_script_pos; unless that leaves bit 1 or 5 of obj_state set, the $B1F7 table handlers then run as below. $FF: update_objects clears obj_flags (sets it to 1 on landing) and skips the table handlers. Any other negative value (for example $FE): no script; the $B1F7 table handlers run when bit 5 of obj_flags is set and bit 3 of obj_state is clear. object_arc_step runs first for any object whose arc state is non-zero. Written by the phase handlers ($A9B9 copies obj_off_y, $A9FA and $AA45 write 2 and 1, $AB2B $FE), the hit handlers $A8E8 and $A904, script commands ($B87F, $BCF7 storing $FE, $BD2C swapping it with $3322), object_walk_land_stop ($B4BD, 0) and the swap at $4C9D; initial values come from the stage data (not traced)."
  },
  {
   "address": 13090,
   "type": "line",
   "text": "Second motion byte. The trigger code at $4C9D swaps it with obj_motion and also saves the script position and repeat count in $3844 and $3898, so the object switches to the other motion when the player comes near (table handlers 0, 2 and 13 jump there, and script command 13 calls it); script command 14 ($BD22) swaps the two as well. Phase 5 objects ($A9EC) instead read it as a saved Y position, low byte, and copy it into obj_y_lo, and destroy routine 1 ($A841) copies it into weapon_level; the uses suit different kinds of object. Initial value comes from the stage data (not traced)."
  },
  {
   "address": 13174,
   "type": "line",
   "text": "Motion byte that replaces obj_motion when the object is hit by the type 1 or 2 reaction ($A8E5) or when a movement script reaches the command at $B86F, which also sets bit 7 of obj_kind and obj_move_bits to $FF. Phase 5 objects ($A9F2) read it as a saved Y position, high byte, and copy it into obj_y_hi. Initial value comes from the stage data (not traced)."
  },
  {
   "address": 13258,
   "type": "line",
   "text": "Animation number of each object: the index into the tables that the pointers $3A and $3C (low and high bytes) point to, which give the address of its animation block; obj_anim_index picks the frame within the block. The hit reactions 0 and 1 replace it through anim_swap_table ($3E), and script command 22 sets it from an object record."
  },
  {
   "address": 13351,
   "type": "line",
   "text": "Behaviour phase of each object, a small number dispatched by object_phase_dispatch ($A990): 0 and 6 or more apply obj_dir and obj_speed, 1 nudges Y, 2 counts a flag down, 3 starts an arc, 4 waits for bit 7 of obj_flags then returns to 0, 5 runs sub-states in obj_off_x. It is also the contact class in object_sprites_and_hits ($A731, $A56A): 0 runs the destroy routine at $A7A1, 1 goes to $A5B2, 2 or more go to $A74E; below 2 the object is tested against the player's second hit box first. The pool setup at $5066 gives every temporary object phase 1. Initial values of stage objects come from the stage data (not traced)."
  },
  {
   "address": 13444,
   "type": "line",
   "text": "Bit mask of the frames in which the object moves: an object moves when it shares a bit with move_mask."
  },
  {
   "address": 13537,
   "type": "line",
   "text": "Step size of each object in pixels (low byte, unsigned). apply_object_direction/step_object_by_script and the move_object_* routines add or subtract it on the object's X or Y per step, and diagonal moves move X twice as far. The walking handlers ($B5D5) use it as the sideways step, and phase handlers copy it into $0295 so a rider is carried the same distance. Set by the script command at $B85D (next script byte), by phase2_wiggle_y (1) and the stage data."
  },
  {
   "address": 13621,
   "type": "line",
   "text": "Animation delay reload value. advance_object_animation ($B57A) counts obj_anim_timer down and, when it passes zero, reloads it from here and steps obj_anim_index. Set to 1 when a pool object turns into its short animation ($8508) and, for spawned pool objects, to the same value as the timer ($B77C, from the spawn record)."
  },
  {
   "address": 13714,
   "type": "line",
   "text": "State bits of each object (stage objects and the temporary pool share the tables). Bit 7 ($80): off screen, not drawn. Bit 6 ($40): set when the object is in the view, but update_objects also sets it, with bit 7, for an object above or below the view. Bit 5 ($20): retired. Bit 1 ($02) makes update_objects skip an object on frames it does not move. Bit 3 ($08) and bit 2 ($04) are tested in update_temp_objects; $FF marks an unused slot."
  },
  {
   "address": 13807,
   "type": "line",
   "text": "Object kind and flag bits. Low four bits: reaction type used by $A88E when a player shot or the player destroys the object (0-9, table at $A87A). Bit 7: for a pool object, makes it blink (see update_temp_objects); for a stage object, set by the trigger at $4C9D, by script command 6 ($B86F) and by the hit handlers, which also clear bits 4 and 5 at $A91D; script command 14 ($BD1A) clears it. Bit 6: object not drawn and not hit (object_sprites_and_hits tests it; the blink sets it on alternate frames; phase 5 clears and sets it, $A124 does so for object $08CC, script command 20 toggles it). Bit 5: the object can be hit by the player's shots (the six shot slots at $06DD). Bit 4: the player can land on it from a jump and take 2 hit points off ($A5BB); when it is clear, that contact hits the player ($A630)."
  },
  {
   "address": 13899,
   "type": "line",
   "text": "Not an array of its own: this is one byte before obj_flags ($364C), so $364B,x is obj_flags of slot x-1. For an object whose obj_motion is $FF, update_objects clears its obj_flags ($A28E); when it is falling (bit 6 of obj_arc_state) and lands level with slot x-1 ($39A5,x is obj_y_lo of slot x-1), it sets the flags of slot x to 1, clears its arc state and the flags of slot x-1 ($A2AF), and toggles bit 0 of obj_anim_index of slot x-1 ($3EBB,x). Reads as a pair of linked slots (a child object at x and its parent at x-1); that reading is inferred."
  },
  {
   "address": 13900,
   "type": "line",
   "text": "Flags of each object. Bit 7: a parent whose position followers take. Bit 6: a follower. Bit 4: retire when leaving the view. Bit 5 is tested before calling $B1F7. When an object is destroyed (code at $A7A1), the low four bits choose a routine from the tables at $A868 and $A871."
  },
  {
   "address": 13901,
   "type": "line",
   "text": "Not an array of its own: one byte after obj_flags ($364C), so $364D,x is obj_flags of slot x+1. The contact code at $A74E tests it. When non-zero it queues sound $10, sets stance ($0299) to 0, jump_state ($08FA) to $FF, jump_counter ($08FB) to $A0 plus jump_start_count and player_action ($0905) to 3, and clears $364D,x again ($A796) (inferred: the player bounces). When zero, and only if jump_state is positive and non-zero, bit 1 of move_dir ($0D) is clear and obj_flags of slot x is zero, it sets obj_flags,x to 1, toggles bit 0 of obj_anim_index,x and starts a rise in slot x+1 (see $3F1A). That the slots x and x+1 are a linked pair is inferred."
  },
  {
   "address": 13984,
   "type": "line",
   "text": "Direction of each object in the low four bits, in the joystick pattern: $0B left, $07 right, $0E up, $0D down, $06 up-right, $05 down-right, $09 down-left, $0A up-left. Written by apply_object_direction (step_object_by_script) from the script byte, by the phase 2 handlers ($0E, $0D) and by the walking code at $B5FE. Read by apply_dir_and_speed, which hands it to the player as $19 when the object carries the player, and by the walking code at $B5D5: bit 2 clear is a left direction; bit 2 and bit 3 both set (up or down) make it return without moving; otherwise bit 3 set moves left (speed subtracted at $B616) and clear moves right. XOR $0C turns the object round at a ledge or wall."
  },
  {
   "address": 14068,
   "type": "line",
   "text": "For a follower (bit 6 of obj_flags set), its X offset from the leader (signed byte): position minus leader_x_lo, stored at $8935 and $B24C, added back to leader_x at $A1E0. Other objects reuse the byte: object_run_script_handler ($B1F7) takes it as the index of its handler in script_cmd2, the phase 5 and phase 3 handlers ($A9C2, $AA61) keep a sub-state in it (counted up with inc, reset at $AA15), and phase1_pull_back_y ($AB69) compares obj_y_lo with it as a lower limit."
  },
  {
   "address": 14152,
   "type": "line",
   "text": "For a follower (bit 6 of obj_flags set), its Y offset from the leader (signed byte): position minus leader_y_lo, stored at $893E and $B255, added back to leader_y at $A200. Other objects reuse the byte: the phase 5 handlers count it down as a timer ($A9CF, $A9FE, $AA23; reloaded with $0E, $07 and $4B), phase4_wait_flag7 ($A9B6) copies it to obj_motion, and phase3_land_check ($AA93) compares it with obj_y divided by 16."
  },
  {
   "address": 14236,
   "type": "line",
   "text": "Position of each object in its movement script (offset into the script bytes found through the pointers $36/$38 and obj_motion). object_script_step ($B207) reads the byte there: below $80 a command, run through $88AF; $80 and above a move. It is advanced when a command or move finishes ($B22A, $B236) and by script command 13 ($B6F1) just before that command calls the trigger at $4C9D, which saves it in $3844 and clears it; $BD40 puts the saved value back and resumes the script. Set to 0 when an object is spawned ($4D09, $B69D) and by the hit handlers at $A91D ($A934)."
  },
  {
   "address": 14320,
   "type": "line",
   "text": "Repeat counter of the current move in the object's movement script. step_object_by_script ($B259) loads it from the byte after the direction byte, with bit 7 set to mark it loaded, counts it down once per step and moves on to the next script byte when it underflows. Script command 5 ($0BA0) keeps its own count in it the same way. Zeroed when a command or move finishes ($B22F), when an object is spawned ($4D0C, $B6A0) and by the hit handlers at $A91D; the trigger at $4C9D saves it in $3898 and zeroes it, and $BD3A puts it back."
  },
  {
   "address": 14572,
   "type": "line",
   "text": "X position in the stage of each object, low byte (high byte in obj_x_hi)."
  },
  {
   "address": 14612,
   "type": "line",
   "text": "Entry 40 of obj_x_lo (X low byte of object 40; the arrays hold 93 objects, $38EC-$3948). stage2_common stores $54 here when section_index is 6 or more (saved value $CC); object 41's entry, $3915, gets $34."
  },
  {
   "address": 14613,
   "type": "line",
   "text": "Entry 41 of obj_x_lo, the X low byte of object 41: $34 from stage2_common for stage 2 from section 6 on (saved value $D8). It is the first of the entries up to $3948, the end of obj_x_lo."
  },
  {
   "address": 14665,
   "type": "line",
   "text": "X position in the stage of each object, high byte."
  },
  {
   "address": 14757,
   "type": "line",
   "text": "Not an array of its own: one byte before obj_y_lo ($39A6), so $39A5,x is obj_y_lo of slot x-1. Compared with $E9 in the landing test at $A29A."
  },
  {
   "address": 14758,
   "type": "line",
   "text": "Y position in the stage of each object, low byte (high byte in obj_y_hi)."
  },
  {
   "address": 14851,
   "type": "line",
   "text": "Y position in the stage of each object, high byte."
  },
  {
   "address": 14944,
   "type": "line",
   "text": "Frame countdown of each object's animation. advance_object_animation ($B57A) decrements it while bit 0 of obj_state is set; when it goes below zero it is reloaded from obj_anim_delay and obj_anim_index goes up. Set to $FF when an object is spawned ($4D11, $B6A8) and by the type 2 hit handler ($A8F5); set to obj_anim_delay by the spawner at $B77F and to obj_anim_delay plus 1 by script command 12 ($B833); cleared when a pool object becomes a short animation ($8510)."
  },
  {
   "address": 15037,
   "type": "line",
   "text": "Smallest screen Y at which a sprite part of the object may be drawn: object_sprites_and_hits ($A4A8) skips parts below it, and also parts at $D5 or beyond. Set by $B5CD to $38 minus byte 4 of the animation data block (carry not set explicitly, so the value may be one lower; its meaning as a height is inferred)."
  },
  {
   "address": 15130,
   "type": "line",
   "text": "Pointer to the data of the object's current animation step, low byte (high byte obj_frame_ptr_hi), set by $B5BC from the animation block at offset 5 plus twice obj_anim_index. The data starts with the hit box offsets that set_object_hitbox adds to the position (left, top, right, bottom), then byte 4 is the part count and the sprite parts follow; object_sprites_and_hits walks the parts."
  },
  {
   "address": 15223,
   "type": "line",
   "text": "High byte of the pointer to the data of the object's current animation step (low byte obj_frame_ptr_lo)."
  },
  {
   "address": 15316,
   "type": "line",
   "text": "Left edge of each object's hit box, low byte (high byte at $3C31). Right $3C8E/$3CEB, top $3D48/$3DA5, bottom $3E02/$3E5F; set by set_object_hitbox."
  },
  {
   "address": 15409,
   "type": "line",
   "text": "Left edge of each object's hit box, high byte (low byte obj_hit_left_lo). Set by set_object_hitbox, and to $3E by the spawner at $B801 (with obj_hit_top_hi), which keeps a new object's box out of reach until set_object_hitbox runs (inferred). Read by the shot and player contact tests."
  },
  {
   "address": 15502,
   "type": "line",
   "text": "Right edge of each object's hit box, low byte (high byte at $3CEB)."
  },
  {
   "address": 15595,
   "type": "line",
   "text": "Right edge of each object's hit box, high byte (low byte obj_hit_right_lo). Set by set_object_hitbox."
  },
  {
   "address": 15688,
   "type": "line",
   "text": "Top edge of each object's hit box, low byte (high byte at $3DA5)."
  },
  {
   "address": 15781,
   "type": "line",
   "text": "Top edge of each object's hit box, high byte (low byte obj_hit_top_lo). Set by set_object_hitbox, and to $3E by the spawner at $B804 (with obj_hit_left_hi at $B801)."
  },
  {
   "address": 15874,
   "type": "line",
   "text": "Bottom edge of each object's hit box, low byte (high byte at $3E5F)."
  },
  {
   "address": 15967,
   "type": "line",
   "text": "Bottom edge of each object's hit box, high byte (low byte obj_hit_bottom_lo). Set by set_object_hitbox."
  },
  {
   "address": 16059,
   "type": "line",
   "text": "Not an array of its own: one byte before obj_anim_index ($3EBC), so $3EBB,x is obj_anim_index of slot x-1. $A2A4 toggles its bit 0 when the object in slot x lands (inferred: flips the facing or frame of a linked parent)."
  },
  {
   "address": 16060,
   "type": "line",
   "text": "Index of the object's current step in its animation (frame sequence of the animation block selected by obj_frame). advance_object_animation ($B57A) adds 1 each time obj_anim_timer runs out and wraps to 0 at the count in byte 0 of the block; script command 9 ($B838) steps it the same way and stores it at $B853. $B5B5 stores it and loads obj_frame_ptr and obj_draw_min_y for it. Cleared by script command 12 ($B824) when it selects a new animation, by the hit handlers at $A91D ($A93A), by the spawners at $B6A3 and $B7A5 and when a pool object becomes a short animation ($850D); bit 0 is toggled at $A76D and $A2A4 (the latter through $3EBB, the entry of slot x-1)."
  },
  {
   "address": 16153,
   "type": "line",
   "text": "Motion state of each object for object_arc_step: 0 is none; with bit 7 set it jumps (bit 6 clear) or falls (bit 6 set); any other non-zero value is an offset into the path data at the pointer $32, and the path move clears it when the path ends."
  },
  {
   "address": 16154,
   "type": "line",
   "text": "Not an array of its own: one byte after obj_arc_state ($3F19), so $3F1A,x is obj_arc_state of slot x+1. $A772 sets it to $80 (start a rise) for slot x+1, with that slot's obj_arc_counter ($3F77) set to $2A, when the contact code at $A74E finds $364D,x zero, jump_state positive and non-zero, bit 1 of move_dir clear and obj_flags of slot x zero (inferred: launches the linked child of the object in slot x)."
  },
  {
   "address": 16246,
   "type": "line",
   "text": "Counter that object_arc_step uses: in a rise or fall (obj_arc_state bit 7 set) it steps through the speed tables jump_rise_steps ($02CE) and jump_fall_steps ($02DF); in a path move it is instead the number of the path, the index path_advance ($894C) uses into the path state at $5C, $60 and $64."
  },
  {
   "address": 16247,
   "type": "line",
   "text": "Not an array of its own: one byte after obj_arc_counter ($3F76), so $3F77,x is obj_arc_counter of slot x+1. $A777 sets it to $2A together with obj_arc_state of slot x+1 ($3F1A), the rise that the contact code at $A74E starts."
  },
  {
   "address": 16339,
   "type": "line",
   "text": "Pool object X velocity, low byte; one byte for each of the nine temporary objects, indexed by the pool number (slot minus temp_first), not by slot. update_temp_objects adds temp_vel_x (this and the next table) to obj_x each frame the object moves. Filled from the spawn record by the spawner at $B7CF, cleared when the object turns into its short animation ($8516)."
  },
  {
   "address": 16348,
   "type": "line",
   "text": "Pool object X velocity, high byte (sign extension of temp_vel_x_lo); added to obj_x_hi with the carry by update_temp_objects. Indexed by pool number. Set at $B7D5, cleared at $8519."
  },
  {
   "address": 16357,
   "type": "line",
   "text": "Pool object Y velocity, low byte; added to obj_y_lo each frame the object moves. Indexed by pool number. Set at $B7DB, cleared at $851C."
  },
  {
   "address": 16366,
   "type": "line",
   "text": "Pool object Y velocity, high byte; added with the carry to obj_y_hi. Indexed by pool number. Set at $B7E1, cleared at $851F."
  },
  {
   "address": 16375,
   "type": "line",
   "text": "Life of each pool object, counted down by one by update_temp_objects on each frame the object moves (set to $18 when one turns into its short animation)."
  },
  {
   "address": 16384,
   "type": "line",
   "text": "Entry reached by jump from round_start ($8078) after store_score_digits when the lives have run out; round_start's comment calls the target the title. Sets the CPU port to $37 (cartridge ROM visible at $8000) and jumps to $8C68. The code at $4007 (also with the port restored to $35) counts $089C down: if it stays non-negative it jumps to $802B inside game_start, otherwise to game_start at $8000. Whether $8C68 returns to $4007 is not traced here."
  },
  {
   "address": 16406,
   "type": "line",
   "text": "Start of the between-stage screen. Clears the page at $FE00, runs the routine at $8C07 with $01 set to $37 (ROM visible; probably unpacks data from $8B27 into $FE00, inferred), then looks at $0294: negative goes to the loop at $4095, positive skips to $407C. When it is zero: if the stage number $08E7 is 5 or more, it switches off the CIA2 timer A interrupt and the screen ($D011), calls $BD5D and restarts the game at game_start. Otherwise it sets $D018 to $31, calls $8E9A and polls read_joystick_ports while bit 4 reads 0, that is until fire is released (at once if it is not held), blanks the screen, bumps $0294, then increments $089D and continues into stage_begin. The $0294 branch and $089D meaning are not established here."
  },
  {
   "address": 16514,
   "type": "line",
   "text": "Reads both joystick ports: writes $7F to $DC00 and $DC01 (CIA 1 ports A/B), reads $DC00 and, if no direction/fire pressed there ($7F), reads $DC01 instead. Returns the port value in A (fire is bit 4, active low). Its one caller is the loop at $4069 in stage_intro_start, which repeats while bit 4 is 0 (AND #$10): it waits for fire to be released."
  },
  {
   "address": 16533,
   "type": "line",
   "text": "Per-frame loop of the pre-round/intro screen. Points the IRQ vector ($FFFE/$FFFF) to irq_panel $837E and the raster line $D012 to $D5, sets sprite X positions in $D000-$D00E (sprites 0 and 2 from player_screen_x $029B with high bit $029C, sprites 1 and 3 at +24, sprites 4-7 at fixed $8C/$A4/$BC/$D4, high bits into $D010), waits for frame_flag $08F7 to change, then increments frame_count $08F6. At $80 frames it enables all sprites ($D015=$FF) and calls $6ED8 with A=$19 (caller of $6ED8); when the count wraps to 0 it increments $0294, turns the display off ($D011=0), sets $08B0=$FF and jumps back to $4044. Entered from $403D when $0294 is negative, and loops back to $4095 each frame otherwise."
  },
  {
   "address": 16658,
   "type": "line",
   "text": "Moves the sort-list entries left over after the eight-sprite limit into a queue at $7E. Returns at once if sprite_more ($6B) is zero. Otherwise it walks the sprite sort list $7CBD from position $6B, skipping empty entries (bit 7 set); each real entry is copied to $7E,Y and the list slot is set to $FF. An entry of $7F ends the walk: the queue gets a closing $FF, that slot and $0807 are set to $FF. Purpose is inferred from the names of the data it touches."
  },
  {
   "address": 16698,
   "type": "line",
   "text": "Choose the player's current animation frame and place the extra parts that depend on it. Depending on player_mode ($09), the facing bit 3 of $18, the animation number $0297, and state flags ($08FA, $0900, $0299, $0B), it finds a frame record (through the pointer tables at $0A4B-$0A91, or the fixed records at $0A29, $0A3A, $095D, and $0962) and then: sets the shape number player_shape_3 ($08EC) from the record's first byte (plus 20 and colour $0E in $0916 while bit 7 of $08B2 is set, otherwise plus 10 while the countdown $08DF is not negative, which it decrements); sets the third sprite's position ($08B3/$08B4 and $08B5/$08B6) to player_x and player_y plus an X and a Y offset from the record (chosen by $0902) and $0322/$0323; and loads the extents $031E-$0321 from the tables at $03F7, $040B, $0401, and $0415 indexed by the record's first byte. In mode 1, with $0B zero and bit 7 of $08C6 set, it also loads player_shape_1 and player_shape_2 ($08EA, $08EB) from bytes 9 and 10 of the record."
  },
  {
   "address": 16966,
   "type": "line",
   "text": "Put the player back at the position saved by save_player_x and save_player_y: Y first (restore_player_y), then X."
  },
  {
   "address": 16969,
   "type": "line",
   "text": "Copy player_try_x ($08BB/$08BC) back to player_x ($08B7/$08B8)."
  },
  {
   "address": 16982,
   "type": "line",
   "text": "Copy player_try_y ($08BD/$08BE) back to player_y ($08B9/$08BA)."
  },
  {
   "address": 16995,
   "type": "line",
   "text": "Save the player's X position ($08B7/$08B8) in player_try_x ($08BB/$08BC)."
  },
  {
   "address": 17008,
   "type": "line",
   "text": "Save the player's Y position ($08B9/$08BA) in player_try_y ($08BD/$08BE)."
  },
  {
   "address": 17021,
   "type": "line",
   "text": "Work out the visible part of the stage in pixels from the scroll position. $40/$41 (view_left) = scroll_x ($1C/$1D, in 8-pixel columns) times 8 plus 7 minus scroll_fine_x ($06); $42/$43 (view_top) = scroll_y ($1E/$1F, in 8-pixel rows) times 8 plus 7 minus scroll_fine_y ($07) (the subtraction at $429F starts with the carry clear, so its 8 acts as 7); $44/$45 (view_right) = view_left + $12F; $46/$47 (view_bottom) = view_top + $9F. Every routine that compares a position with the screen (the object updates, the sprite placement, the hit tests) reads these."
  },
  {
   "address": 17121,
   "type": "line",
   "text": "Moves player_try_x ($08BB/$08BC) left by move_step ($0A), with borrow into the high byte, unless bit 7 of fire_flags ($08C6) is set, in which case it does nothing. Mirror of move_prev_x_right."
  },
  {
   "address": 17144,
   "type": "line",
   "text": "Moves player_prev_x ($08BB/$08BC) right by move_step ($0A), with carry into the high byte, unless bit 7 of fire_flags ($08C6) is set, in which case it does nothing. Called for a step to the right by player_jump_right and walk_right_move (mode 0), by mode2_step_right, mode2_up_right and mode2_down_right, and by mode1_right."
  },
  {
   "address": 17167,
   "type": "line",
   "text": "Subtracts move_step ($0A) from player_try_y ($08BD/$08BE), with borrow into the high byte, unless bit 7 of fire_flags ($08C6) is set. A smaller Y is taken as up (inferred from the scroll direction table, where direction 0 is up)."
  },
  {
   "address": 17190,
   "type": "line",
   "text": "Adds move_step ($0A) to player_try_y ($08BD/$08BE), with carry into the high byte, unless bit 7 of fire_flags ($08C6) is set. Mirror of move_prev_y_up."
  },
  {
   "address": 17213,
   "type": "line",
   "text": "Set the scroll direction $0F to 0 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17222,
   "type": "line",
   "text": "Set the scroll direction $0F to 1 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17231,
   "type": "line",
   "text": "Set the scroll direction $0F to 2 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17240,
   "type": "line",
   "text": "Set the scroll direction $0F to 3 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17249,
   "type": "line",
   "text": "Mark the scroll idle: $0F and scroll_phase $0E both become $FF."
  },
  {
   "address": 17256,
   "type": "line",
   "text": "Set the scroll direction $0F to 4 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17265,
   "type": "line",
   "text": "Set the scroll direction $0F to 5 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17274,
   "type": "line",
   "text": "Set the scroll direction $0F to 6 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17283,
   "type": "line",
   "text": "Set the scroll direction $0F to 7 and scroll_phase $0E to 0, so that the next call of the matching scroll routine starts moving."
  },
  {
   "address": 17307,
   "type": "line",
   "text": "Adds a score award to the five-byte score at $08D0-$08D4. The top two bits of A pick the award class 0-2 (class 3 returns with nothing added). Pointer $4A/$4B comes from the tables at $042E and $0431, and its five bytes are added digit by digit from the last place with carry. A digit reaching $CB wraps by subtracting $0A, leaving the carry set for the next place, so the digits are stored as $C1 plus the digit value (the snapshot's score is five $C1 bytes). The three awards ($02BB, $02C0, $02C5) are 10, 50 and 100. Role as the score is inferred from this arithmetic."
  },
  {
   "address": 17349,
   "type": "line",
   "text": "Copies the 16-bit scroll_y ($1E/$1F) to $22/$23 and stores its low bit in $08C8, then jumps to $43FB. Part of the scroll engine's row setup; the exact use of $22/$23 is not shown in this range (inferred)."
  },
  {
   "address": 17365,
   "type": "line",
   "text": "Same as copy_scroll_y_row but for the row above: stores scroll_y minus 1 (16-bit) in $22/$23, its low bit in $08C8, and jumps to $43FB when no borrow happened."
  },
  {
   "address": 17385,
   "type": "line",
   "text": "Starts the same setup for the row below: loads scroll_y and adds 1. The routine continues past this range, so the rest is not described here."
  },
  {
   "address": 17452,
   "type": "line",
   "text": "Redraws the playfield column just left of the view (map x = scroll_x minus 1, map y low byte = scroll_y plus 1; the carry into the high byte is added to $1F, not to $23, so $23 keeps its old value) into the screen buffer pointed to by $08C1/$08C2, one character column down the screen (21 rows, counter in $E9). Bit 0 of the map x and y positions go to $08C7 and $08C8 and select which half of each 2x2-character block is copied. Map blocks are found through the row pointer tables at ($2A)/($2C) indexed by y/2, then the block number times 4 plus $2E gives the block's characters. Odd-row starts are handed to draw_column_odd_start. Used while the screen scrolls; role inferred from the code."
  },
  {
   "address": 17632,
   "type": "line",
   "text": "Address inside the instruction at $44DE: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 17634,
   "type": "line",
   "text": "Variant of draw_column_left_of_view for a column that starts on the lower half of a map block ($08C8 non-zero). It copies one character of the first block to the top screen row, and one from the block ten rows further down to the row twenty rows below ($E5 plus $320), then sets the remaining row counter $E9 to 18 and rejoins the normal column loop at $448D. The $320 offset is the bottom row of the 21-row playfield; role inferred."
  },
  {
   "address": 17790,
   "type": "line",
   "text": "Entry that sets up a map-row copy at map position ($1C/$1D plus 1, $1E/$1F minus 1): $20/$21 get scroll_x plus 1 with the carry carried into the high byte, $08C7 gets bit 0 of $20, then it sets carry and joins the shared code at $45A6, which derives $22 and $08C8 from scroll_y minus 1. Sibling of draw_row_x_minus1_y_minus1 ($4593), which subtracts instead of adding."
  },
  {
   "address": 17811,
   "type": "line",
   "text": "Entry that sets up a map-row copy at map position ($1C/$1D minus 1, $1E/$1F minus 1): stores the results in $20/$21 and $22/$23, the odd-column and odd-row flags in $08C7 and $08C8, and the destination pointer from $08C1/$08C2 into $E5/$E6, then jumps to map_row_copy_start."
  },
  {
   "address": 17860,
   "type": "line",
   "text": "Entry that sets up a map-row copy at column $1C/$1D and row $1E/$1F plus $15 (21): column flag goes to $08C7, row flag to $08C8, and destination is $08C1/$08C2 plus $0320 in $E5/$E6. Falls through to map_row_copy_start."
  },
  {
   "address": 17876,
   "type": "line",
   "text": "Same as draw_bottom_row_x_plus0 but the column is $1C/$1D plus 1. Reached only from outside this range; the preceding clc and bcc skip past it."
  },
  {
   "address": 17896,
   "type": "line",
   "text": "Same as draw_bottom_row_x_plus0 but the column is $1C/$1D minus 1."
  },
  {
   "address": 17915,
   "type": "line",
   "text": "Common tail of the three bottom-row entries: row = $1E/$1F + $15 into $22/$23 with its low bit in $08C8, and destination = $08C1/$08C2 + $0320 into $E5/$E6."
  },
  {
   "address": 17946,
   "type": "line",
   "text": "Finds the map cell: loads row ($22/$23) shifted right once, uses it as an index into the pointer tables at ($2A) and ($2C) for the row's address, and adds column ($20/$21) shifted right once to get the cell pointer in $E1/$E2. Sets $E9 to $13, then chooses the even path when $08C7 is 0 or the odd path otherwise."
  },
  {
   "address": 18000,
   "type": "line",
   "text": "Even-column path loop: multiplies the cell value by 4, adds the block table base $2E/$2F, adds 2 when $08C8 is set (picks the lower pair of the 4-byte block), then copies two characters to ($E5), advancing $E1/$E2 by 1 and $E5/$E6 by 2 until $E9 underflows after 20 passes (40 characters)."
  },
  {
   "address": 18074,
   "type": "line",
   "text": "Return from the even path."
  },
  {
   "address": 18075,
   "type": "line",
   "text": "Odd-column path: copies only the right-hand character of the first block, then copies the left-hand character of the block 20 cells further on ($14 offset) to destination offset $27, sets $E9 to $12, and jumps into the even loop. Locates the block the same way (cell value times 4 plus $2E/$2F, plus 2 for odd rows)."
  },
  {
   "address": 18188,
   "type": "line",
   "text": "Move the view by one step toward where it should be; called from track_stage_section each frame that $08CB is zero and the player is not hit. First it sets scroll_step to 2. Bits 7 and 6 of section_scroll_flags then choose the mode. Bit 7 clear: auto_scroll_horizontal, which scrolls right (bit 5 set) or left (bit 5 clear) until the section limit, then follows the player vertically. Bit 7 set and bit 6 clear: auto_scroll_vertical, down (bit 5 set) or up, then follows the player horizontally. Both set: follow_player_both. Following means that a player_screen_x or player_screen_y outside the zone makes the view scroll toward that side; inside the zone the scroll goes idle through stop_scroll. A straight follow move that meets a limit stores it in view_pinned_edges and also goes idle; the auto modes store it and go on to follow, and a diagonal move pins an edge without storing it."
  },
  {
   "address": 18198,
   "type": "line",
   "text": "Section that scrolls sideways by itself. With bit 5 of section_scroll_flags set, room_to_scroll_right is asked and the view scrolls right while there is room; otherwise room_to_scroll_left and a scroll left. At the limit the view is pinned (pin_view_right or pin_view_left), view_pinned_edges gets $08 or $04, and the code falls into follow_player_y."
  },
  {
   "address": 18230,
   "type": "line",
   "text": "Follow the player vertically: player_screen_y below zone_top ($090A) scrolls up (try_scroll_up), at or beyond zone_bottom ($090B) scrolls down (try_scroll_down), and inside the zone the scroll stops."
  },
  {
   "address": 18270,
   "type": "line",
   "text": "Bit 7 of section_scroll_flags is set. With bit 6 also set the view follows the player in both axes (follow_player_both). Otherwise the section scrolls vertically by itself: bit 5 set asks room_to_scroll_down and scrolls down while there is room, bit 5 clear asks room_to_scroll_up and scrolls up. At the limit the view is pinned (pin_view_bottom or pin_view_top), view_pinned_edges gets 2 or 1, and the code falls into follow_player_x."
  },
  {
   "address": 18304,
   "type": "line",
   "text": "Follow the player horizontally: player_screen_x beyond zone_right ($0906) scrolls right (try_scroll_right), below zone_left ($0908) scrolls left (try_scroll_left), and inside the zone the scroll stops."
  },
  {
   "address": 18336,
   "type": "line",
   "text": "Follow the player in both axes. The horizontal position is tested first (beyond zone_right, below zone_left, or inside) and then the vertical one (above zone_top, below zone_bottom, or inside). Outside on one axis only gives a straight scroll; outside on both gives a diagonal one through try_up_right, try_up_left, try_down_right, or try_down_left. Inside on both axes stops the scroll."
  },
  {
   "address": 18425,
   "type": "line",
   "text": "Scroll up if room_to_scroll_up allows; otherwise pin the view at the top (pin_view_top), store 1 in view_pinned_edges, and stop the scroll."
  },
  {
   "address": 18444,
   "type": "line",
   "text": "Scroll down if room_to_scroll_down allows; otherwise pin the view at the bottom (pin_view_bottom), store 2 in view_pinned_edges, and stop the scroll."
  },
  {
   "address": 18459,
   "type": "line",
   "text": "Scroll right if room_to_scroll_right allows; otherwise pin the view at the right edge (pin_view_right), store 8 in view_pinned_edges, and stop the scroll."
  },
  {
   "address": 18474,
   "type": "line",
   "text": "Scroll left if room_to_scroll_left allows; otherwise pin the view at the left edge (pin_view_left), store 4 in view_pinned_edges, and stop the scroll."
  },
  {
   "address": 18489,
   "type": "line",
   "text": "The player is above and to the right of the zone. With no room to scroll up the view is pinned at the top and scrolls right only; with no room to scroll right it is pinned at the right edge and scrolls up only; with room on both sides it takes the diagonal scroll_up_right."
  },
  {
   "address": 18514,
   "type": "line",
   "text": "The player is above and to the left of the zone. With no room up the view is pinned at the top and scrolls left only; with no room left it is pinned at the left edge and scrolls up only; with room on both sides it takes scroll_up_left."
  },
  {
   "address": 18539,
   "type": "line",
   "text": "The player is below and to the right of the zone. With no room down the view is pinned at the bottom and scrolls right only; with no room right it is pinned at the right edge and scrolls down only; with room on both sides it takes scroll_down_right."
  },
  {
   "address": 18564,
   "type": "line",
   "text": "The player is below and to the left of the zone. With no room down the view is pinned at the bottom and scrolls left only; with no room left it is pinned at the left edge and scrolls down only; with room on both sides it takes scroll_down_left."
  },
  {
   "address": 18589,
   "type": "line",
   "text": "One step of the view to the right. If the scroll direction $0F is not 2 yet, set_dir_right makes it 2 and the step waits for the next call. The step is skipped while the previous tile's redraw is still too recent: scroll_fine_x scaled by scroll_step (fine_x_steps) has to be above scroll_phase. The step clears the left bit of view_pinned_edges and subtracts scroll_step from scroll_fine_x ($06). When that goes below 0 the value wraps into 0 to 7, scroll_x ($1C) grows by 1, and tile_scroll_done starts the redraw."
  },
  {
   "address": 18656,
   "type": "line",
   "text": "One step of the view to the left, the mirror of scroll_right (direction 6, set_dir_left). It clears the right bit of view_pinned_edges and adds scroll_step to scroll_fine_x ($06); when scroll_fine_x is 7 it first prepares scroll_x minus 1 in $20/$21, and a result of 8 or more wraps into 0 to 7 and stores that value into scroll_x before tile_scroll_done."
  },
  {
   "address": 18737,
   "type": "line",
   "text": "One step of the view up (direction 0, set_dir_up). It waits like scroll_left, sets scroll_step to 4 when the player is $2C or more pixels above zone_top, clears the bottom bit of view_pinned_edges, and adds scroll_step to scroll_fine_y ($07). When scroll_fine_y is 7 it first prepares scroll_y minus 1 in $22/$23, and a result of 8 or more wraps into 0 to 7 and stores that value into scroll_y ($1E) before tile_scroll_done."
  },
  {
   "address": 18832,
   "type": "line",
   "text": "One step of the view down (direction 4, set_dir_down). It waits like scroll_right, sets scroll_step to 4 when the player is $2C or more pixels below zone_bottom, prepares scroll_y plus 1 in $22/$23, clears the top bit of view_pinned_edges, and subtracts scroll_step from scroll_fine_y ($07). Going below 0 wraps the value into 0 to 7 and stores scroll_y plus 1 before tile_scroll_done."
  },
  {
   "address": 18914,
   "type": "line",
   "text": "Diagonal step up and to the right (direction 1). A diagonal only runs when the fine positions are in step, 8 minus scroll_fine_y equal to scroll_fine_x. When they are not, the view scrolls right by itself (scroll_right) until they are. The first instructions work out scroll_x plus $26 and throw the result away."
  },
  {
   "address": 18948,
   "type": "line",
   "text": "The jump at $4A04 to scroll_up; no branch or jump in the code reaches it."
  },
  {
   "address": 18951,
   "type": "line",
   "text": "Jump stub: continues at scroll_right ($489D)."
  },
  {
   "address": 18954,
   "type": "line",
   "text": "The move of the diagonal up and to the right. It keeps only the top and right bits of view_pinned_edges, subtracts scroll_step from scroll_fine_x and adds it to scroll_fine_y. When scroll_fine_x goes below 0 both wrap into 0 to 7, scroll_x grows by 1, scroll_y shrinks by 1 (a subtract with the carry left clear), and tile_scroll_done runs."
  },
  {
   "address": 19032,
   "type": "line",
   "text": "Diagonal step down and to the right (direction 3), allowed when scroll_fine_y equals scroll_fine_x. Otherwise the view scrolls right by itself (scroll_right) until they are equal."
  },
  {
   "address": 19048,
   "type": "line",
   "text": "The jump at $4A68 to scroll_down; no branch or jump in the code reaches it."
  },
  {
   "address": 19051,
   "type": "line",
   "text": "Jump stub: continues at scroll_right ($489D). This is the byte at $4A6B."
  },
  {
   "address": 19054,
   "type": "line",
   "text": "The move of the diagonal down and to the right. It keeps the bottom and right bits of view_pinned_edges, subtracts scroll_step from both fine positions (they stay equal), and when they go below 0 wraps them and adds 1 to both scroll_x and scroll_y before tile_scroll_done."
  },
  {
   "address": 19118,
   "type": "line",
   "text": "Diagonal step down and to the left (direction 5), allowed when 8 minus scroll_fine_y equals scroll_fine_x. Otherwise the view scrolls left by itself (scroll_left) until they are."
  },
  {
   "address": 19143,
   "type": "line",
   "text": "The jump at $4AC7 to scroll_down; no branch or jump in the code reaches it."
  },
  {
   "address": 19146,
   "type": "line",
   "text": "Jump stub: continues at scroll_left ($48E0)."
  },
  {
   "address": 19149,
   "type": "line",
   "text": "The move of the diagonal down and to the left. It keeps the bottom and left bits of view_pinned_edges, subtracts scroll_step from scroll_fine_y and adds it to scroll_fine_x. When scroll_fine_y goes below 0 both wrap into 0 to 7, scroll_x shrinks by 1, scroll_y grows by 1, and tile_scroll_done runs."
  },
  {
   "address": 19234,
   "type": "line",
   "text": "Diagonal step up and to the left (direction 7), allowed when scroll_fine_x equals scroll_fine_y. Otherwise the view scrolls left by itself (scroll_left) until they are equal. The first six instructions are two compares whose branches lead to the next instruction."
  },
  {
   "address": 19262,
   "type": "line",
   "text": "The jump at $4B3E to scroll_up; no branch or jump in the code reaches it."
  },
  {
   "address": 19265,
   "type": "line",
   "text": "Jump stub: continues at scroll_left ($48E0). This is the byte at $4B41."
  },
  {
   "address": 19268,
   "type": "line",
   "text": "The move of the diagonal up and to the left. It keeps the top and left bits of view_pinned_edges and adds scroll_step to both fine positions. When they reach 8 or more both wrap into 0 to 7 and scroll_x and scroll_y shrink by 1 before tile_scroll_done."
  },
  {
   "address": 19338,
   "type": "line",
   "text": "The view has moved by one whole tile. Flip the displayed screen buffer $10 (the old value goes to $11), swap the bytes at $08C0 and $08C2, and set scroll_phase to 1 so that the redraw of the new edge starts (see scroll_phase)."
  },
  {
   "address": 19363,
   "type": "line",
   "text": "Return with the N flag clear when the view can still move right: the largest view_left in the section record (bytes 8 and 9 at ($26)) is above view_left."
  },
  {
   "address": 19376,
   "type": "line",
   "text": "Return with the N flag clear when the view can still move left: view_left is above the smallest view_left in the section record (bytes 6 and 7)."
  },
  {
   "address": 19389,
   "type": "line",
   "text": "Return with the N flag clear when the view can still move down: the largest view_top in the section record (bytes 12 and 13) is above view_top."
  },
  {
   "address": 19402,
   "type": "line",
   "text": "Return with the N flag clear when the view can move up by a whole scroll_step: view_top minus scroll_step is not below the smallest view_top in the section record (bytes 10 and 11)."
  },
  {
   "address": 19435,
   "type": "line",
   "text": "Return scroll_fine_y ($07) divided by 1, 2, or 4 for a scroll_step of 1, 2, or more. The scroll routines compare the value with scroll_phase to decide whether the redraw has got far enough."
  },
  {
   "address": 19439,
   "type": "line",
   "text": "Return scroll_fine_x ($06) divided by 1, 2, or 4 for a scroll_step of 1, 2, or more, for comparison with scroll_phase."
  },
  {
   "address": 19453,
   "type": "line",
   "text": "Pin the view at the top limit: scroll_fine_y becomes 7 and view_top is rounded down to a multiple of 8."
  },
  {
   "address": 19464,
   "type": "line",
   "text": "Pin the view at the bottom limit: scroll_fine_y becomes 7 and view_top is rounded down to a multiple of 8 (the same code as pin_view_top)."
  },
  {
   "address": 19475,
   "type": "line",
   "text": "Pin the view at the left limit: scroll_fine_x becomes 7 and view_left is rounded down to a multiple of 8."
  },
  {
   "address": 19486,
   "type": "line",
   "text": "Pin the view at the right limit: scroll_fine_x becomes 7 and view_left is rounded down to a multiple of 8 (the same code as pin_view_left)."
  },
  {
   "address": 19741,
   "type": "line",
   "text": "NMI/IRQ frame handler (nmi_frame). Saves A and the CPU port ($01), maps I/O in with $01=$35, then reads CIA2 $DD0D: if bit 7 is clear (not an NMI) it jumps to frame_exit $4D42. Otherwise it reads state byte $08B0: negative leaves, 0 goes to blank_screen_exit $4D3D, non-zero saves X and Y in $7C/$7D. A value of 1 skips the sprite copy and goes to wait_and_set_vic $4D9A. A value of 2 or more falls into copy_sprite_shadows $4D47."
  },
  {
   "address": 19756,
   "type": "line",
   "text": "Branch target after the CIA2 check shows an NMI. Loads $08B0 and picks between exit (negative), blank_screen_exit (zero) or the frame update (positive)."
  },
  {
   "address": 19773,
   "type": "line",
   "text": "When $08B0 is 0, writes $57 to VIC $D011 (screen control, ECM on) and falls into frame_exit. No sprite or colour work is done for this frame."
  },
  {
   "address": 19778,
   "type": "line",
   "text": "Common exit of nmi_frame: pulls the saved $01 value and A from the stack and returns with RTI."
  },
  {
   "address": 19783,
   "type": "line",
   "text": "Full frame update, taken when $08B0 is 2 or more. Disables interrupts, then loops X from 7 to 0 copying shadow buffers: $07E7,x to the sprite pointers $CBF8,x and $CFF8,x (both screens), $07EF,x to zero page $6C,x, $07F7,x to $D000,x and $07FF,x to $D008,x (the sprite position registers $D000-$D00F, X and Y alternating) and $07BF,x to sprite colours $D027,x. Then writes the enable mask $07BD to $D015, the X high bits $07BC to $D010 and the expand flags $07BE to both $D017 and $D01D. Sets the next interrupt: $07AB/$07AC (raster_vector) go to $FFFE/$FFFF, line $07AD goes to $D012, and the raster flag in $D019 is acknowledged."
  },
  {
   "address": 19866,
   "type": "line",
   "text": "Reached from nmi_frame when $08B0 is 1, or by falling through from the sprite copy. If $D011 bit 7 (raster line high bit) is clear, it waits in a loop until the raster passes line $FB, so the VIC register writes below happen in the lower border."
  },
  {
   "address": 19878,
   "type": "line",
   "text": "Writes $00 to CIA2 $DD00 (VIC bank 3, $C000-$FFFF), then applies the shadow registers: shadow_d018 $07B0 to $D018, bg_colour0-2 $08C3-$08C5 to $D021-$D023, shadow_d016 $07AF to $D016 and shadow_d011 $07AE to $D011. Increments frame_flag $08F7 so the main loop sees a new frame, restores X and Y from $7C/$7D, restores $01 and A, and returns with RTI."
  },
  {
   "address": 19931,
   "type": "line",
   "text": "Patches game code and data for the current stage ($08E7); called once from round_start at $80A8, after the raster vector is set. Stage 0: sets bytes $213E=$BC and $2150=$C1, sets pointer $48/$49 to $000A, then copies 32 bytes from $20C0 to $C780 unless bit 5 of $35A8 is set, in which case the buffer is cleared. Other stages are handled by the branches below. Returns with RTS."
  },
  {
   "address": 19973,
   "type": "line",
   "text": "Stage 0 with $35A8 bit 5 set: fills the 32 bytes at $C780-$C79F with $00 (Y from $1F down to 0), then returns."
  },
  {
   "address": 19982,
   "type": "line",
   "text": "Stage is not 0: compares it with 1 and goes to stage_not1 $4E34 if different."
  },
  {
   "address": 19986,
   "type": "line",
   "text": "Stage 1: stores $08 at $2D32, sets pointer $48/$49 to $1FC8, copies $201B to $2E87 and $202E to $2019, clears $201A and $2018, then returns."
  },
  {
   "address": 20020,
   "type": "line",
   "text": "Stage is not 1: compares it with 2 and goes to stage_not2 $4EB3 if different."
  },
  {
   "address": 20024,
   "type": "line",
   "text": "Stage 2. When section_index ($0298) is below 2, reads a pointer into $E1/$E2, its low byte from ($2A),$13 and its high byte from ($2C),$13, writes $36 at offsets $28 and $29 of that target, and sets $1D08/$1D0A to $A0 and $1D09/$1D0B to $00. Falls into stage2_common."
  },
  {
   "address": 20066,
   "type": "line",
   "text": "Stage 2 common part: clears bytes $1D6A and $1D6B. If section_index ($0298) is 6 or more, also sets $3914=$54 and $3915=$34."
  },
  {
   "address": 20093,
   "type": "line",
   "text": "Stage 2 end: stores $BD, $B7 and $BC at $30DA, $30CA and $30D6, then initialises a table at $BFFE-$C007 (values $FF, $00, $01, $06, $80 by byte) and returns with RTS."
  },
  {
   "address": 20147,
   "type": "line",
   "text": "Stage is not 2: compares it with 3 and goes to patch_stage_exit $4EDC if different."
  },
  {
   "address": 20151,
   "type": "line",
   "text": "Stage 3: stores $C0 at $1AD0, $00 at $1AD1, $10 at $1AE5, $04 at $1AE6, $19 at $BF22, $01 at $BF24 and $00 at $BF23/$BF25, then falls into the RTS."
  },
  {
   "address": 20188,
   "type": "line",
   "text": "Return point of patch_stage_code (RTS), also reached for stage 4 or higher where nothing is patched."
  },
  {
   "address": 20189,
   "type": "line",
   "text": "Resets per-round state: stores starting values (mostly 0 or $FF, also $19, 4, 3, $FE and 7) into about 30 game variables ($0898-$0913, zero page $06-$1A and $6B, player_effect $08B1, player_hit $0292, jump_state $08FA, view_pinned_edges $08FE), loads the record of the section numbered by $0C06 from table $0D22 to get byte $18 into $16, marks every obj_state $3592-$35E5 as $FF (free), then runs the start-position lookup, spawns objects, and ends by jumping to player_pose $413A."
  },
  {
   "address": 20305,
   "type": "line",
   "text": "Loop: writes $FF into obj_state $3592,x for x = $53 down to 0, freeing 84 object slots."
  },
  {
   "address": 20315,
   "type": "line",
   "text": "Loop: zeroes the six bytes $06DD-$06E2."
  },
  {
   "address": 20357,
   "type": "line",
   "text": "Start of the per-record test: record pointer is $E1/$E2 (from stage tables $8113/$8118, read with bank $80 selected; $85 is then written to the cartridge bank register $DE00 before the records are read). Compares player_hit_x $08E3/$08E4 and player_hit_y $08E5/$08E6 against the record's min and max x and y (bytes 0-7); any miss branches to skip_to_next_start_record."
  },
  {
   "address": 20418,
   "type": "line",
   "text": "Record did not contain the player position: scans forward from byte $11 (past the section byte $10) for a byte with bit 7 set, adds that byte's index plus 1 to $E1/$E2, and retests the next record at find_start_record_loop."
  },
  {
   "address": 20420,
   "type": "line",
   "text": "Loop: advances Y until the byte at ($E1),y has bit 7 set, marking the end of the current record."
  },
  {
   "address": 20439,
   "type": "line",
   "text": "A record matched: copies bytes 8-11 to $1C-$1F, bytes 12-15 to player_x $08B7, player_x_hi $08B8, player_y $08B9, and player_y_hi $08BA, then reads byte 16 as the section index."
  },
  {
   "address": 20494,
   "type": "line",
   "text": "Stores the section index (bit 7 stripped; if bit 7 was set, $09 is first set to 2) into section_index $0298, then loads the section record pointer from table $0D22 into $26/$27 and reads two bytes from ($E9) into $F0 and $08CC."
  },
  {
   "address": 20523,
   "type": "line",
   "text": "Reads the next object-range pair from the matched record (from Y = $11 on): a first byte with bit 7 set ends the list; otherwise X = first index and $E3 = end index, with Y saved in $E4."
  },
  {
   "address": 20536,
   "type": "line",
   "text": "Loop: calls $8000 once for each X from the range start up to (not including) $E3, then restores Y from $E4 and goes back to next_spawn_range."
  },
  {
   "address": 20548,
   "type": "line",
   "text": "After the object ranges: sets $01 to $35, calls load_section_record $936E, sets $28/$29 to $B9C9 and $08FC to $38, and calls $0BF6."
  },
  {
   "address": 20582,
   "type": "line",
   "text": "Loop: sets $17 = $16 + 9, then for nine slots counting down from $17-1 writes $FF to obj_state $3592 and obj_move_bits $3484, and 1 to $3427."
  },
  {
   "address": 20626,
   "type": "line",
   "text": "Runs with interrupts off and $01 = $37 while cartridge bank $8D is selected: copies a 63-byte sprite shape into $FF80 when player_shape_3 $08EC differs from the cached value $02CB (source from tables $9245/$9263), the same for $08EA into $FF00 (cache $02CC, tables $91BF/$9202), and $08EB into $FF40 (cache $02CD); the code then restores bank $80 and $01 = $35. Note a spin loop at $50BB when $08EA is zero, seen in the disassembly."
  },
  {
   "address": 20744,
   "type": "line",
   "text": "Background loader that copies cartridge data into RAM $C000+ in pieces of 63 bytes (the pointers step 64), one per call, so the game never stalls. If section_scroll_flags ($08FD) bits 2-3 are clear it returns. Bit 3 set starts a new stream: it clears the bit, takes the stream number from the low flag bits and begins at the destination. Otherwise it copies the next piece with ROM banked in ($DE00 selects the cartridge bank, $01 flips ROM/RAM), and when the count in $08A2 runs out it moves to the next entry of the stream table, the next segment of the same stream with its own count; a zero entry ends the stream and clears bit 2."
  },
  {
   "address": 20840,
   "type": "line",
   "text": "Sets the RAM destination for a new data stream: the stream's block number ($08AC,y) times 64 plus $C000 goes into pointer $04/$05, then falls into load_stream_source."
  },
  {
   "address": 20877,
   "type": "line",
   "text": "Reads the next stream entry from the table at $0773,x. The high byte gives the cartridge bank (top 3 bits, selects bank via $DE00 and $08A4) and the address in $8000-$9FFF; a zero high byte ends the list (clears flag bit 2 in $08FD and moves to the next entry). The first source byte is the number of pieces to copy (64 bytes apart, 63 copied from each) and is stored in $08A2."
  },
  {
   "address": 20945,
   "type": "line",
   "text": "Common exit of the stream loader: puts cartridge bank 0 back ($DE00 = $80) and restores the normal memory map ($01 = $35, I/O visible), then returns."
  },
  {
   "address": 20955,
   "type": "line",
   "text": "Switches in ROM and I/O ($01 = $37), selects cartridge bank 0 ($DE00 = $80) and calls $8194: with the cartridge in view that runs bank 0's routine there, not the RAM copy enable_frame_nmi (facts.md has stage_load use it to refresh the stack-page routines). It then runs cart_copy for the cartridge directory entries at offsets $40, $48 and $50 (entries 8-10) and restores the normal map ($01 = $35). Called once from $80AE before the per-frame calls in the main code; the entries' destinations are not read here, so what they hold is not claimed."
  },
  {
   "address": 20987,
   "type": "line",
   "text": "First code the game runs from RAM (the hand-over, entry.vsf): clears $C480-$C53F, copies 192 bytes from $FFBF-$FFFE to $44E1-$45A0 and selects bank 13 ($DE00 = $8D). With bank 13 in view it copies three 64-byte blocks into RAM (sprite shapes $3F, $40 and $41): $8000 to $CFC0 with ROM in view ($01 = $37), and $8300 to $D000 and $9282 to $D040 with $01 switched to $00 (all RAM) for each store under I/O and back to $37 for the next read. It then selects bank 0 again, runs stage_load ($0A9B) twice (X = $80, then $60), stores $07, $8C and the byte in $E0 at $0C02-$0C04, calls $0C05, sets $E0 to 9 and copies 59 bytes from $44E1 back to $FFBF-$FFF9."
  },
  {
   "address": 21095,
   "type": "line",
   "text": "Sets the CPU port ($01) to $37, ROM and I/O visible, and returns."
  },
  {
   "address": 21100,
   "type": "line",
   "text": "Sets the CPU port ($01) to $00 and returns. With the data-direction register in $00 this selects the all-RAM view (inferred)."
  },
  {
   "address": 21105,
   "type": "line",
   "text": "Called by game_start ($8003). Disable interrupts, set $08B0 to $FF, point the NMI vector ($FFFA/$FFFB) at nmi_frame ($4D1D), switch the cartridge into view ($01 = $37), call $8194 (with the cartridge in view this runs the cartridge's code there, not the main loop's; facts.md has $0A9B use it to refresh the stack-page routines), copy six cartridge directory entries (0-5, per facts.md) into RAM with cart_copy_six, then hide the cartridge again ($01 = $35)."
  },
  {
   "address": 21136,
   "type": "line",
   "text": "Keyboard matrix scan through CIA 1 ($DC00 rows, $DC01 columns), called from $80FC."
  },
  {
   "address": 23427,
   "type": "line",
   "text": "Draw the strip of the background that a one-tile scroll will bring into view. It does nothing unless scroll_phase ($0E) is zero. It then picks from scroll_dir ($0F: 0 is up, 2 right, 4 down, 6 left, and the odd numbers 1, 3, 5, and 7 are the diagonals between them) the row, the column, or both that are about to appear at the edge of the screen, and fills them into the off-screen character buffer whose address is in $08C1/$08C2. The stage map is read through the row pointer tables $2A and $2C (low and high bytes of each map row's address); each map byte is a tile, expanded to a 2 by 2 block of characters taken from the table at $2E/$2F, with $08C7 and $08C8 choosing which half of the tile the row or column starts in. A row is 40 characters (20 tiles) wide and a column 21 characters tall. The routines at $433D-$438B set $0F and clear $0E, except $4361, which sets both to $FF, as the reset at $4F1D does; $4B8A sets $0E to 1 once a tile step is made, and $888D then counts $0E down."
  },
  {
   "address": 23490,
   "type": "line",
   "text": "Refresh the colour RAM of the 21 playfield rows ($D800-$DB47, 840 characters) so it matches the screen buffer that is now on show. The screen buffer is swapped by the tile step at $4B8A, which flips $10 (0 shows the buffer at $C800, 1 shows $CC00; build_vic_shadows turns that into $D018 $21 or $31). Colour RAM exists only once, so it is rewritten rather than swapped: the tile step sets scroll_phase ($0E) to 1, and the countdown at $888D calls this routine when it sees the old value 1, one frame later. Each character's colour is taken from char_colour_table ($0C22). Reached by the jump at $889B and by the stub at $9517. The copy is unrolled with Y as the index, in four loops: three of 32 characters a pass, each covering a page of 256, and a last one of 72 (36 a pass for $C800, 24 for $CC00): recolour_c800_0 and the loops after it do the $C800 buffer, and recolour_cc00_0 and its loops do the $CC00 buffer."
  },
  {
   "address": 23497,
   "type": "line",
   "text": "Colour-RAM refresh from the screen buffer at $C800, used when $10 is zero. Clears carry for the additions in the loops and starts Y at 0."
  },
  {
   "address": 23500,
   "type": "line",
   "text": "First of 4 copy loops that read the screen buffer at $C800 one character at a time and write each character's colour to colour RAM. Each of the 32 unrolled steps takes the character code from $C800+Y, looks its colour up in char_colour_table ($0C22), and stores it at $D800+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $D800 to $D8FF. When Y wraps it falls into the next page's loop at $5CF6."
  },
  {
   "address": 23798,
   "type": "line",
   "text": "Copy loop 2 of 4 for the screen buffer at $C800. Each of the 32 unrolled steps takes the character code from $C900+Y, looks its colour up in char_colour_table ($0C22), and stores it at $D900+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $D900 to $D9FF. When Y wraps it falls into the next page's loop at $5E20."
  },
  {
   "address": 24096,
   "type": "line",
   "text": "Copy loop 3 of 4 for the screen buffer at $C800. Each of the 32 unrolled steps takes the character code from $CA00+Y, looks its colour up in char_colour_table ($0C22), and stores it at $DA00+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $DA00 to $DAFF. When Y wraps it falls into the next page's loop at $5F4C."
  },
  {
   "address": 24396,
   "type": "line",
   "text": "Copy loop 4 of 4 for the screen buffer at $C800. Each of the 36 unrolled steps takes the character code from $CA48+Y, looks its colour up in char_colour_table ($0C22), and stores it at $DA48+Y. Y then moves on by $24 and the loop repeats until Y wraps past $FF, so it copies 72 characters, from $DB00 to $DB47 (the Y offsets are shifted so the unrolled steps end exactly at the last playfield character). That ends the 21 playfield rows (840 characters, $D800-$DB47); the routine then returns."
  },
  {
   "address": 24730,
   "type": "line",
   "text": "Colour-RAM refresh from the screen buffer at $CC00, used when $10 is non-zero (jumped to from $5BC6). The same four loops as recolour_c800 with the source moved up by $0400, except that the last one is unrolled 24 steps a pass (Y moving on by $18) rather than 36 ($24); clears carry and starts Y at 0."
  },
  {
   "address": 24733,
   "type": "line",
   "text": "First of 4 copy loops that read the screen buffer at $CC00 one character at a time and write each character's colour to colour RAM. Each of the 32 unrolled steps takes the character code from $CC00+Y, looks its colour up in char_colour_table ($0C22), and stores it at $D800+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $D800 to $D8FF. When Y wraps it falls into the next page's loop at $61C7."
  },
  {
   "address": 25031,
   "type": "line",
   "text": "Copy loop 2 of 4 for the screen buffer at $CC00. Each of the 32 unrolled steps takes the character code from $CD00+Y, looks its colour up in char_colour_table ($0C22), and stores it at $D900+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $D900 to $D9FF. When Y wraps it falls into the next page's loop at $62F1."
  },
  {
   "address": 25329,
   "type": "line",
   "text": "Copy loop 3 of 4 for the screen buffer at $CC00. Each of the 32 unrolled steps takes the character code from $CE00+Y, looks its colour up in char_colour_table ($0C22), and stores it at $DA00+Y. Y then moves on by $20 and the loop repeats until Y wraps past $FF, so it copies 256 characters, from $DA00 to $DAFF. When Y wraps it falls into the next page's loop at $641D."
  },
  {
   "address": 25629,
   "type": "line",
   "text": "Copy loop 4 of 4 for the screen buffer at $CC00. Each of the 24 unrolled steps takes the character code from $CE48+Y, looks its colour up in char_colour_table ($0C22), and stores it at $DA48+Y. Y then moves on by $18 and the loop repeats until Y wraps past $FF, so it copies 72 characters, from $DB00 to $DB47 (the Y offsets are shifted so the unrolled steps end exactly at the last playfield character). That ends the 21 playfield rows (840 characters, $D800-$DB47); the routine then returns."
  },
  {
   "address": 25845,
   "type": "line",
   "text": "End of the fourth unrolled colour-RAM loop of the screen recolour: adds $18 to Y; when Y wraps to zero it returns, otherwise it jumps back into the loop at recolour_cc00_3 ($641D). Role inferred from the jump target."
  },
  {
   "address": 25851,
   "type": "line",
   "text": "Jumps back to recolour_cc00_3 ($641D) for the next pass of the loop."
  },
  {
   "address": 25857,
   "type": "line",
   "text": "Mode flag. sound_init sets it to $1F (nonzero); sid_player_init clears it. While it is nonzero, sid_load_song_voices works, update_filter_sweep is held off, and sid_voice_change_check silences a voice whose one-shot sound has run out. While it is zero, sid_load_song_voices does nothing and update_filter_sweep passes this test (it still returns when the voice it finds owning the filter has a one-shot sound active). Which of the two the game means (sound effects against a music player) is inferred from the callers."
  },
  {
   "address": 25858,
   "type": "line",
   "text": "Busy flag. sid_player_init increments it on entry and sid_init_finish clears it at the end; sid_player_update returns at once while it is nonzero, so the per-frame update never runs half way through a re-initialisation."
  },
  {
   "address": 25859,
   "type": "line",
   "text": "Scratch byte. sid_voice_start_change saves the voice number here; script command $81 (the pattern select at $6B52) also uses it as a temporary for the pattern index doubled."
  },
  {
   "address": 25860,
   "type": "line",
   "text": "Scratch byte. sid_voice_start_change saves the one-shot step counter here."
  },
  {
   "address": 25861,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames left in the current note of the voice's script. tick_voice_script counts it down and reads the next script event at zero; the duration byte of each note (voice_store_duration) is stored here. Bytes $6505-$6507. Pattern command 4 also reads it, scheduling the next pattern step that many frames before the note ends (taken to be a gate-off; not proven)."
  },
  {
   "address": 25862,
   "type": "line",
   "text": "Voice 1's byte of voice_script_timer ($6505-$6507). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 2 here (voice 0 gets 1 and voice 2 gets 3), so the voices' timers run out on different frames. sid_reset_voice_state also stores 2 here (Y + 1) for voice 1. The code that indexes voice_script_timer by voice number reads and writes it."
  },
  {
   "address": 25863,
   "type": "line",
   "text": "Voice 2's byte of voice_script_timer ($6505-$6507). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 3 here (voices 0 and 1 get 1 and 2), so the voices' timers run out on different frames. sid_reset_voice_state also stores 3 here (Y + 1) for voice 2. The code that indexes voice_script_timer by voice number reads and writes it."
  },
  {
   "address": 25864,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Saved duration used while the repeat flag voice_repeat_flag is set (script command $87 stores it, $88 clears the flag). Bytes $6508-$650A."
  },
  {
   "address": 25867,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames until the voice's pattern stream (the SID control and envelope writes, read by music_voice_step) is read again. Set to 1 at each new note unless restart-mask bit 2 is set, and loaded by the pattern wait commands. Bytes $650B-$650D."
  },
  {
   "address": 25868,
   "type": "line",
   "text": "Voice 1's byte of voice_pattern_timer ($650B-$650D). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 2 here (voice 0 gets 1 and voice 2 gets 3), so the voices' timers run out on different frames. The code that indexes voice_pattern_timer by voice number reads and writes it."
  },
  {
   "address": 25869,
   "type": "line",
   "text": "Voice 2's byte of voice_pattern_timer ($650B-$650D). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 3 here (voices 0 and 1 get 1 and 2), so the voices' timers run out on different frames. The code that indexes voice_pattern_timer by voice number reads and writes it."
  },
  {
   "address": 25870,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames left in the current step of the voice's pulse-width program (music_voice_pulse_sweep). Bytes $650E-$6510."
  },
  {
   "address": 25871,
   "type": "line",
   "text": "Voice 1's byte of voice_pulse_timer ($650E-$6510). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 2 here (voice 0 gets 1 and voice 2 gets 3), so the voices' timers run out on different frames. The code that indexes voice_pulse_timer by voice number reads and writes it."
  },
  {
   "address": 25872,
   "type": "line",
   "text": "Voice 2's byte of voice_pulse_timer ($650E-$6510). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 3 here (voices 0 and 1 get 1 and 2), so the voices' timers run out on different frames. The code that indexes voice_pulse_timer by voice number reads and writes it."
  },
  {
   "address": 25873,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames left in the current event of the voice's pitch program (music_voice_advance). Bytes $6511-$6513."
  },
  {
   "address": 25874,
   "type": "line",
   "text": "Voice 1's byte of voice_pitch_timer ($6511-$6513). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 2 here (voice 0 gets 1 and voice 2 gets 3), so the voices' timers run out on different frames. The code that indexes voice_pitch_timer by voice number reads and writes it."
  },
  {
   "address": 25875,
   "type": "line",
   "text": "Voice 2's byte of voice_pitch_timer ($6511-$6513). It is not cleared: right after sid_clear_registers_loop, sid_player_init stores 3 here (voices 0 and 1 get 1 and 2), so the voices' timers run out on different frames. The code that indexes voice_pitch_timer by voice number reads and writes it."
  },
  {
   "address": 25876,
   "type": "line",
   "text": "Single byte, not per voice. Frames left in the current step of the filter-cutoff program read from filter_sweep_table by update_filter_sweep. sid_player_init sets it to 1, and a note start resets it to 1 when the voice owns the filter (voice_filter_ctrl nonzero) and restart-mask bit 3 is clear."
  },
  {
   "address": 25877,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Read position in the voice's top-level sequence script (the one pointed to by seq_script_ptr_lo and seq_script_ptr_hi, copied to $F7/$F8 by advance_voice_sequence). Bytes $6515-$6517; $6518-$651A are not used by the code."
  },
  {
   "address": 25883,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low bytes of the three sequence script addresses. sid_player_init fills $651B-$6520 from sid_seq_start_sets. Bytes $651B-$651D; the high bytes are seq_script_ptr_hi."
  },
  {
   "address": 25884,
   "type": "line",
   "text": "Byte written by sid_player_init when a song starts (it copies six bytes to $651B-$6520). Low byte of voice 1's sequence script address (seq_script_ptr_lo), which advance_voice_sequence loads indexed by the voice number."
  },
  {
   "address": 25885,
   "type": "line",
   "text": "Byte written by sid_player_init when a song starts (it copies six bytes to $651B-$6520). Low byte of voice 2's sequence script address (seq_script_ptr_lo), which advance_voice_sequence loads indexed by the voice number."
  },
  {
   "address": 25886,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High bytes of the three sequence script addresses (low bytes in seq_script_ptr_lo). Bytes $651E-$6520."
  },
  {
   "address": 25887,
   "type": "line",
   "text": "Byte written by sid_player_init when a song starts (it copies six bytes to $651B-$6520). High byte of voice 1's sequence script address (seq_script_ptr_hi), which advance_voice_sequence loads indexed by the voice number."
  },
  {
   "address": 25888,
   "type": "line",
   "text": "Byte written by sid_player_init when a song starts (it copies six bytes to $651B-$6520). High byte of voice 2's sequence script address (seq_script_ptr_hi, $651E-$6520), which advance_voice_sequence loads with lda $651E,x, X = 2."
  },
  {
   "address": 25889,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the voice's current position in its pattern stream (music_voice_step). Bytes $6521-$6523. Both halves are set to $6602, an idle pattern, at a reset; script command $81 (at $6B52) sets voice_pattern_start to a real pattern, which the next note copies here unless restart-mask bit 2 is set."
  },
  {
   "address": 25892,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the address the pattern stream is restarted from at each new note (copied into voice_pattern_ptr_lo unless restart-mask bit 2 is set). Bytes $6524-$6526."
  },
  {
   "address": 25895,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the current pattern stream position (low byte in voice_pattern_ptr_lo). Bytes $6527-$6529."
  },
  {
   "address": 25898,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the pattern restart address (low byte in voice_pattern_start_lo). Bytes $652A-$652C."
  },
  {
   "address": 25901,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Current byte index into pulse_program_table for the voice's pulse-width program. Bytes $652D-$652F."
  },
  {
   "address": 25904,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Index into pulse_program_table where the pulse-width program starts; script command $82 sets it, and each new note copies it into voice_pulse_index. Cleared to 0 at voice reset. Bytes $6530-$6532."
  },
  {
   "address": 25907,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Chooses the pitch-program table: 0 reads pitch_program_a ($7184), nonzero reads pitch_program_b ($7277). Script commands $83 (sets 0) and $8D (sets nonzero) write it, and pattern command 6 ($6B23) sets it to 0. Bytes $6533-$6535."
  },
  {
   "address": 25910,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Current byte index into the chosen pitch-program table. Bytes $6536-$6538."
  },
  {
   "address": 25913,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Index where the pitch program starts, set by script commands $83 and $8D; each new note copies it to voice_pitch_pos when voice_pitch_enabled is nonzero and restart-mask bit 0 is clear. Bytes $6539-$653B."
  },
  {
   "address": 25916,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the address of the arpeggio note offsets the voice steps through (script command $84; points just after the two-byte header in arp_ptr_table's records). Bytes $653C-$653E; $653F-$6541 are not used."
  },
  {
   "address": 25922,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the arpeggio offsets address (low byte in voice_arp_ptr_lo). Bytes $6542-$6544."
  },
  {
   "address": 25928,
   "type": "line",
   "text": "Single byte. Start index into filter_sweep_table, set by script command $85 (first operand); copied to filter_index at a note start. sid_player_init's voice loop also stores 0 at $6548,x for X = 2 to 0, so it zeroes this byte, filter_index ($6549) and filter_step_lo ($654A); nothing else clears those two."
  },
  {
   "address": 25929,
   "type": "line",
   "text": "Single byte. Current byte index into filter_sweep_table."
  },
  {
   "address": 25930,
   "type": "line",
   "text": "Single byte. Low byte of the 16-bit amount added to the filter accumulator each frame (high byte in $654B). Loaded from filter_sweep_table."
  },
  {
   "address": 25931,
   "type": "line",
   "text": "Single byte. High byte of the filter step; see filter_step_lo."
  },
  {
   "address": 25932,
   "type": "line",
   "text": "Single byte. High byte of the filter accumulator's starting value, set by script command $85 (second operand, stored straight into filter_acc_hi too); copied into filter_acc_hi ($654E) at a note start."
  },
  {
   "address": 25933,
   "type": "line",
   "text": "Single byte. Low byte of the filter accumulator's starting value, set by script command $85 (third operand, stored straight into filter_acc_lo too); copied into filter_acc_lo ($654F) at a note start."
  },
  {
   "address": 25934,
   "type": "line",
   "text": "Single byte. High byte of the filter-cutoff accumulator; only its low three bits reach the SID. update_filter_sweep adds filter_step_hi to it, with the carry from $654F, each time it runs, and writes the value shifted right three times to $D416: bits 0-2 of $654E become the top three bits of $D416, above the top five bits of $654F, whose low three bits go to $D415."
  },
  {
   "address": 25935,
   "type": "line",
   "text": "Single byte. Low byte of the filter-cutoff accumulator (the byte added to first, with carry into $654E)."
  },
  {
   "address": 25936,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the address of the waveform bytes for the voice's one-shot sound, taken from the first two bytes of a record in sid_oneshot_defs. sid_voice_start_change patches it into the operand of its lda at $6E96. Bytes $6550-$6552."
  },
  {
   "address": 25939,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the address of the frequency bytes: waveform address plus the length. Patched into the operand of the lda at $6E88. Bytes $6553-$6555."
  },
  {
   "address": 25942,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the waveform address (low byte in voice_oneshot_wave_lo). Bytes $6556-$6558. dispatch_voice_command's lda $6557,x has $6557 as its base, but its X is the command byte ($80 up), so it reads voice_cmd_table_hi at $65D7, not these bytes."
  },
  {
   "address": 25943,
   "type": "line",
   "text": "Voice 1's and 2's bytes of voice_oneshot_wave_hi ($6556-$6558): script command $86 writes them and sid_voice_start_change reads them, indexed by the voice. dispatch_voice_command's lda $6557,x only uses $6557 as its base: X is the command byte, $80 or more, so it reads voice_cmd_table_hi at $65D7 onward."
  },
  {
   "address": 25945,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the frequency-bytes address (low byte in voice_oneshot_freq_lo). Bytes $6559-$655B."
  },
  {
   "address": 25948,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the address of the voice's note script, loaded from the song-script table at $7C3D by sid_load_song_voices (or $F5 after reset). tick_voice_script copies it to $F5. Bytes $655C-$655E; the high bytes are voice_script_ptr_hi."
  },
  {
   "address": 25951,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the voice's note script address. Bytes $655F-$6561."
  },
  {
   "address": 25954,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the voice's current SID frequency. It is loaded from note_freq_lo, changed by the pitch program, and written to $D400 by sid_write_frequency. Bytes $6562-$6564."
  },
  {
   "address": 25957,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the voice's current SID frequency (from note_freq_hi), written to $D401. Bytes $6565-$6567."
  },
  {
   "address": 25960,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. The voice's current note: the byte read from the note script, an index into note_freq_lo and note_freq_hi. Bytes $6568-$656A."
  },
  {
   "address": 25963,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Sequence script repeat counter. advance_voice_sequence keeps the same phrase playing while it counts down, then moves on; sequence command $F1 sets it. Bytes $656B-$656D."
  },
  {
   "address": 25966,
   "type": "line",
   "text": "Single byte. Offset in the pattern stream (relative to $F5/$F6) while music_voice_step reads one step; added to the stream pointer when the step ends (code at $6B3E)."
  },
  {
   "address": 25967,
   "type": "line",
   "text": "Single byte. SID register offset of the voice being processed: 0, 7 or 14, copied from sid_voice_offsets by sid_update_voice_loop. The per-voice update code adds it to $D400 for its SID writes; sid_load_song_voices and sid_voice_change_check take the offset from sid_voice_offsets directly instead."
  },
  {
   "address": 25968,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Attack/decay value of the voice, set by pattern command 2 and written to $D405. Bytes $6570-$6572 (no symbol existed; $6573 is voice_sustain_release)."
  },
  {
   "address": 25971,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Sustain/release value of the voice, set by pattern command 2 and written to $D406. Bytes $6573-$6575."
  },
  {
   "address": 25974,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Nonzero while the voice has a pitch program running. Script commands $83 and $8D, and pattern command 6, set it; music_voice_advance does nothing while it is zero. Bytes $6576-$6578."
  },
  {
   "address": 25977,
   "type": "line",
   "text": "Three bytes, one per voice ($6579-$657B). Only sid_init_voice_loop and sid_reset_voice_state write them, both storing zero, and no instruction reads them (no base reaches them with an index of 0 to 2), so the array is unused."
  },
  {
   "address": 25980,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Nonzero while the voice plays an arpeggio (script command $84). While it is set, sid_voice_run skips the plain frequency lookup because the arpeggio writes the frequency itself. Bytes $657C-$657E. The neighbouring array $6579-$657B is only ever cleared."
  },
  {
   "address": 25983,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Nonzero for the voice that owns the SID filter: it holds the value script command $85 wrote to $D417 (resonance and filter routing). The command clears all three before setting its own. Bytes $657F-$6581; update_filter_sweep only runs when no filtered voice is playing a one-shot sound."
  },
  {
   "address": 25984,
   "type": "line",
   "text": "Written by script_cmd_set_filter; the routines that index this array from its first byte read it (the references list which)."
  },
  {
   "address": 25985,
   "type": "line",
   "text": "Written by script_cmd_set_filter; the routines that index this array from its first byte read it (the references list which). This is the byte at $6581."
  },
  {
   "address": 25986,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Nonzero while a one-shot SID sound (script command $86) is playing on the voice: set from the record's sustain/release byte, cleared at each new note. While nonzero, sid_voice_run skips the pattern, pulse and arpeggio steps, and sid_voice_change_check steps the sound. Bytes $6582-$6584."
  },
  {
   "address": 25989,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Set to 1 at each new note, so that sid_voice_run looks the note up in the frequency tables and refreshes voice_freq_lo/hi. Bytes $6585-$6587."
  },
  {
   "address": 25992,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Nonzero makes voice_store_duration reuse voice_repeat_duration instead of reading a duration byte (script command $87 sets it, $88 clears it). Bytes $6588-$658A."
  },
  {
   "address": 25995,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Set only by pattern command 5 (the handler at $6AE2): to its third operand when that is nonzero, or to 1 when it is zero (after the frequency is set to $FFFF). While nonzero it is also a note offset: sid_voice_run and the arpeggio step at $6D81 add it to voice_note and voice_transpose when they index note_freq_lo/hi. At the voice's next pattern step music_voice_step clears it and reloads voice_freq_lo/hi from voice_note plus voice_transpose, without the offset. Bytes $658B-$658D."
  },
  {
   "address": 25998,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Transposition in semitones added to voice_note before every frequency lookup. Set by sequence command $F3 and cleared by advance_voice_sequence once the repeat counter has run out. Bytes $658E-$6590."
  },
  {
   "address": 26001,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the voice's pulse width: music_voice_pulse_sweep adds voice_pulse_delta to it each frame and writes it to $D402. Bytes $6591-$6593."
  },
  {
   "address": 26004,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the pulse width a note starts from (third operand of script command $82); copied into voice_pulse_lo when a new note starts, unless bit 1 of voice_restart_mask is set. Bytes $6594-$6596."
  },
  {
   "address": 26007,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the pulse width, written to $D403. Bytes $6597-$6599."
  },
  {
   "address": 26010,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the starting pulse width (second operand of script command $82). Bytes $659A-$659C."
  },
  {
   "address": 26013,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the pulse-width change added every frame, loaded from pulse_program_table. Bytes $659D-$659F."
  },
  {
   "address": 26016,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the pulse-width change per frame. Bytes $65A0-$65A2."
  },
  {
   "address": 26019,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Low byte of the change added to voice_freq every frame, loaded from the pitch program. Bytes $65A3-$65A5."
  },
  {
   "address": 26022,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. High byte of the per-frame pitch change. Bytes $65A6-$65A8."
  },
  {
   "address": 26025,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Read position (offset from $F5) in the voice's note script; saved at the end of every script step. Bytes $65A9-$65AB."
  },
  {
   "address": 26028,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames left before the arpeggio moves to its next note offset. Bytes $65AC-$65AE."
  },
  {
   "address": 26031,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Frames per arpeggio step: first byte of the record (arp_pattern_0, arp_pattern_1). Bytes $65AF-$65B1."
  },
  {
   "address": 26034,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Current step of the arpeggio; wraps to 0 at voice_arp_length. Bytes $65B2-$65B4."
  },
  {
   "address": 26037,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Number of steps in the arpeggio: second byte of the record. Bytes $65B5-$65B7."
  },
  {
   "address": 26040,
   "type": "line",
   "text": "Single byte. Working copy of the filter accumulator's low byte while update_filter_sweep shifts the cutoff into $D416."
  },
  {
   "address": 26041,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Number of steps of the voice's one-shot sound: the third byte of its sid_oneshot_defs record. Bytes $65B9-$65BB."
  },
  {
   "address": 26044,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Steps of the one-shot sound played so far; sid_voice_start_change increments it, and the sound ends when it equals voice_oneshot_length. Bytes $65BC-$65BE."
  },
  {
   "address": 26047,
   "type": "line",
   "text": "Single byte. Nonzero while the master volume fades down. Set (with $65C0 and $65C1) to the same value by sequence command $F4 and by sid_start_fade_out ($6ED8), which the game calls to start a fade-out; sid_check_fade does the stepping."
  },
  {
   "address": 26048,
   "type": "line",
   "text": "Single byte. Frames left before the next volume step of a fade; reloaded from $65C1."
  },
  {
   "address": 26049,
   "type": "line",
   "text": "Single byte. Frames per volume step of a fade, in both directions."
  },
  {
   "address": 26050,
   "type": "line",
   "text": "Single byte. Master volume and filter mode as written to $D418: $1F after init, then counted down or up by the fades. Zero in the low nibble ends a fade-out by calling sid_silence_all."
  },
  {
   "address": 26051,
   "type": "line",
   "text": "Single byte. Nonzero while the volume fades up (sequence command $F5 stores the rate here and starts $65C2 at $10); sid_fade_in_step clears it when the volume reaches sid_fade_in_target."
  },
  {
   "address": 26052,
   "type": "line",
   "text": "Single byte. Volume the fade-up stops at, the second operand of sequence command $F5."
  },
  {
   "address": 26053,
   "type": "line",
   "text": "Per-voice array: three bytes, one for each SID voice 0 to 2, indexed by X. Bits that stop a new note restarting parts of the voice's sound (script command $89 sets it; sid_silence_all sets $FF). Bit 0: pitch program, bit 1: pulse-width program, bit 2: pattern stream, bit 3: filter program, bit 4: arpeggio. Bytes $65C5-$65C7."
  },
  {
   "address": 26054,
   "type": "line",
   "text": "Voice 1's byte of voice_restart_mask ($65C5-$65C7). sid_silence_all sets it to $FF directly; sid_reset_voice_state, sid_init_voice_loop and script command $89 (the handler at $6C16) write it through $65C5 indexed by the voice, and advance_voice_script reads it as $65C5,x when a new note starts."
  },
  {
   "address": 26055,
   "type": "line",
   "text": "Voice 2's byte of voice_restart_mask ($65C5-$65C7). sid_silence_all sets it to $FF directly; sid_reset_voice_state, sid_init_voice_loop and script command $89 (the handler at $6C16) write it through $65C5 indexed by the voice, and advance_voice_script reads it as $65C5,x when a new note starts."
  },
  {
   "address": 26056,
   "type": "line",
   "text": "Single byte of scratch for sid_load_song_voices. It keeps the position in the song list at $7C15 (X) across the call to sid_reset_voice_state, then briefly holds the voice number (Y) while X indexes sid_voice_offsets, and gives Y back before the next entry."
  },
  {
   "address": 26057,
   "type": "line",
   "text": "Low bytes of the handler addresses for the voice-script commands $80 to $8D (14 entries, $65C9-$65D6). dispatch_voice_command reads it as $6549,x with X = the command byte, which is why the label has the filter variable's address. Handlers: $80 6939 (next phrase of the sequence), $81 6B52 (select pattern from pattern_ptr_table), $82 6B70 (pulse program), $83 6B8A (pitch program A), $84 6BBC (arpeggio), $85 6C88 (filter), $86 6C24 (one-shot sound), $87 6BFA (fix duration), $88 6C0B (end fixed duration), $89 6C16 (restart mask), $8A 6EE7 (stop voice), $8B 6EF2 (new script address), $8C 6F06 (not code: it points into note_freq_lo, so the command is not used), $8D 6BA3 (pitch program B)."
  },
  {
   "address": 26071,
   "type": "line",
   "text": "High bytes of the voice-script command handlers, 14 entries at $65D7-$65E4; read as $6557,x. Pairs with voice_cmd_table_lo."
  },
  {
   "address": 26085,
   "type": "line",
   "text": "Low bytes of the sequence-script command handlers for bytes $F0 to $F5, $65E5-$65EA; seq_run_command reads them as $64F5,x. Handlers: $F0 6996 (jump to a position), $F1 699F (repeat count), $F2 69AE (stop the voice), $F3 69BF (transpose), $F4 69CE (start fade-out), $F5 69E3 (start fade-in)."
  },
  {
   "address": 26091,
   "type": "line",
   "text": "High bytes of the sequence-script command handlers, $65EB-$65F0, all $69; read as $64FB,x."
  },
  {
   "address": 26097,
   "type": "line",
   "text": "Low bytes of the seven pattern-stream command handlers, $65F1-$65F7: 0 6A53 (wait), 1 6A5F (jump), 2 6A73 (envelope), 3 6A92 (control byte, wait), 4 6AB8 (control byte, wait for the note length minus an amount), 5 6AE2 (control byte, wait, frequency flag), 6 6B23 (start a pitch program). music_voice_step patches the one it needs into the jmp at $6A50."
  },
  {
   "address": 26104,
   "type": "line",
   "text": "High bytes of the pattern-stream command handlers, $65F8-$65FE; pairs with pattern_cmd_table_lo."
  },
  {
   "address": 26111,
   "type": "line",
   "text": "SID register offset of each voice: 0, 7, 14 ($65FF-$6601), added to $D400 for voice 0, 1 and 2."
  },
  {
   "address": 26114,
   "type": "line",
   "text": "Default pattern stream for every voice (voice_pattern_ptr points here after a reset): command 0 wait $FF frames, then command 1 jump back to $6602. Five bytes, $00 $FF $01 $02 $66."
  },
  {
   "address": 26125,
   "type": "line",
   "text": "Sound start-up: clears the fade flags sid_fade_in_active and sid_fade_out_active and the filter resonance ($D417), sets sid_volume, sid_effects_enabled ($6501) and $D418 to $1F (volume 15 with the low-pass filter), then zeroes SID registers $D400-$D416 and $6530-$6546. The sound code's SID writes run from $6615 to $6EEE; the last, $D404,y at $6EEE, is in the $8A stop-voice handler at $6EE7, which the listing has not reached."
  },
  {
   "address": 26163,
   "type": "line",
   "text": "Starts a set of up to three sound voices from a song list. Does nothing if sid_effects_enabled ($6501) is zero. X is the position of the first entry in the list at $7C15; voice Y = 0 to 2 takes the entry at X+Y. An entry with bit 7 set is skipped; otherwise it is doubled and used to fetch a two-byte script pointer from $7C3D/$7C3E into $655C/$655F for that voice. It then calls sid_reset_voice_state and writes 0 to a SID control register: $D404 plus sid_voice_offsets indexed by the list position X, not by the voice. Only for a list that starts at position 0 is that the voice's own register; for a later list it reads the bytes after the table ($6602 on) and clears some other SID register. Which song or effect a list means is inferred."
  },
  {
   "address": 26219,
   "type": "line",
   "text": "Resets the sound-engine state for one voice slot (Y = 0..2). Sets the voice flag $FC+Y to 1, stores Y+1 in voice_script_timer ($6505+Y), and zeroes nine per-voice tables at Y: voice_transpose, voice_script_pos, voice_repeat_flag, voice_restart_mask, voice_pitch_enabled, f_6579, voice_arp_enabled, voice_oneshot_active and voice_freq_pending. It points the voice's pattern stream at sid_idle_pattern ($6602: 2 into voice_pattern_ptr_lo and voice_pattern_start_lo, $66 into the high bytes $6527/$652A) and clears voice_pulse_start ($6530+Y). Its only caller is sid_load_song_voices, before a voice starts its script."
  },
  {
   "address": 26281,
   "type": "line",
   "text": "Sound driver setup: sets busy flag $6502 (incremented here, cleared at $6781), then copies six bytes from $70BA,x ($70BA-$70BF plus the caller's x) into $651B-$6520. Zeroes per-voice state for voices 2 to 0 in $6515-$65C5 and calls $693F for each. Clears SID registers $D400-$D417, sets the per-voice flags $FC-$FE to 1, and loads $650x-$651x counters with 1, 2, and 3. If $65C3 is zero, sets volume $65C2 and SID $D418 to $1F."
  },
  {
   "address": 26340,
   "type": "line",
   "text": "Loop over voices 2, 1, and 0 using counter $FF: zeroes the per-voice arrays ($6515, $658E, $656B, $6588, $65C5, $6576, $6579, $657C, $6582, $6585), calls $693F, then stores 2 and $66 in $6521-$652A, 0 in $6530 and $6548, and $F5/$F6 in $655C/$655F."
  },
  {
   "address": 26419,
   "type": "line",
   "text": "Writes $08 then $00 to each SID register $D400-$D417 counting x down from $17, leaving every register at zero."
  },
  {
   "address": 26497,
   "type": "line",
   "text": "Clears the busy flag $6502 and returns; reached directly when $65C3 is nonzero, skipping the volume setup."
  },
  {
   "address": 26503,
   "type": "line",
   "text": "Per-frame sound driver step: returns at once if busy flag $6502 is nonzero. Otherwise walks voices 2 to 0 (counter $FF), loading the SID register offset from $65FF,x into $656F, and skips voices whose flag $FC,x is zero. Per active voice: optional call to $6828 when $65C3 is set, volume fade via $65BF, then the step routines $684C, $6A09, $6CBE, $6D81, and the frequency write. Finishes with $6E3E and a jump to $6DCE."
  },
  {
   "address": 26509,
   "type": "line",
   "text": "Starts a pass: sets the voice counter $FF to 2."
  },
  {
   "address": 26513,
   "type": "line",
   "text": "Top of the per-voice loop: loads x from $FF, copies the voice's SID offset $65FF,x to $656F, and jumps to sid_next_voice if the voice flag $FC,x is zero."
  },
  {
   "address": 26528,
   "type": "line",
   "text": "Active voice: calls $6828 when $65C3 is nonzero."
  },
  {
   "address": 26536,
   "type": "line",
   "text": "If fade flag $65BF is nonzero, decrements delay $65C0; when it reaches zero, reloads it from $65C1, decrements volume $65C2, and writes it to SID $D418. Jumps to $6EB0 when the low nibble of the new volume is zero; otherwise continues."
  },
  {
   "address": 26571,
   "type": "line",
   "text": "Calls $684C, then skips to sid_next_voice if $FC,x is zero or $6582,x is nonzero. Otherwise calls $6A09, $6CBE, and $6D81, and skips to sid_next_voice if $657C,x is nonzero. When $6585,x is set, clears it and looks up the voice's frequency: y = $6568,x + $658B,x + $658E,x indexes the tables $6F06 (low byte, to $6562,x) and $6F64 (high byte, to $6565,x)."
  },
  {
   "address": 26633,
   "type": "line",
   "text": "Calls $6D08, then writes the voice's frequency low byte $6562,x and high byte $6565,x to SID registers $D400,y and $D401,y, where y is the offset saved in $656F."
  },
  {
   "address": 26651,
   "type": "line",
   "text": "Decrements the voice counter $FF and loops back to $6791 until it goes negative."
  },
  {
   "address": 26658,
   "type": "line",
   "text": "After the last voice: calls $6E3E, then jumps to $6DCE."
  },
  {
   "address": 26664,
   "type": "line",
   "text": "Volume fade-up step, the counterpart of the fade-down code at $67A8. Decrements the delay $65C0; when it reaches zero, reloads it from $65C1, increments the volume byte $65C2 and writes it to SID $D418 (master volume and filter mode). When the low nibble (the volume) equals the target in $65C4, clears $65C3, which stops the fade (inferred to be the fade-in flag)."
  },
  {
   "address": 26700,
   "type": "line",
   "text": "Per-frame step of one music voice (X selects the voice). Decrements the note duration $6505,x and returns unless it hits zero. Then loads the voice's script pointer from $655C,x/$655F,x into $F5/$F6, runs advance_voice_script to read the next event, advances the script position $65A9,x and saves the pointer back."
  },
  {
   "address": 26733,
   "type": "line",
   "text": "Reads the next event for one music voice (X selects the voice, script pointer $F5, position in $65A9,x). A negative byte is a command, handled by dispatch_voice_command; $60 is a rest: it takes a duration and the script goes on, with no new note; any other byte becomes the new note in $6568,x, restarts the voice counters and, unless the voice's mask in $65C5,x says otherwise, re-arms the pattern, pulse, pitch, arpeggio and filter slots for it. The next byte, or the repeated value, is stored as the duration in $6505,x and the position is saved."
  },
  {
   "address": 26897,
   "type": "line",
   "text": "Common end of advance_voice_script: takes the duration from the next script byte (or reuses the saved one in $6508,x if the repeat flag $6588,x is set), stores it in $6505,x, and saves the script position in $65A9,x."
  },
  {
   "address": 26919,
   "type": "line",
   "text": "Handles a command byte (bit 7 set) in a voice script: looks the handler address up in voice_cmd_table_lo/hi, read as $6549,x/$6557,x with X = the command byte ($80-$8D), patches it into the jmp at $6936 (operand $6937/$6938), restores X from $FF and takes the jmp. The $6C88 (script_cmd_set_filter) that the jmp shows is only the last handler patched in before the snapshot."
  },
  {
   "address": 26935,
   "type": "line",
   "text": "Address inside the instruction at $6936: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 26936,
   "type": "line",
   "text": "Address inside the instruction at $6936: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $6938."
  },
  {
   "address": 26943,
   "type": "line",
   "text": "Steps one voice's sequence (order list), with X = voice number from $FF. The sequence pointer comes from $651B/$651E,x into $F7/$F8 and the position from voice_seq_pos ($6515,x). It clears voice_script_pos, and clears voice_transpose if it is set while the repeat count voice_repeat_count ($656B,x) is zero. A sequence byte of $F0 or more is a command (seq_run_command); any other byte is a phrase number, whose address from phrase_ptr_lo/hi ($70CC/$70F5) goes into $F5/$F6 as the voice's new note script. A nonzero repeat count is decremented and the position stays put while it is still nonzero, so the phrase plays again; otherwise the position moves on one byte. Called from sid_init_voice_loop and from the stub at $6939 (voice-script command $80), which then reads the new phrase with advance_voice_script."
  },
  {
   "address": 27008,
   "type": "line",
   "text": "Counter spent (or zero): step the voice's script position on by one byte and return."
  },
  {
   "address": 27012,
   "type": "line",
   "text": "Sequence byte of $F0 or more is a command: the handler address is taken from seq_cmd_table_lo/hi, read as $64F5,x and $64FB,x with X = the command byte, and written into the operand of the jmp at $6993 (the bytes $6994/$6995); then X is restored from $FF and the jmp runs. The $69BF it shows in the snapshot is only the last handler patched in, that of command $F3 (transpose). Patching a jmp operand is the same trick dispatch_voice_command uses at $6936."
  },
  {
   "address": 27028,
   "type": "line",
   "text": "Address inside the instruction at $6993: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 27029,
   "type": "line",
   "text": "Address inside the instruction at $6993: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $6995."
  },
  {
   "address": 27071,
   "type": "line",
   "text": "Voice sequence command handler, reached by jump from the command loop at $695F: reads the byte after the command from ($F7),y and stores it in voice_transpose ($658E,x), adds 2 to voice_seq_pos ($6515,x) (command byte and operand), and jumps back to $695F. Name is inferred from the destination table's name."
  },
  {
   "address": 27145,
   "type": "line",
   "text": "Sound engine: steps one voice's pattern stream (X selects the voice). Counts down voice_pattern_timer ($650B,x) and returns until it hits zero. If voice_freq_lookup ($658B,x) is set, it clears it and reloads voice_freq_lo/hi ($6562,x/$6565,x) from note_freq_lo/hi ($6F06/$6F64) indexed by voice_note plus voice_transpose. Then the voice's pattern pointer ($6521,x low, $6527,x high) goes into $F5/$F6 and the pattern bytes are read: each command byte indexes pattern_cmd_table_lo/hi ($65F1/$65F8) and the handler is patched into the jmp at $6A50 (operand $6A51/$6A52). Commands 1, 2 and 6 go back to $6A3C for the next byte; 0, 3, 4 and 5 set a new wait and end at voice_save_pattern_ptr. The $6AB8 the jmp shows is only the last handler patched in (command 4)."
  },
  {
   "address": 27217,
   "type": "line",
   "text": "Address inside the instruction at $6A50: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 27218,
   "type": "line",
   "text": "Address inside the instruction at $6A50: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $6A52."
  },
  {
   "address": 27282,
   "type": "line",
   "text": "Pattern-stream command 3 (reached through the patched jmp at $6A50, ends by jumping to voice_save_pattern_ptr at $6B3E). Reads two operand bytes from the pattern at ($F5),y: the first goes to $FB, the second to voice_pattern_timer ($650B,x), the frames until the voice's next pattern step. Then writes $FB to the voice's SID control register ($D404 plus the offset in $656F) if bit 3 (test bit) is set, and always writes it again with bit 3 cleared. The extra write with the test bit set resets the oscillator before the real waveform/gate value goes in (inferred from the SID register layout)."
  },
  {
   "address": 27454,
   "type": "line",
   "text": "Common end of the pattern commands that wait (0 at $6A5C, 3 at $6AB5, 4 at $6ADF, 5 at $6B0E): adds one to sid_pattern_pos ($656E), then stores the 16-bit pointer ($F5/$F6 plus that position) in voice_pattern_ptr_lo/hi ($6521,x / $6527,x) for voice X, so the next pattern step starts after the bytes just read. Then returns."
  },
  {
   "address": 27784,
   "type": "line",
   "text": "Sound script command handler (inferred to be the SID filter setup command). Reads four parameter bytes through the script pointer ($F5),Y: the first goes to $6548, the next two are stored twice each at $654C/$654E and $654D/$654F, and the fourth is held on the stack. It saves the new script position in $65A9,X, clears $657F-$6581, writes the fourth byte to the SID filter control register $D417 (and to $657F,X), then jumps to advance_voice_script."
  },
  {
   "address": 27838,
   "type": "line",
   "text": "Sound engine: per-voice sweep of the SID pulse width. Counts down the step timer $650E,x. At zero it reads the next entry of the table at $711E using index $652D,x: a zero duration means loop, with the next byte as the new index. Otherwise it loads the duration, then a 16-bit delta into $659D,x and $65A0,x. Every call adds the delta to the 16-bit value in $6591,x and $6597,x, and writes it to the voice's SID registers +2 and +3 (pulse width low and high) at offset $656F. A pulse-width sweep, which gives the voice its moving tone."
  },
  {
   "address": 27912,
   "type": "line",
   "text": "Music engine: advances one voice (X = 0 to 2) by one frame. If the voice is enabled ($6576,x), counts down its note timer $6511,x; when it reaches zero it reads the next 3-byte event (duration, two data bytes) from the stream at $7277 or, when $6533,x is zero, from $7184, using the voice's position $6536,x. A zero duration byte is a jump: the next byte becomes the new stream position. The two data bytes go to $65A3,x and $65A6,x. Every frame it then adds that pair to the 16-bit accumulator $6562,x/$6565,x, which looks like the voice's pitch (slide or vibrato step); that reading is inferred."
  },
  {
   "address": 28033,
   "type": "line",
   "text": "Arpeggio step for one voice (voice number in X). Does nothing unless the voice's arpeggio flag $657C,x is set (script command $84 sets it). Otherwise counts down $65AC,x; on zero it reloads the count from $65AF,x (frames per step), reads the next semitone offset from the arpeggio record (pointer $653C/$6542,x, index $65B2,x), adds voice_note ($6568,x) and the offsets $658B,x and $658E,x, looks the sum up in note_freq_lo/hi ($6F06/$6F64) and writes the result to the voice's SID frequency registers ($D400/$D401 plus the voice offset in $656F). It then advances the index, wrapping to 0 at the record's step count $65B5,x."
  },
  {
   "address": 28110,
   "type": "line",
   "text": "Per-frame SID filter-cutoff sweep. Returns at once if $6501 is non-zero or if the highest-numbered voice with $657F,x non-zero has $6582,x non-zero (the loop stops at the first active voice, counting down from voice 2). Otherwise counts down $6514; when it expires it reads the next (length, step low, step high) triple from the table at $72C5 (a zero length is a jump: the next byte is the new index). Each frame the 16-bit step in $654A/$654B is added to the accumulator $654F (low)/$654E (high); bits 0-2 of the low byte go to $D415 and the sum shifted right three to $D416, the 11-bit filter cutoff. Purpose (a sound effect sweep) inferred from the register writes."
  },
  {
   "address": 28222,
   "type": "line",
   "text": "Sound engine: checks the three SID voices, X = 2 down to 0. A voice with $6582,x zero is skipped. If $65BC,x differs from $65B9,x it goes to sid_voice_start_change. If they match and $6501 is non-zero, it writes 0 to that voice's SID registers +4, +5 and +6 (waveform/gate, attack-decay, sustain-release), silencing the voice; $65FF,x gives the voice's register offset. Exact meaning of the $65B9/$65BC tables is inferred."
  },
  {
   "address": 28260,
   "type": "line",
   "text": "Voice has a pending change: saves the voice number in $6503 and the step in A (voice_oneshot_step, $65BC,x) in $6504, then copies table bytes from $6550/$6553/$6556/$6559,x into operands of later instructions at $6E89/$6E8A and $6E97/$6E98 (self-modifying code). It then loads Y from $65FF,x and X from $6504, and writes the byte of the voice's frequency data at that step (the patched lda at $6E88; the $6FFD the listing shows is only the last value patched in) to SID registers +0 and +1. The routine continues past this range."
  },
  {
   "address": 28296,
   "type": "line",
   "text": "Writes the new voice's start values to the SID. The operand of the lda at $6E88 is self-modified: sid_voice_start_change copied the voice's bytes from $6553,x and $6559,x into $6E89 and $6E8A, so the table address is chosen per voice. X is reloaded from $6504 (the table index saved earlier), and the byte read is written to both the frequency registers at $D400,y and $D401,y, where Y is the voice's register offset ($65FF). Then $08 goes to the control register $D404,y."
  },
  {
   "address": 28297,
   "type": "line",
   "text": "Address inside the instruction at $6E88: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 28298,
   "type": "line",
   "text": "Address inside the instruction at $6E88: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $6E8A."
  },
  {
   "address": 28310,
   "type": "line",
   "text": "Second table read of the voice start: the operand of this lda is also self-modified (from $6550,x and $6556,x via $6E97 and $6E98, which is why those two addresses are labelled). The byte, indexed by $6504, goes to the control register $D404,y. Then X is reloaded with the voice number ($6503), voice_oneshot_step ($65BC,x) is increased, X counts down and, if still non-negative, control returns to the voice loop at $6E40; otherwise it returns."
  },
  {
   "address": 28311,
   "type": "line",
   "text": "Address inside the instruction at $6E96: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 28312,
   "type": "line",
   "text": "Address inside the instruction at $6E96: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $6E98."
  },
  {
   "address": 28329,
   "type": "line",
   "text": "Test: leaves Z set when the three voice flag bytes $FC, $FD and $FE are all zero (ORs them into A). Called from the main loop at $8127, which keeps waiting while any voice flag is set. Reading the flags as 'voice is sounding' is inferred; sid_silence_all clears them."
  },
  {
   "address": 28336,
   "type": "line",
   "text": "Silences the sound chip and clears the voice state. Zeroes the three voice flag bytes $FC-$FE, $65BF and $65C3, writes 0 to the SID volume register $D418, sets $65C5-$65C7 to $FF, and writes $08 (test bit set, gate off) to the control registers of all three voices ($D404, $D40B, $D412)."
  },
  {
   "address": 28376,
   "type": "line",
   "text": "Starts a fade-out: stores A in sid_fade_out_active ($65BF), sid_fade_delay ($65C0) and sid_fade_rate ($65C1), clears sid_fade_in_active ($65C3), and returns. Called with A = $19 from $40FC and with A = $25 from $82DC, $8B92, $8E2C and $A64B. The sequence command at $69CE stores a script byte into the same three bytes. What each of the three does in the fade is not traced here."
  },
  {
   "address": 28422,
   "type": "line",
   "text": "SID frequency low bytes, 94 entries ($6F06-$6F63), indexed by note number. Entries 1 to 93 are the equal-tempered notes C#0 to A7 (entry 57, $1D60, is A4 at 441.6 Hz on a PAL clock, and entry 93, $EB00, is twice entry 81); only entry 0 is out of place: $0578 where C0 would be about $0117. The index is the note byte of a script plus the transposition and arpeggio offsets."
  },
  {
   "address": 28516,
   "type": "line",
   "text": "SID frequency high bytes for the same 94 notes ($6F64-$6FC1); pairs with note_freq_lo."
  },
  {
   "address": 28610,
   "type": "line",
   "text": "Ten five-byte records ($6FC2-$6FF3) for the one-shot SID sounds started by script command $86. The command's operand is the record's byte offset (0, 5, 10 ...). Bytes: address of the waveform bytes (2), number of steps (1), sustain/release for $D406 (1), pulse width high for $D403 (1). The step data is in sid_oneshot_0_wave and sid_oneshot_data, and records may share blocks. Records 3 and 8 have sustain/release 0, so voice_oneshot_active stays 0 and they do not play."
  },
  {
   "address": 28660,
   "type": "line",
   "text": "Waveform bytes of one-shot sound 0 (9 steps, $6FF4-$6FFC): one byte per frame written to $D404 after a write of $08 (test bit); bit 7 noise, bit 6 pulse, bit 5 sawtooth, bit 4 triangle, bit 0 gate. The step data of the ten sounds follows in $6FFD-$70B9; no record reaches $7068-$707D or $7096-$70A3."
  },
  {
   "address": 28669,
   "type": "line",
   "text": "Step data of the one-shot sounds ($6FFD-$70B9). Each sound is a block of waveform bytes followed by the same number of frequency bytes; the byte at step n is written to both $D400 and $D401. The records in sid_oneshot_defs point into it and several share blocks: record 0 uses $6FF4 (9 steps, so its frequency bytes are $6FFD-$7005), records 1, 2 and 4 all use $7006 (12, 3 and 12 steps), record 3 uses $702A (3), record 5 $7030 (19), record 6 $7056 (9), record 7 $701E (9), record 8 $707E (12) and record 9 $70A4 (11)."
  },
  {
   "address": 28858,
   "type": "line",
   "text": "Three sets of six bytes ($70BA-$70CB). A set holds the start addresses of the three voices' sequence scripts as little-endian words: $76B7, $7691, $7668 (set 0), $7891, $7800, $784A (set 1), $7B54, $7B3A, $7B26 (set 2). sid_player_init copies the set that starts at $70BA plus X into $651B-$6520; both callers in the code pass X = 6, so set 1 is the one used. $70BA-$70BF are the first set, labelled byte by byte."
  },
  {
   "address": 28859,
   "type": "line",
   "text": "High byte of voice 0's start address in set 0 ($76B7)."
  },
  {
   "address": 28860,
   "type": "line",
   "text": "Low byte of voice 1's start address in set 0 ($7691)."
  },
  {
   "address": 28861,
   "type": "line",
   "text": "High byte of voice 1's start address in set 0."
  },
  {
   "address": 28862,
   "type": "line",
   "text": "Low byte of voice 2's start address in set 0 ($7668)."
  },
  {
   "address": 28863,
   "type": "line",
   "text": "High byte of voice 2's start address in set 0; the bytes up to $70CB are sets 1 and 2 with the same layout."
  },
  {
   "address": 28876,
   "type": "line",
   "text": "Low bytes of 41 phrase addresses ($70CC-$70F4). A byte below $F0 in a sequence script is an index into this table and its high-byte pair phrase_ptr_hi; the address becomes the voice's note script ($F5/$F6) that advance_voice_script then plays. The addresses run from $76C9 to $7BEE."
  },
  {
   "address": 28917,
   "type": "line",
   "text": "High bytes of the 41 phrase addresses ($70F5-$711D); pairs with phrase_ptr_lo."
  },
  {
   "address": 28958,
   "type": "line",
   "text": "Pulse-width programs ($711E-$7183, 102 bytes): three-byte steps of frame count, delta low, delta high, where the 16-bit delta is added to the voice's pulse width every frame for that many frames. A frame count of 0 is followed by a step index to jump to. Programs are entered at the index script command $82 gives; for example index 8 is +$0028 for 8 frames, -$0028 for 8 frames, then a jump back to index 8, a repeating pulse-width wobble."
  },
  {
   "address": 29060,
   "type": "line",
   "text": "Pitch programs, table A ($7184-$7276). Same format as pulse_program_table: frame count, delta low, delta high, with 0 and an index to jump. The delta is added to the voice's SID frequency every frame (music_voice_advance); small alternating deltas give a vibrato, for example the program entered at index 5: delta 0 for 25 frames (a delay), then from index 8 +8 for 3 frames, -8 for 6, +8 for 3, and a jump back to index 8. Selected by script command $83. The boundary with table B is where the label $7277 starts; indexes are bytes, so it is inferred."
  },
  {
   "address": 29303,
   "type": "line",
   "text": "Pitch programs, table B ($7277-$72B6): same format as pitch_program_a, selected by script command $8D."
  },
  {
   "address": 29367,
   "type": "line",
   "text": "Two arpeggio record addresses ($72B7-$72BA): $72BB and $72C1. Script command $84 picks one by index; the routine reads the high byte of both from $72B8, which works because both are in page $72. A record is the frames per step, the number of steps, then that many semitone offsets added to the note: arp_pattern_0 and arp_pattern_1."
  },
  {
   "address": 29371,
   "type": "line",
   "text": "Arpeggio record 0: 1 frame per step, 4 steps, offsets 0, 3, 7, 3 semitones ($72BB-$72C0)."
  },
  {
   "address": 29377,
   "type": "line",
   "text": "Arpeggio record 1: 3 frames per step, 2 steps, offsets 0 and 2 semitones ($72C1-$72C4)."
  },
  {
   "address": 29381,
   "type": "line",
   "text": "Filter-cutoff programs ($72C5-$7383, 191 bytes): three-byte steps of frame count, step low, step high, where the 16-bit step is added to the cutoff accumulator every frame. A frame count of 0 is followed by a step index to jump to. Programs are entered at the index script command $85 gives; update_filter_sweep reads it only when sid_effects_enabled is zero."
  },
  {
   "address": 29572,
   "type": "line",
   "text": "49 pattern stream addresses as little-endian words ($7384-$73E5), from $73E6 to $765C. Script command $81 takes the pattern number, doubles it, and copies the word into voice_pattern_start_lo and voice_pattern_start_hi."
  },
  {
   "address": 29670,
   "type": "line",
   "text": "Pattern streams, from $73E6 to the sequence scripts at $7668: byte sequences interpreted by music_voice_step through pattern_cmd_table_lo/hi, with command numbers 0 to 6 and their operands (wait, jump, envelope, control byte). The first stream starts: command 2 (attack/decay $00, sustain/release $C9), command 5 (control byte $89, wait 1, frequency flag 0)."
  },
  {
   "address": 31765,
   "type": "line",
   "text": "List read by sid_load_song_voices at $663A: the byte at $7C15+X+Y is voice Y's number into voice_script_table, or has bit 7 set ($80) when the slot is unused. The 40 bytes $7C15-$7C3C are ten groups of four, one per sound: every request queued through $0B8C is a multiple of 4 from 0 to $24, so all ten are used, and the fourth byte of each group (0) is never read, since only Y = 0 to 2 are taken."
  },
  {
   "address": 31805,
   "type": "line",
   "text": "Table of ten note script addresses, words low byte first, $7C3D-$7C50: $7C51, $7C5C, $7C67, $7C72, $7C7D, $7C88, $7C93, $7C9A, $7CA5 and $7CB2. sid_load_song_voices doubles the number from song_voice_list and copies the word's two bytes to voice_script_ptr_lo ($655C,y) and voice_script_ptr_hi ($655F,y), Y being the voice."
  },
  {
   "address": 31806,
   "type": "line",
   "text": "High byte of the first word of voice_script_table ($7C, giving $7C51); the other nine words follow at $7C3F-$7C50."
  },
  {
   "address": 31825,
   "type": "line",
   "text": "The ten note scripts that voice_script_table points to, $7C51-$7CBC (108 bytes). Command bytes $81, $82, $83, $84 and $8A, $8D are sound-engine commands run by tick_voice_script; $84 starts an arpeggio."
  },
  {
   "address": 31933,
   "type": "line",
   "text": "Sort list for the logical sprites: an entry is filed at position Y / 2 of its screen line, or at the next free position after it, so walking the list from the start gives top-to-bottom order. A position holding $00-$7E holds an entry number; $FF marks a free position, and $7F, written one past the highest position used, ends the list."
  },
  {
   "address": 31934,
   "type": "line",
   "text": "Entry 1 of sprite_y_buckets (position Y / 2 on the screen line, one byte for each); many routines write it through $7CBD,x. $FF marks an empty position; $7F is the end-of-list marker, which j_A43A stores at $7CBE plus sprite_bucket_max, so it reaches this entry only when that maximum is 0."
  },
  {
   "address": 32597,
   "type": "line",
   "text": "Status line cell: the stage number as a digit tile, written by draw_status_stage ($8353) as stage ($08E7) + $C2 (tile $C1 is digit 0, so stage 0 shows 1). Row 21, column 13 of the panel screen at $7C00."
  },
  {
   "address": 32600,
   "type": "line",
   "text": "Eleven status line cells $7F58-$7F62 (row 21, columns 16 to 26) drawn by draw_segment_gauge from the value in $08A1: cells left of value / 4 get tile $D7, cells right of it $D5 (the empty cell), and the edge cell a partial tile from gauge_tiles ($0434) by the value's low two bits. With $08A1 = 0 in the saved state all eleven show $D5; the saved state also shows $D4 at the left end of the row and $D6 at the right end."
  },
  {
   "address": 32617,
   "type": "line",
   "text": "Five status line cells $7F69-$7F6D (row 21, columns 33 to 37), the label written by draw_status_label from the 9-byte records at $FFC2 (each byte plus $A5)."
  },
  {
   "address": 32665,
   "type": "line",
   "text": "Status line cell written with tile $C1 (digit 0) by draw_status_lives ($8347): the first digit of the lives pair. update_status_line calls it each frame unless player_hit ($0292) is set; $80BA and $A862 call it too. Row 23, column 1."
  },
  {
   "address": 32666,
   "type": "line",
   "text": "Status line cell for the lives counter: draw_status_lives ($8347) stores lives_tile ($089D) here, each frame through update_status_line unless player_hit ($0292) is set, and when called from $80BA and $A862. Row 23, column 2."
  },
  {
   "address": 32668,
   "type": "line",
   "text": "Status line cell, row 23 column 4: update_status_line copies $089E here each frame unless player_hit ($0292) is set (a digit tile, $C1 at the start)."
  },
  {
   "address": 32669,
   "type": "line",
   "text": "Status line cell, row 23 column 5: update_status_line copies $089F here each frame unless player_hit ($0292) is set (digit tile)."
  },
  {
   "address": 32686,
   "type": "line",
   "text": "Status line cell of the level clock's minute digit: draw_level_timer stores $0899 + $C1 here. Row 23, column 22."
  },
  {
   "address": 32688,
   "type": "line",
   "text": "Status line cell of the clock's tens of seconds: draw_level_timer stores $089A + $C1 here. Row 23, column 24."
  },
  {
   "address": 32689,
   "type": "line",
   "text": "Status line cell of the clock's units of seconds: draw_level_timer stores $089B + $C1 here. Row 23, column 25."
  },
  {
   "address": 32697,
   "type": "line",
   "text": "Five status line cells $7FB9-$7FBD (row 23, columns 33 to 37) that update_status_line fills with the score digits copied from $08D0-$08D4. The two blank cells after them ($B8) are not written."
  },
  {
   "address": 32704,
   "type": "line",
   "text": "Sixty-four bytes $7FC0-$7FFF made of the pattern $FF $FF $00 $00 $00 $00 $FF $FF repeated. It lies in the last 64 bytes of the panel screen at $7C00 (the last eight bytes at the place of the screen's sprite pointers). No routine in the listing reads or writes it."
  },
  {
   "address": 32768,
   "type": "line",
   "text": "Start of a game: initialise, set the CIA 2 timer for the per-frame NMI, wait for raster line $EE, blank the screen and enter the stage."
  },
  {
   "address": 32769,
   "type": "line",
   "text": "Address inside the instruction at $8000: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 32771,
   "type": "line",
   "text": "Calls nmi_and_first_copy ($5271), then loads the CIA 2 timer A latch with $4CC7 (19655; low byte $C7 at $DD04, high byte $4C at $DD05), the interval for the per-frame NMI. The timer runs latch + 1 = 19656 cycles, one PAL frame of 312 lines of 63 cycles."
  },
  {
   "address": 32777,
   "type": "line",
   "text": "Address inside the instruction at $8008: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 32778,
   "type": "line",
   "text": "Address inside the instruction at $8008: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $800A."
  },
  {
   "address": 32779,
   "type": "line",
   "text": "Loads $4C, the high byte of the per-frame timer interval $4CC7, for the CIA 2 timer A latch."
  },
  {
   "address": 32780,
   "type": "line",
   "text": "Address inside the instruction at $800B: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 32781,
   "type": "line",
   "text": "Stores the high byte $4C in the CIA 2 timer A latch ($DD05), completing the interval $4CC7 for the per-frame NMI."
  },
  {
   "address": 32782,
   "type": "line",
   "text": "Address inside the instruction at $800D: the label sits on an operand byte, not on an instruction start. cart_copy reads it as the base of an indexed table (lda $800E,x at $0138, with ROM bank 0 selected), the destination high byte of a cartridge directory entry; it is not a patched operand of the RAM instruction."
  },
  {
   "address": 32783,
   "type": "line",
   "text": "Address inside the instruction at $800D: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction. This is the byte at $800F."
  },
  {
   "address": 32784,
   "type": "line",
   "text": "Begins a new game after the title. Waits for raster line $EE, writes $91 to CIA 2 control register A ($DD0E), blanks the screen by clearing $D011, sets the stage number $08E7 to 0 and $089C to 2, and calls new_game_defaults. Then it turns on the raster interrupt ($D01A = 1), clears $DD00 (selects the video bank), clears cheat_flag and $08C1, $08BF and $0294, and jumps to $403A in the stage intro. The meaning of $089C, $08C1 and $08BF is not established here."
  },
  {
   "address": 32838,
   "type": "line",
   "text": "A stage begins: stage_start loads it from the cartridge, then the round starts."
  },
  {
   "address": 32847,
   "type": "line",
   "text": "A round begins (at a stage's start and after losing a life): stop the interrupts, reset the frame state, count $089D down (below $C1 the game is over: $BD5D, then back to the title at $4000), start the sound, set the raster interrupt to irq_panel_on ($BCE1) at line $DE, set up the stage, then wait 20 frames."
  },
  {
   "address": 33017,
   "type": "line",
   "text": "The main loop, once a frame: count the frame, scan the keyboard ($5290) for as long as $02CA holds the game paused, run the game's updates ($A178 to $5B83), count down $0293 after a life is lost and restart the round at 0, then wait for the frame."
  },
  {
   "address": 33033,
   "type": "line",
   "text": "Address inside the instruction at $8107: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 33038,
   "type": "line",
   "text": "Address inside the instruction at $810D: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 33043,
   "type": "line",
   "text": "Main-loop call of place_player_sprites. The auto label f_8113 comes from two reads of the table of stage pointers in bank 0 at $8113 ($0B46 and $4F6C, with the cartridge bank 0 switched in by $DE00); nothing in RAM writes to this instruction, so the call is never patched."
  },
  {
   "address": 33048,
   "type": "line",
   "text": "Address inside the instruction at $8116: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 33053,
   "type": "line",
   "text": "Address inside the instruction at $811C: the label sits on an operand byte, not on an instruction start. Other code refers to this address (an indexed table or buffer base, a patched operand, or a jump into the middle of the instruction; the references show which); the routine that contains it is commented at its first instruction."
  },
  {
   "address": 33058,
   "type": "line",
   "text": "Per-frame check of $0293 (death_countdown): if it is zero skips ahead to $8134; otherwise calls sid_any_voice_active ($6EA9) and, while no voice is sounding, counts $0293 down (inferred reading of the branch)."
  },
  {
   "address": 33063,
   "type": "line",
   "text": "Death-countdown tail of the main loop, reached when death_countdown ($0293) is non-zero: calls sid_any_voice_active ($6EA9); if any voice flag is set, jumps to wait_nmi and waits. Otherwise decrements death_countdown and, when it reaches zero, jumps to round_start ($804F); if not, falls to wait_nmi ($8134). So the next round starts only after the sound has finished (inferred from the flag test)."
  },
  {
   "address": 33076,
   "type": "line",
   "text": "Wait for the interrupt to set frame_flag ($08F7), then choose the next frame's raster interrupt: sprite_reuse_irq ($95A4) at the line spr_min_free_line returns when sprite_more ($6B) is non-zero, otherwise irq_panel ($837E) at line $D5. Then copy the sprite tables the game fills into the set the interrupts draw from: pointers, free lines and X/Y ($07C7-$07E6) to $07E7-$0806, colours ($07B4-$07BB) to $07BF-$07C6, and the enable, X high bit and expand images ($07B2, $07B1, $07B3) to $07BD, $07BC and $07BE. Then calls build_vic_shadows and falls into enable_frame_nmi."
  },
  {
   "address": 33172,
   "type": "line",
   "text": "Writes $81 to the CIA 2 interrupt control register ($DD0D), which enables the timer A interrupt (the per-frame NMI), loads X with 1 and falls into wait_frame. Reached only by fall-through from wait_nmi at $8191. The three jsr $8194 in the program (stage_load $0A9B, copy_three_cart_entries $51E4, nmi_and_first_copy $5285) run with $01 = $37, so they reach the cartridge's routine at $8194, not this RAM copy."
  },
  {
   "address": 33179,
   "type": "line",
   "text": "Wait for frame_flag to change from the value wait_nmi read (Y), clear it (X is 1 from enable_frame_nmi) and allow interrupts. Then test bit 5 (retired) of obj_state ($3592) of the stage's goal object, whose number is in $08CC, and store the result in all_move_flag ($94). When it is set the stage is cleared: increment stage, set up the sprites and go to stage_intro_start ($4016). Otherwise go on with the frame: copy the logical sprite lists to the interrupt's tables, stream data and run the per-frame routines."
  },
  {
   "address": 33397,
   "type": "line",
   "text": "Per-frame status line update. Returns at once if player_hit is non-zero, so the clock stops while the player is dying. Otherwise calls $8347 (stores $C1 at $7F99 and $089D at $7F9A), copies the five bytes $08D0-$08D4 to $7FB9-$7FBD and $089E/$089F to $7F9C/$7F9D, then falls into level_timer_tick. The copied values are probably score or counter digits already in tile form (inferred)."
  },
  {
   "address": 33429,
   "type": "line",
   "text": "Level countdown timer. Called once by round_start ($80B7) and entered every main-loop pass from update_status_line, which skips it while player_hit is set. $0898 counts passes down from $19 (25); each wrap ticks the clock digits $089B (units, 9..0), $089A (tens, 5..0) and $0899 (minutes) down like a minutes:seconds display. When the minutes go below zero the time has run out: the digits are set to zero and the player is killed here (player_hit and jump_state $FF, see $82B8), sound $24 is queued with queue_sound ($0B8C), the music fades out through sid_start_fade_out when $DF is non-zero, and hit_save_pos ($8E2F) runs. Every path ends in draw_level_timer."
  },
  {
   "address": 33464,
   "type": "line",
   "text": "Time is up: zero the clock digits, clear player_mode, set jump_state and player_hit to $FF (the same flags a hit sets, so the player dies) and jump_counter to $10, then play sound $24."
  },
  {
   "address": 33494,
   "type": "line",
   "text": "If $DF (music_mode) is non-zero (queue_sound refuses new effects then), the music is faded out instead: sid_start_fade_out ($6ED8) is called with A = $25, which goes into sid_fade_out_active, sid_fade_delay and sid_fade_rate. Then hit_save_pos records where the player died."
  },
  {
   "address": 33506,
   "type": "line",
   "text": "Draws the clock: each digit ($0899, $089A, $089B) plus $C1 is stored in the status-line cells $7FAE, $7FB0 and $7FB1 (the cell between them, $7FAF, is skipped; the $C1 digit base is read from the code, the glyphs are not checked here). Carry is clear going in, so the adds do not chain."
  },
  {
   "address": 33536,
   "type": "line",
   "text": "Reached from draw_level_timer when the clock's minute digit $0899 is zero, so the last minute. Chooses colour $0E or $0A from bit 2 of frame_count, so it alternates every four frames, and writes it to the five colour RAM bytes $DBA8-$DBAC. The cells are probably the clock's label next to the digits, a time-running-out warning (inferred)."
  },
  {
   "address": 33563,
   "type": "line",
   "text": "Draws an 11-cell bar gauge into the status line at $7F58-$7F62 from the value in gauge_value ($08A1). The value divided by 4 is the whole-cell count: cells above it get tile $D5, cells below it get tile $D7, and the boundary cell gets a partial tile fetched from $0434 indexed by the low two bits of the value (four fill steps). The value is the health of the stage's goal object: track_stage_section ($92EF) stores the low 5 bits of its obj_health in $08A1 and calls this routine while $08CB is non-zero; round_start calls it once at $80BD."
  },
  {
   "address": 33607,
   "type": "line",
   "text": "Writes the lives display on the status line: status_lives_tens ($7F99) gets $C1 (the digit 0 tile) and status_lives_digit ($7F9A) gets lives_tile ($089D). Called from update_status_line and from $80BA and $A862."
  },
  {
   "address": 33619,
   "type": "line",
   "text": "Writes the stage digit on the status line: stage ($08E7) plus $C2 goes to status_stage_digit ($7F55), so stage 0 shows as 1. Called once per round by round_start at $80B1."
  },
  {
   "address": 33629,
   "type": "line",
   "text": "Writes a five-character label into the status line cells $7F69-$7F6D. Scans 9-byte records starting at $FFC7 (X steps by 9, skipping records whose byte at $FFC7+X has bit 6 set), then copies five bytes from $FFC2+X, each plus $A5, as screen tile codes. What the text is (and what picks the record) is not established here, so the name is neutral; called once per round by round_start at $80B4."
  },
  {
   "address": 33662,
   "type": "line",
   "text": "Raster interrupt at line $D5, the top of the status panel. Waits for line $D6, then sets $D011 = $57: extended colour and multicolour together, a mode the VIC-II shows as black, which hides the switch to the panel's video bank ($DD00 = $02), screen and character set ($D018 = $FF) and colours. Moves all sprites to x = 0, out of sight, chains irq_panel_on for line $DE, and calls sound_frame."
  },
  {
   "address": 33773,
   "type": "line",
   "text": "New-game start values, called once by game_start ($802B). Puts $C6 (digit 5) in lives_tile ($089D), $C1 (digit 0) in $089E, $089F and the score digits $08D0-$08D4, $CC in shown_buf_hi ($08C0) and $C8 in back_buf_hi ($08C2). Sets player_facing ($18) to 7, clears $11, $08A0 and $D01B (so every sprite is drawn in front of the background), sets $10 to 1 and move_step ($0A) to 2. Writes $31 to $D018 (screen and character memory layout) and $10 to $D016 (multicolour on, 38 columns, no fine scroll)."
  },
  {
   "address": 33844,
   "type": "line",
   "text": "Once a frame, update the pool of nine short-lived objects, temp_first ($16) to temp_first + 8 (stage 1: $4C-$54), from the last slot down. Y is the slot and indexes the velocities ($3FD3/$3FDC X, $3FE5/$3FEE Y) and life ($3FF7). For each slot not retired: bit 7 of $35EF makes it blink (bit 6 cleared on frames whose parity matches bit 0, set on the others); it moves only when $3484 shares a bit with move_mask. A move counts the life down (at zero it is retired with $A0), adds the velocity, and runs object_arc_step when $3F19 is non-zero. With bit 3 of obj_state set, $9400 (A = $0C, Y = $0A) is tested; if either low bit is set the object is retired or, with bit 2 set, becomes animation $37 (obj_anim_num) with life $18, motion cleared, and the routine returns. Then $B57A, and the view test ($40-$47): left, right or below retires; above retires only when $3F19 is zero. A survivor's position is stored and set_object_hitbox ($ABC7) run."
  },
  {
   "address": 34162,
   "type": "line",
   "text": "Once a frame, read the joystick and run the player. It writes $7F to both CIA 1 ports, reads port A (port B instead when A reads $7F), keeps the low four bits in joy_bits ($08), and copies the fire bit (bit 4) into bit 6 of $08C6 (1 means not pressed). Before that it tests a hidden combination: when port A ($DC00, joystick 2) has bits 0 and 4 low (up and fire) and port B ($DC01, joystick 1) has bits 1 and 4 low (down and fire), it increments cheat_flag ($08F9) and the background colour ($D021), once for each frame they are held. With port A at $7F the keys left arrow and space also pull port B bits 1 and 4 low. It then decrements $08DE unless its bit 7 is set, saves the previous position with save_player_x and save_player_y, runs player_mode_step ($85DC), sets $19 to $FF, calls $AF34 (skipped while bit 6 of $08C6 is set), $98F3, and $9F05 (skipped while bit 7 of $08C6 is set), picks the animation frame with player_pose ($413A), and ends in $92DF."
  },
  {
   "address": 34268,
   "type": "line",
   "text": "Run the player's movement for the current player_mode ($09). Mode 1 goes to $9025, and modes other than 0 and 1 go to $8E88. Mode 0 first rewrites $08C6: $40 when fire is not pressed (bit 6 set), otherwise $00 while $08FA is non-zero and $80 when it is zero; then it runs $8603, which reads joy_bits, and goes on to $89A9."
  },
  {
   "address": 34307,
   "type": "line",
   "text": "Mode 0 movement for one frame, called from player_mode_step. Reads joy_bits ($08), fire_flags ($08C6), and jump_state ($08FA). While player_hit ($0292) is non-zero it goes to player_hit_step. Calls $8D67 unless $1A is negative. On the ground: down ($0D) goes to player_down_enter_mode1, right ($07) to player_walk_right, left ($0B) to player_walk_left, down-right ($05) and down-left ($09) to player_down_right and player_down_left when $0C is zero (when $0C is non-zero they go to player_stop_facing if bit 7 of $08C6 is set, otherwise they walk right or left), up-right ($06) and up-left ($0A) to the jump routines (walks instead while bit 7 of $08C6 is set), and up ($0E) to player_jump_up only while bit 7 of $08C6 is clear (with it set, up is idle). In the air only right and left count. Anything else sets move_dir ($0D) to $FF and $0299 to 0, then runs player_jump_motion when airborne or sets $0905 to 1 when on the ground."
  },
  {
   "address": 34458,
   "type": "line",
   "text": "Start a jump to the right (joy_bits $06). When jump_state ($08FA) is non-zero it goes to walk_right_dir instead. Otherwise it calls $42F8 (adds move_step to player_try_x, skipped while bit 7 of $08C6 is set), loads A with 6, and falls into player_jump_start."
  },
  {
   "address": 34468,
   "type": "line",
   "text": "Shared tail of the jumps: stores A in move_dir ($0D), calls $0B8C with A at 0, and clears bit 7 of obj_flags ($364C) for the object whose index is in $1A when $1A is not negative. Then sets $1A and jump_state ($08FA) to $FF, $0299 and $0C to 0, $0903 to 1, and $0905 to 3, and copies $08FC into jump_counter ($08FB). player_jump_motion then lifts the player by $02CE steps until jump_counter runs out."
  },
  {
   "address": 34516,
   "type": "line",
   "text": "Start a jump to the left (joy_bits $0A). When jump_state ($08FA) is non-zero it goes to walk_left_dir instead. Otherwise it calls $42E1 (subtracts move_step from player_try_x, skipped while bit 7 of $08C6 is set), loads A with $0A, and goes to player_jump_start."
  },
  {
   "address": 34529,
   "type": "line",
   "text": "Down-left on the ground, entered with A at $09. Stores A in move_dir ($0D) and $18, sets $0B to 1 and $0905 to 5, and loads A with $FF, then joins player_walk_left at walk_left_move, so $0299 becomes $FF and the player steps left."
  },
  {
   "address": 34546,
   "type": "line",
   "text": "Down-right on the ground, entered with A at $05. Stores A in move_dir ($0D) and $18, sets $0B to 1 and $0905 to 5, and loads A with $FF, then joins player_walk_right at walk_right_move, so $0299 becomes $FF and the player steps right."
  },
  {
   "address": 34563,
   "type": "line",
   "text": "Step right. On the ground ($08FA zero) it sets $0905 to 1. Sets move_dir ($0D) to $07 and $0299 to 0, then calls $42F8, which adds move_step ($0A) to player_try_x unless bit 7 of $08C6 is set. When $0C is non-zero it goes to player_slope_step. Otherwise it sets move_step to 2 and, when jump_state is non-zero, goes on to player_jump_motion."
  },
  {
   "address": 34599,
   "type": "line",
   "text": "Step left. On the ground ($08FA zero) it sets $0905 to 1. Sets move_dir ($0D) to $0B and $0299 to 0, then calls $42E1, which subtracts move_step ($0A) from player_try_x unless bit 7 of $08C6 is set. When $0C is non-zero it goes to player_slope_step. Otherwise it sets move_step to 2 and, when jump_state is non-zero, goes on to player_jump_motion."
  },
  {
   "address": 34635,
   "type": "line",
   "text": "Vertical step that goes with a horizontal one when $0C is non-zero (A holds $0C). Ends in $430F (subtracts move_step from player_try_y) or $4326 (adds it), whichever the direction calls for, and the rts of that routine returns to the caller, so no jump motion follows. With $0C equal to 1 the player goes down when bit 3 of move_dir ($0D) is set (moving left) and up when it is clear (moving right). With any other value it goes up when moving left and down when moving right. $430F and $4326 do nothing while bit 7 of $08C6 is set."
  },
  {
   "address": 34657,
   "type": "line",
   "text": "Movement after a hit (player_hit non-zero). Does nothing while $0293 is non-zero. While jump_state ($08FA) is negative, or while $08ED plus $0F (added without clearing the carry first) is below $EB, it goes to player_jump_motion. Otherwise it sets $0293 to $19, the countdown that the main loop at $8122 uses to reach round_start."
  },
  {
   "address": 34682,
   "type": "line",
   "text": "Vertical motion of a jump, using jump_state ($08FA) and jump_counter ($08FB) on player_try_y ($08BD/$08BE). A jump_state of 0 does nothing. A negative one (rising) clears bit 0 of move_dir ($0D), subtracts $02CE[x] from player_try_y, where x is jump_counter limited to 16, and subtracts the same amount from jump_counter. When jump_counter would reach zero or below it sets jump_state to 1 and jump_counter to 0. A positive one (falling) clears bit 1 of move_dir, adds $02DF[x] with x as jump_counter, and raises jump_counter by one until it reaches 8."
  },
  {
   "address": 34773,
   "type": "line",
   "text": "Down pressed on the ground. Goes to player_stop when bit 7 of $08C6 is set. Otherwise it calls $9E69 and goes to player_stop when bit 4 of $08E9 is clear. Otherwise it sets $0322 to $12, adds $15 to player_y ($08B9/$08BA), adds $E1/$E2 to player_x ($08B7/$08B8), sets $08FF to $44, clears player_third_on ($0913), $0B, $0900, and $0323, sets player_mode ($09) to 1 and move_step ($0A) to 2, stores $0D in both $18 and move_dir ($0D), and sets $0905 to 6."
  },
  {
   "address": 34862,
   "type": "line",
   "text": "Stores A in $18, then runs player_stop. Reached from player_move with A at $05 or $09 when $0C is non-zero and bit 7 of $08C6 is set."
  },
  {
   "address": 34864,
   "type": "line",
   "text": "Stand still: sets move_dir ($0D) and $0299 to $FF and $0905 to 4. No position changes."
  },
  {
   "address": 34880,
   "type": "line",
   "text": "Start a straight-up jump (joy_bits $0E). When jump_state ($08FA) is non-zero it goes to player_jump_motion. Otherwise it loads A with $0E and goes to player_jump_start, with no horizontal step."
  },
  {
   "address": 34890,
   "type": "line",
   "text": "Set up the tables for a stage, called at $8049. Clears section_index ($0298), sets the sprite multicolour enable $D01C to $FF, and copies the 22 bytes at $0C0C-$0C21 to $2A-$3F. Points $24/$25 at $0D22 and loads $26/$27 from the word stored there. Copies $0C03, $0C04, and $0C05 to bg_colour0, bg_colour1, and bg_colour2 ($08C3-$08C5, written to the three VIC background colour registers $D021-$D023 by nmi_frame at $4DB1), and sets the sprite multicolours $D025 and $D026 to $0B and $0F."
  },
  {
   "address": 34957,
   "type": "line",
   "text": "Count scroll_phase ($0E) down once a frame (called from the main loop at $825F). Does nothing when scroll_phase is negative. Otherwise it decrements it. When the old value was 1 it jumps to $5BC2. When the old value was 0 (now $FF) and player_hit ($0292) is zero, it reads the address from the tables $0324 (low) and $032C (high) at the index scroll_dir ($0F), stores it in $E1/$E2, and jumps through it at jump_via_e1. Any other old value just returns."
  },
  {
   "address": 34991,
   "type": "line",
   "text": "Jump through the address in $E1/$E2 (jmp ($00E1)). scroll_phase_step runs into it, and a jsr to it (as at $B224, after loading $E1/$E2 from the tables at $B33C and $B35F) lets the target's rts return to the caller."
  },
  {
   "address": 34994,
   "type": "line",
   "text": "Build the copies of the VIC registers that nmi_frame writes out at $4DAB-$4DCC (apply_vic_shadows). shadow_d018 ($07B0, for $D018) gets $21 when $10 is zero and $31 otherwise. shadow_d016 ($07AF, for $D016) gets $10 combined with scroll_fine_x ($06). shadow_d011 ($07AE, for $D011) gets $10 combined with scroll_fine_y ($07). Called at $8191."
  },
  {
   "address": 35022,
   "type": "line",
   "text": "Apply one frame of vertical motion to an object's new position (E9/EA) according to obj_arc_state ($3F19 for the object in X, passed in the flags). With bit 7 and bit 6 set it falls: the position moves down by a value from $02DF indexed by obj_arc_counter ($3F76), which rises by one up to 8 (so it speeds up). With bit 7 set and bit 6 clear it rises by a value from $02CE indexed by the counter (at most 16), the counter falls by the same amount, and when it runs out obj_arc_state becomes $C0 (falling). With bit 7 clear it works out a move along a path through the data at the pointer $32 and, for a follower, stores the offset from its parent in $36F4 and $3748; that path is not decoded."
  },
  {
   "address": 35101,
   "type": "line",
   "text": "Path case of object_arc_step (obj_arc_state has bit 7 clear). Saves X (the object) in $EB and Y in $ED, calls path_advance with A as obj_arc_state, and restores X and Y. When bit 6 of obj_flags ($364C) is set it then stores $E7 minus $08DA in obj_off_x ($36F4) and $E9 minus $08DC in obj_off_y ($3748)."
  },
  {
   "address": 35138,
   "type": "line",
   "text": "Advance an object one step along its path. A is obj_arc_state (an offset into the table of path addresses at the pointer $32) and X is the object. Loads $E3/$E4 with the word at $32 plus A, copies obj_arc_counter ($3F76) into $EC, and uses that as the slot in path_end ($5C), path_axes ($60), and path_pos ($64). When path_end is below path_pos the path is over (path_finish). Otherwise path_axes 0 adds one word of path data to the X position $E7/$E8, 1 adds one word to the Y position $E9/$EA, and 2 or more adds an X word then a Y word, reading at offset path_pos."
  },
  {
   "address": 35177,
   "type": "line",
   "text": "Add the next word of path data to the Y position $E9/$EA. The data is at $E3/$E4 plus Y; a low byte of $80 restarts at offset 0. Y is advanced by two and stored in path_pos ($64) at the slot in $EC. Entered by path_advance when path_axes is 1, and after path_add_x when it is 2 or more."
  },
  {
   "address": 35205,
   "type": "line",
   "text": "Add the next word of path data to the X position $E7/$E8. The data is at $E3/$E4 plus Y; a low byte of $80 restarts at offset 0. Y is advanced by two and stored in path_pos ($64) at the slot in $EC. Called by path_advance, which enters it directly when path_axes is 0."
  },
  {
   "address": 35233,
   "type": "line",
   "text": "End of a path: clears obj_arc_state ($3F19) for the object in $EB and returns."
  },
  {
   "address": 35241,
   "type": "line",
   "text": "Second half of mode 0 movement, reached from player_move. Checks the new position that player_move left in player_try_x and player_try_y against the blocks. While player_hit ($0292) is non-zero it goes to restore_player_pos ($4246). On the ground (jump_state $08FA zero) it looks at move_dir ($0D): with bit 3 clear it goes to collide_ground_right, with bit 3 set and bit 2 clear to collide_ground_left, and otherwise it returns. In the air it goes by move_dir: $05 to air_down_right_x, $09 to air_down_left_x, $0D to air_vertical, $0E to $8D10, $06 to $8CDF, and $0A to $8CF6. Any other value returns."
  },
  {
   "address": 35316,
   "type": "line",
   "text": "Ground check for a step to the left (move_dir with bit 3 set and bit 2 clear). When slope_kind ($0C) is non-zero it goes to $8C60. Otherwise it calls $9BF6, merges $E1, $E2, and $E3 into $E1, and tests bit 0 (solid). If it is set, save_player_x ($4263) copies player_x over player_try_x, so the step is dropped. If it is clear, restore_player_x ($4249) copies player_try_x into player_x, so the step stands. Either way it goes on to ground_floor_check."
  },
  {
   "address": 35346,
   "type": "line",
   "text": "Check what is under the player after a ground step. Returns at once when stand_obj ($1A) is not negative. Otherwise it calls $9D3C. If bit 5 is set in all three of $E1, $E2, and $E3, it clears $08FF, sets $0B, player_mode ($09), and move_step ($0A) to 1, 1, and 2, sets $0905 to 5, and returns (the player enters mode 1). Otherwise, if $0291 has bit 2 or bit 3 set, it stores those two bits shifted down in slope_kind ($0C) and returns. If not, and no block has bit 0 set and stand_obj is still negative (the probe found no platform), it starts a fall: jump_counter ($08FB) becomes 1, $0299 becomes 0, jump_state ($08FA) becomes 1, and $0905 becomes 3."
  },
  {
   "address": 35433,
   "type": "line",
   "text": "Ground check for a step to the right (move_dir with bit 3 clear). Same as collide_ground_left, but a non-zero slope_kind ($0C) goes to $8CAB and the block probe is $9C1E. A solid block drops the step through ground_x_blocked, and a free one commits it with restore_player_x ($4249) before going on to ground_floor_check."
  },
  {
   "address": 35470,
   "type": "line",
   "text": "Airborne step down and to the left (move_dir $09). Pushes $031D, subtracts the fall step $02DF[jump_counter] from it, calls $9BF6 with the smaller value, and puts $031D back. Then it merges $E1, $E2, and $E3 and tests bit 0. A solid block drops the step with save_player_x ($4263), and a free one commits it with restore_player_x ($4249). Both ways it ends in air_vertical."
  },
  {
   "address": 35517,
   "type": "line",
   "text": "Airborne step down and to the right (move_dir $05). Same as air_down_left_x, but the block probe is $9C1E instead of $9BF6. Both ways it ends in air_vertical."
  },
  {
   "address": 35561,
   "type": "line",
   "text": "Vertical check for an airborne player: calls air_floor_check, then goes on to $8D20."
  },
  {
   "address": 35567,
   "type": "line",
   "text": "Decide what the blocks under an airborne player do, then commit or adjust player_prev_y. It calls $9D3C. If bit 5 is set in all three of $E1, $E2, and $E3, it sets $0905 to 5, $0B and player_mode ($09) to 1, ORs 3 into $18, copies $18 to move_dir ($0D), and goes to land_and_snap (mode 1 is entered). Otherwise it merges the three: with bit 1 set it goes to air_hit_hazard. If $0291 has bit 2 or bit 3 set it goes to $8C0B. When stand_obj ($1A) is not negative it goes to air_on_object. Otherwise bit 0 (solid) goes to air_land_solid. With bit 0 clear and bit 6 set it sets player_mode to 2, jump_state to $FF, jump_counter to $30, and $0905 to 7. In both bit 0 clear cases it then commits the new Y with restore_player_y ($4256)."
  },
  {
   "address": 35662,
   "type": "line",
   "text": "Land on a stage object: sets $0905 to 1, calls player_land, and sets player_try_y to obj_hit_top for the object stand_obj ($1A), minus $031C and $031D. Then it commits the Y with restore_player_y ($4256)."
  },
  {
   "address": 35704,
   "type": "line",
   "text": "Harmful block under the player (bit 1 set): sets player_hit ($0292) to 1, jump_state ($08FA) to $FF, and jump_counter ($08FB) to $10. Sound $24 is queued with queue_sound ($0B8C); when $DF is non-zero (queue_sound refuses it then) the music is faded out instead through sid_start_fade_out ($6ED8, A = $25). Then it goes to hit_save_pos ($8E2F)."
  },
  {
   "address": 35736,
   "type": "line",
   "text": "Landing on a solid block. When up is held (bit 0 of joy_bits $08 clear) and fire is not pressed (bit 6 of fire_flags $08C6 set), the player jumps again at once: jump_state ($08FA) becomes $FF, jump_counter ($08FB) is loaded from $08FC, sound 0 is queued, and $0905 becomes 3. Otherwise $0905 becomes 1 and player_land runs. Either way it continues in snap_player_to_block."
  },
  {
   "address": 35778,
   "type": "line",
   "text": "Snap the player's feet to a block boundary. Adds $031C and $031D to player_try_y ($08BD/$08BE), rounds the sum down to a multiple of $10, subtracts $031D and $031C again, and stores the result in player_try_y. Then it commits the Y with restore_player_y ($4256)."
  },
  {
   "address": 35836,
   "type": "line",
   "text": "Mark the player as on the ground: jump_state ($08FA) and slope_kind ($0C) become 0, and $0902 and move_dir ($0D) become $FE."
  },
  {
   "address": 35847,
   "type": "line",
   "text": "Address inside the instruction at $8C05 (sta $0902 in player_land): the label sits on an operand byte. Its one reference is jsr $8C07 at $4033 in stage_intro_start, made with $01 = $37, so it runs the cartridge's code at $8C07 (in whichever bank $DE00 last selected), not these RAM bytes. What that cartridge routine does is not read here."
  },
  {
   "address": 35851,
   "type": "line",
   "text": "Slope check for an airborne player, entered from air_floor_check when $0291 has bit 2 or bit 3 set. When bit 0 of $0291 is set it goes straight to air_slope_land. Otherwise it takes (player_try_x $08BB plus $1F) AND $0F into $E2, and turns that into $0F minus itself when bit 3 of $0291 is clear. Then it compares ((player_try_y $08BD AND $0E) plus 1 plus $031C plus $031D) AND $0F with $E2. If that is smaller it goes to air_slope_commit, because the feet are still above the slope. If not, it falls into air_slope_land."
  },
  {
   "address": 35901,
   "type": "line",
   "text": "Land on a slope from the air: move_dir ($0D) becomes $FF, jump_state ($08FA) becomes 0, slope_kind ($0C) becomes 1 when bit 2 of $0291 is set and 2 otherwise, and $0905 becomes 1. Then player_try_y ($08BD/$08BE) is increased by 1 and it falls into air_slope_commit."
  },
  {
   "address": 35933,
   "type": "line",
   "text": "Commit the step: goes to restore_player_pos ($4246), which copies player_try_x and player_try_y into player_x and player_y."
  },
  {
   "address": 35936,
   "type": "line",
   "text": "Ground step to the left while slope_kind ($0C) is non-zero, entered from collide_ground_left. When slope_kind is 1 it goes to ground_slope_left_one. Otherwise it calls $9D3C and, if $0291 has bit 2 or bit 3 set (still on a slope), goes to ground_slope_commit. If not, it adds 6 to player_try_y ($08BD/$08BE) and goes to land_and_snap."
  },
  {
   "address": 35972,
   "type": "line",
   "text": "Ground step to the right with slope_kind ($0C) not equal to 1, reached from ground_slope_right. Calls $9D3C and, if $0291 has bit 2 or bit 3 set, goes to ground_slope_commit. Otherwise it goes to land_and_snap with player_try_y unchanged."
  },
  {
   "address": 35985,
   "type": "line",
   "text": "Ground step to the left with slope_kind ($0C) equal to 1, reached from ground_slope_left. Calls $9D3C and, if $0291 has bit 2 or bit 3 set, goes to ground_slope_commit. Otherwise, unless bit 1 of joy_bits ($08) is set, it sets $0905 and $0B to 5. Either way it ends in land_and_snap."
  },
  {
   "address": 36011,
   "type": "line",
   "text": "Ground step to the right while slope_kind ($0C) is non-zero, entered from collide_ground_right. When slope_kind is not 1 it goes to ground_slope_right_two. Otherwise it calls $9D3C and, if $0291 has bit 2 or bit 3 set, goes to ground_slope_commit. If not, it adds 6 to player_try_y ($08BD/$08BE) and, unless bit 1 of joy_bits ($08) is set, sets $0905 and $0B to 5. It ends in land_and_snap."
  },
  {
   "address": 36060,
   "type": "line",
   "text": "Commit the step: goes to restore_player_pos ($4246). Used by the ground slope routines when $0291 still has bit 2 or bit 3 set."
  },
  {
   "address": 36063,
   "type": "line",
   "text": "Airborne step up and to the right (move_dir $06). Calls $9C1E. When bit 0 is set in $E1, $E2, or $E3 the step is dropped with save_player_x ($4263); otherwise it is committed with restore_player_x ($4249). Both ways it ends in air_up_check."
  },
  {
   "address": 36086,
   "type": "line",
   "text": "Airborne step up and to the left (move_dir $0A). Same as air_up_right_x, but the block probe is $9BF6 instead of $9C1E. Both ways it ends in air_up_check."
  },
  {
   "address": 36112,
   "type": "line",
   "text": "Vertical check for an airborne player moving up. Calls $9D17 and merges $E1, $E2, and $E3. When bit 0 is set it goes to air_start_fall. Otherwise it commits the Y with restore_player_y ($4256), calls $9E69, and goes on to air_mode1_check. Also entered with move_dir $0E."
  },
  {
   "address": 36128,
   "type": "line",
   "text": "Calls $9E69, then tests bit 4 of $08E8 and $08E9; when either is clear it returns. When both are set it adds $E1/$E2 to player_x ($08B7/$08B8), sets $0B, $08FF, and jump_state ($08FA) to 0, player_mode ($09) to 1, move_step ($0A) to 2, $18 and move_dir ($0D) to $0E, and $0905 to 6 (the player enters mode 1). Entered from air_up_check, and from air_vertical."
  },
  {
   "address": 36188,
   "type": "line",
   "text": "Start a fall: jump_state ($08FA) becomes 1, jump_counter ($08FB) becomes 0, and it returns."
  },
  {
   "address": 36199,
   "type": "line",
   "text": "Carry the player along with the object it stands on; player_move calls it when stand_obj ($1A) is not negative (with X = stand_obj). It acts on ride_dir ($19): $0E goes to ride_up, $0D to ride_down, $0B to ride_left, $07 to ride_right, and any other value returns. ride_up places the player on the object and commits Y; ride_down does the same after a block test (a harmful block goes to ride_hit, a fast object to player_leave_object); ride_left and ride_right move player_prev_x by obj_speed and commit it unless a block is solid. Most paths end in ride_finish."
  },
  {
   "address": 36218,
   "type": "line",
   "text": "Case $0E of player_ride_object: calls place_player_on_object, commits the Y with restore_player_y ($4256), and goes to ride_finish."
  },
  {
   "address": 36227,
   "type": "line",
   "text": "Case $0D of player_ride_object. When $0295 is 7 or more it goes to player_leave_object. Otherwise it calls place_player_on_object and $9D3C and merges $E1, $E2, and $E3. With bit 1 set it goes to ride_hit; if not, it commits the Y with restore_player_y ($4256) and goes to ride_finish."
  },
  {
   "address": 36256,
   "type": "line",
   "text": "The player leaves the object: $0299 becomes 0, jump_state ($08FA) becomes 1, jump_counter ($08FB) becomes 8, and $0905 and $0903 become 3."
  },
  {
   "address": 36279,
   "type": "line",
   "text": "Case $0B of player_ride_object. Subtracts obj_speed ($34E1) for the object in X from player_try_x ($08BB/$08BC), calls $9BF6, and merges $E1, $E2, and $E3. With bit 0 set the step is not committed and it goes to ride_finish. Otherwise it commits with restore_player_x ($4249) and, when stand_obj ($1A) is not negative, goes to ride_finish; else it returns."
  },
  {
   "address": 36315,
   "type": "line",
   "text": "Case $07 of player_ride_object. Same as ride_left, but it adds obj_speed ($34E1) to player_try_x, and the block probe is $9C1E instead of $9BF6."
  },
  {
   "address": 36351,
   "type": "line",
   "text": "End of a ride step: clears bit 7 of obj_flags ($364C) for the object stand_obj ($1A) and calls $AC13. When stand_obj is still not negative it returns; otherwise it goes to player_leave_object."
  },
  {
   "address": 36370,
   "type": "line",
   "text": "Harmful block while riding an object (bit 1 set), reached from ride_down ($8D98): sets player_hit ($0292) to 1, jump_state ($08FA) to $FF, and jump_counter ($08FB) to $10. Sound $24 is queued with queue_sound ($0B8C), and when music_mode ($DF) is non-zero a fade-out is started with sid_start_fade_out ($6ED8, A = $25). It falls into hit_save_pos."
  },
  {
   "address": 36399,
   "type": "line",
   "text": "Remember where the player was hit: stores player_x ($08B7/$08B8) in player_hit_x ($08E3/$08E4) and player_y ($08B9/$08BA) in player_hit_y ($08E5/$08E6). A word whose high byte is negative is stored as 0. Reached by falling in from ride_hit, by a jump from air_hit_hazard ($8B95), and by jsr from level_timer_tick ($82DF, when time runs out) and the hit code at $A64E; each first queues sound $24 and, with music on, starts the fade-out."
  },
  {
   "address": 36453,
   "type": "line",
   "text": "Put the player on the object in X: stores the object's Y position (obj_y_lo $39A6 and obj_y_hi $3A03) minus $031D and then minus $031C in player_try_y ($08BD/$08BE). It loads Y from stand_obj ($1A) but does not use it. ride_up commits the Y with restore_player_y ($4256) straight after; ride_down does so only when the probe that follows finds no harmful block."
  },
  {
   "address": 36488,
   "type": "line",
   "text": "Mode 2 movement for one frame, jumped to from player_mode_step for any player_mode ($09) other than 0 and 1. Keeps only bit 6 of fire_flags ($08C6), so bit 7 is clear and the position steps are never skipped, sets player_action ($0905) to 7, runs mode2_move ($8E9B) to pick and apply the direction, and goes to mode2_collide ($8F73) to check the new position."
  },
  {
   "address": 36506,
   "type": "line",
   "text": "Address inside the instruction at $8E98 (jmp $8F73 in player_mode2_step): the label sits on an operand byte. Its one reference is jsr $8E9A at $4066 in j_403A, made with $01 = $37, so it runs the cartridge's code at $8E9A (in whichever bank $DE00 last selected), not these RAM bytes. What that cartridge routine does is not read here."
  },
  {
   "address": 36507,
   "type": "line",
   "text": "Choose the direction in mode 2 and step player_try_x or player_try_y. Sets move_dir ($0D) to $FF first. While jump_state ($08FA) is non-zero it runs mode2_jump_motion ($8F12) and then steps sideways by the facing flag $18: bit 3 clear steps right ($0D masked with $07, then $42F8), bit 3 set steps left ($0D masked with $0B, then $42E1). When jump_state is zero it follows joy_bits ($08): $07 is right, $0B left, $0E up ($430F), and $0D down ($4326), and the diagonals $06, $05, $09, and $0A do one vertical step and one horizontal step. The joy_bits value is stored in move_dir; any other value leaves $FF."
  },
  {
   "address": 36626,
   "type": "line",
   "text": "Vertical motion of the mode 2 jump, the reverse of player_jump_motion, using jump_state ($08FA) and jump_counter ($08FB) on player_try_y ($08BD/$08BE). A jump_state of 0 does nothing. A negative one clears bit 1 of move_dir ($0D), adds $02CE[x] to player_try_y, where x is jump_counter limited to 16, and subtracts the same amount from jump_counter; when jump_counter would reach zero or below, jump_state becomes 1 and jump_counter 0. A positive one clears bit 0 of move_dir, subtracts $02DF[x] with x as jump_counter, and then adds one to jump_counter, or sets jump_state to 0 when x is 8 or more. Entering mode 2 from the air ($8B37) sets $FF and $30, so the player first moves down the screen and then back up; the stage-start entry at $500A sets neither."
  },
  {
   "address": 36723,
   "type": "line",
   "text": "Second half of mode 2 movement (from player_mode2_step). While jump_state ($08FA) is non-zero it commits player_try_y with $4256 unchecked, then probes the sideways step ($9BF6 when bit 3 of move_dir ($0D) is set, otherwise $9C1E). When bit 0 is clear in $E1, $E2, and $E3 it commits X with $4249; otherwise it flips bits 2 and 3 of move_dir and stores the result in move_dir and $18, turning the player round. On the ground it returns while move_dir is negative; otherwise bit 2 clear probes left ($9BF6), else bit 3 clear probes right ($9C1E), and it commits X with $4249 or cancels it with save_player_x ($4263), cancelling without a probe when both bits are set. Then it handles up ($0D bit 0 clear, probe $9D17) and down (bit 1 clear, probe $9D3C). A block with bit 0 set stops the step; otherwise it commits Y with $4256. Going up with bit 6 clear in the probe results also sets player_mode ($09) to 0, jump_state to $FF, jump_counter ($08FB) to $08FC plus $10, and player_action ($0905) to 3."
  },
  {
   "address": 36901,
   "type": "line",
   "text": "Mode 1 movement for one frame, jumped to from player_mode_step when player_mode ($09) is 1. When $08FF is non-zero it goes straight to mode1_collide ($919E). Otherwise it rewrites fire_flags ($08C6), first setting $0903 to $FF when bits 7 and 6 are both set, then keeping bit 6 and setting bit 7 when bit 6 is clear. Then it runs mode1_move_vertical ($9055) when $0B is zero or mode1_move_horizontal ($917A) otherwise, and goes to mode1_collide."
  },
  {
   "address": 36949,
   "type": "line",
   "text": "Mode 1 movement when $0B is zero. Returns at once while bit 7 of fire_flags ($08C6) is set. Sets player_action ($0905) to 6, and sets jump_state ($08FA) to $FF when bits 2 and 3 of joy_bits ($08) are both set (neither left nor right). While jump_state is not negative only the vertical bits count: bit 1 clear steps down ($0D, $4326), else bit 0 clear steps up ($0E, $430F), and with neither move_dir ($0D) becomes $FF. With jump_state negative, exactly $0E and $0D step up and down, and otherwise left or right (diagonals included) sets move_dir to $0B or $07, moves player_try_x by 4 that way, and probes with $9BF6 or $9C1E. When bit 0 is clear in $E1, $E2, and $E3 it sets player_mode ($09) to 0, player_third_on ($0913) to 1, and queues sound 0 with queue_sound ($0B8C); otherwise mode1_step_blocked tries down, then up."
  },
  {
   "address": 37056,
   "type": "line",
   "text": "Tail of mode1_step_left, fallen into after its probe at $90B9 and the first two ORs: ORs in $E3, and if bit 0 of $E1/$E2/$E3 is set the step is blocked and it branches to mode1_step_blocked. Otherwise it clears $09, sets player_third_on to 1 and queues sound 0 through queue_sound. The label is here because stage_start ($0B25) reads $90C0,x with $01 = $37 and cartridge bank 13 selected, copying 256 bytes of the cartridge from $90C0 to $FD00; that read never touches this RAM."
  },
  {
   "address": 37075,
   "type": "line",
   "text": "The step was blocked. Reads the direction bits in joy_bits ($08, 0 = pressed): if bit 1 is clear (down) it goes to mode1_down_set, else if bit 0 is clear (up) it goes to mode1_up_set (try moving vertically instead). With neither, it stores $FF in move_dir ($0D, no move) and returns. Reached from mode1_step_left ($90C4) and mode1_step_right ($9104)."
  },
  {
   "address": 37092,
   "type": "line",
   "text": "Walks the player right by 4 pixels in the 16-bit try X position (player_try_x, player_try_x_hi), after setting move_dir ($0D) to 7, the right direction code. Then probe_player_tiles checks the tiles there. If blocked it goes to mode1_step_blocked, else it clears $09, sets player_third_on to 1 and queues sound 0. Reached from mode1_move_vertical ($9085) when right is pressed."
  },
  {
   "address": 37139,
   "type": "line",
   "text": "Return in A the smallest of the eight bytes of spr_free_line ($07CF-$07D6), one per hardware sprite slot. Called from $8147. Each slot is compared with the running minimum, starting from slot 0."
  },
  {
   "address": 37200,
   "type": "line",
   "text": "Start an object on a path from the record at ($E3),Y. X is the object. The byte at Y is skipped; the bytes at Y+1 and Y+2 go to obj_arc_state ($3F19,X) and obj_arc_counter ($3F76,X, the slot in the path tables). The byte at Y+3 is kept in $ED and the one at Y+4 is stored in path_end ($5C), $ED in path_axes ($60), and 0 in path_pos ($64), all at that slot. Y is left at Y+4 (from $EB) and the routine returns with carry set. It is the handler for script command $15 (entry 21 of the tables at $B33C/$B35F), reached from the dispatch at $B217-$B224."
  },
  {
   "address": 37242,
   "type": "line",
   "text": "Mode 1 movement when $0B is non-zero. Sets player_action ($0905) to 5. Right in joy_bits ($08, bit 3 clear) sets move_dir ($0D) to $07 and steps right with $42F8; otherwise left (bit 2 clear) sets $0B and steps left with $42E1; otherwise move_dir becomes $FF."
  },
  {
   "address": 37278,
   "type": "line",
   "text": "Second half of mode 1 movement, reached from player_mode1_step. When $08FF is negative it is set to 0, and when it is positive nothing more happens. When $08FF is zero and $0B is non-zero, move_dir ($0D) of $07 goes to $9276 and $0B to $92AD. When $0B is zero, $0E goes to mode1_up_end ($91CF), $0D to $91EB, and left (bit 2 clear) or right (bit 3 clear) to $9207 or $921C, which move player_x by 8 and start a jump back in mode 0. mode1_up_end probes with $9D17; when $0291 is non-zero it commits Y with $4256, otherwise it sets player_third_on ($0913) to 0, $0903 to 1, and $08FF to 2."
  },
  {
   "address": 37306,
   "type": "line",
   "text": "Vertical half of mode 1 movement, entered when $0B is zero. Reads move_dir ($0D): $0E goes to mode1_up_end, $0D to mode1_down_end. Otherwise bit 2 clear (the left code $0B) goes to mode1_step_left_8, and bit 3 clear (the right code $07) to mode1_step_right_8; any other value returns."
  },
  {
   "address": 37311,
   "type": "line",
   "text": "Address inside the instruction at $91BE (beq $91CF in mode1_vertical_collide): the label sits on an operand byte. Its references are lda $91BF,x at $50C8 and $50E9 in copy_sprite_shapes, made with $01 = $37 and cartridge bank 13 selected: they read the low bytes of the shape addresses for player_shape_1 and player_shape_2 from the cartridge (high bytes at $9202), not these RAM bytes."
  },
  {
   "address": 37312,
   "type": "line",
   "text": "Continuation of mode1_vertical_collide (the run starts in the operand of the beq at $91BE): compares move_dir ($0D) with $0D and branches to mode1_down_end ($91EB) if equal. Otherwise bit 2 clear (the left code) goes to mode1_step_left_8; failing that, bit 3 clear (the right code) goes to mode1_step_right_8, and any other value returns."
  },
  {
   "address": 37327,
   "type": "line",
   "text": "Entry for move_dir $0E. Calls $9D17, then if $0291 is non-zero jumps to $91F5, which commits the Y position with restore_player_y. Otherwise clears player_third_on ($0913), sets $0903 to 1 and $08FF to 2, and returns."
  },
  {
   "address": 37355,
   "type": "line",
   "text": "Entry for move_dir $0D (the code the object path script uses for down; inferred to be down here too). Calls player_probe_tiles_and_platforms. If bit 4 of $0291 is set it jumps to $91F5 and commits the Y position with restore_player_y. Otherwise it falls into mode1_down_check."
  },
  {
   "address": 37368,
   "type": "line",
   "text": "Calls $9BF6, then ORs the tile attribute bytes $E1, $E2 and $E3 and tests bit 0. When it is set, control goes to mode1_set_dir_07; when clear, to mode1_set_dir_0B. The meaning of the bit is not established here."
  },
  {
   "address": 37378,
   "type": "line",
   "text": "Address inside the instruction at $9201 (and #$01 in mode1_down_check): the label sits on an operand byte. Its references are lda $9202,x at $50CD and $50EE in copy_sprite_shapes, made with $01 = $37 and cartridge bank 13 selected: they read the high bytes of the shape addresses for player_shape_1 and player_shape_2 from the cartridge (low bytes at $91BF), not these RAM bytes."
  },
  {
   "address": 37383,
   "type": "line",
   "text": "Moves player_x ($08B7/$08B8) left by 8 pixels, loads $0B (the left direction code) and joins mode1_start_jump. Reached from mode1_vertical_collide when move_dir has bit 2 clear."
  },
  {
   "address": 37404,
   "type": "line",
   "text": "Moves player_x ($08B7/$08B8) right by 8 pixels, loads $07 (the right direction code) and falls into mode1_start_jump. Reached from mode1_vertical_collide when move_dir has bit 3 clear."
  },
  {
   "address": 37423,
   "type": "line",
   "text": "Shared tail. Stores the direction code in $18, sets jump_state ($08FA) to $FF, clears $09 and $0C, sets move_step ($0A) to 2 and jump_counter ($08FB) to $10, sets player_action ($0905) to 3, and queues sound 0 through queue_sound. Mode 1 hands back to mode 0 here, as a jump (inferred from the jump_state and jump_counter names)."
  },
  {
   "address": 37444,
   "type": "line",
   "text": "End of mode1_start_jump's shared tail ($922F): sets player_action ($0905) to 3 and queues sound 0 through queue_sound, which returns to the caller. The run listed at $9245 starts inside the operand of the lda at $9244."
  },
  {
   "address": 37445,
   "type": "line",
   "text": "Address inside the instruction at $9244 (lda #$03 in mode1_start_jump): the label sits on an operand byte. Its reference is lda $9245,x at $50A7 in copy_sprite_shapes, made with $01 = $37 and cartridge bank 13 selected: it reads the low bytes of the shape addresses for player_shape_3 from the cartridge (high bytes at $9263), not these RAM bytes."
  },
  {
   "address": 37454,
   "type": "line",
   "text": "Loads direction code $0B (left) and goes to mode1_set_dir_tail."
  },
  {
   "address": 37458,
   "type": "line",
   "text": "Loads direction code $07 (right) and falls into mode1_set_dir_tail."
  },
  {
   "address": 37460,
   "type": "line",
   "text": "Shared tail. Stores the direction code in $18, clears $09 and $0C, sets jump_state ($08FA) to 1, move_step ($0A) to 2, jump_counter ($08FB) to 1 and player_action ($0905) to 3, then queues sound 0 through queue_sound. Like mode1_start_jump but with jump_state and jump_counter set to 1, which looks like the start of a fall rather than a rise (inferred)."
  },
  {
   "address": 37475,
   "type": "line",
   "text": "Last part of mode1_set_dir_tail: sets jump_counter ($08FB) to 1 and player_action ($0905) to 3, then queues sound 0 through queue_sound, which returns to the caller. The tail's first part ($9254) set the direction, jump_state and move_step."
  },
  {
   "address": 37494,
   "type": "line",
   "text": "Resolve a mode 1 sideways step to the right: reached only from mode1_horizontal_collide ($91E8) when move_dir is $07 ($92AD is the left-hand sibling, for $0B). Probes the tiles around the player (probe_player_tiles); if any of $E1-$E3 has bit 0 set the move is blocked and the routine ends at $92AC without committing. Otherwise it continues at $9283, which commits the new X with restore_player_x and probes again."
  },
  {
   "address": 37506,
   "type": "line",
   "text": "Address inside the instruction at $9281 (bne $92AC in player_step_check_first_dir): the label sits on an operand byte. Its reference is lda $9282,x at $5227 in game_init, made with $01 = $37 and cartridge bank 13 selected: it copies 64 bytes of the cartridge ($9282-$92C1) to the RAM under I/O at $D040, and never touches these RAM bytes."
  },
  {
   "address": 37507,
   "type": "line",
   "text": "Second half of player_step_check_first_dir, reached when none of $E1-$E3 has bit 0 set. Calls restore_player_x ($4249), which commits the new X (player_try_x to player_x), probes again with player_probe_tiles_and_platforms, and returns if bit 0 of $E1 is clear. Otherwise it picks a direction code from bit 1 of joy_bits ($08, 0 = pressed): set (down not pressed) gives $07 (jumps to $92CE), clear (down) gives $05, which is stored in $18 and move_dir ($0D) here; $09, jump_state ($08FA) and $0C are cleared and stance ($0299) set to 1. The run before this address ends in the operand of the bne at $9281, so the first real instruction is at $9283."
  },
  {
   "address": 37549,
   "type": "line",
   "text": "Second variant of the move-step check: probes with $9BF6 and returns if bit 0 of $E1, $E2 or $E3 is set; otherwise restores x (restore_player_x) and re-probes. If bit 0 of $E3 is then set: with joy_bits bit 1 set, $18 becomes $0B and player_action 1 (via $92CE); with it clear, $18 and move_dir become 9 and $0299 becomes 1 (via $9272). Both clear player_mode, jump_state and slope_kind. Direction meaning inferred."
  },
  {
   "address": 37599,
   "type": "line",
   "text": "Last step of update_player. First it updates the energy bar: when $08CB is non-zero it takes the low 5 bits of the health of object $08CC into $08A1 and draws the bar with $831B; when $08CB is zero and player_hit ($0292) is zero it calls update_view_scroll ($470C). Then, while the player is not hit, it takes a probe point (player_x plus $18, and player_y plus $031C, with their high bytes $08B8 and $08BA) and finds the stage section that holds it. The current section record is the one at ($26) and the section number is section_index ($0298); $93CD tests the point against the bounds in the record (offsets $0E to $15: x low and high, then y low and high, each as two bytes). When the point is outside, it tries the next section (up to the limit $0C06) and then the previous one, using the record addresses at $0D22, and on a match stores the new index and pointer and falls into $936E."
  },
  {
   "address": 37742,
   "type": "line",
   "text": "Copy the settings of the section record at ($26) into working variables: bytes 0 to 5 to zone_left ($0908/$0909), zone_right ($0906/$0907), zone_top ($090A) and zone_bottom ($090B), the edges of the zone in which the view does not follow the player; byte $16 to section_scroll_flags ($08FD); and bytes $17 and $18 to obj_first and obj_end. view_pinned_edges ($08FE) is cleared, and bit 2 of $08FD is cleared unless it is set and the low two bits of $08FD differ from stream_current ($08A7), in which case those bits are stored in $08A7 and bits 2 and 3 of $08FD are set (start a new background stream). Called when the player enters a new section (falling in from track_stage_section), and from $5048 (finish_round_setup) during stage setup."
  },
  {
   "address": 37837,
   "type": "line",
   "text": "Test whether the point at $E1/$E2 (x) and $E3/$E4 (y) lies inside the section record at ($E5): it compares each coordinate with the 16-bit minimum and maximum at offsets $0E to $15. Returns with the carry set when the point is inside and clear when it is outside."
  },
  {
   "address": 37888,
   "type": "line",
   "text": "Look up the block property at a position. The inputs are A (added to the x position $E7/$E8), Y (added to the y position $E9/$EA), and the 16-bit position itself. Both sums are divided by 16 to give a block column ($EB) and row ($EC); the row picks a row pointer from the tables at ($2A) and ($2C), the column picks a block number from that row, and the block number picks the property byte in the table at ($30), which comes back in A. A row above the top of the map (the high byte of Y plus $E9/$EA negative) returns 0. Used by the object code at $84B5 and $AA3C; the same lookup idea gives the tile bits that the player code tests (for example bit 0 solid and bit 1 harmful)."
  },
  {
   "address": 37955,
   "type": "line",
   "text": "Redraws the whole playfield from the level map. Each map byte (found through row pointers $2A/$2C, starting at scroll_x/2 and scroll_y/2) selects a 2x2-character tile in the table at ($2E); its four characters are written to screen RAM (buffer pointed to by $08BF) and the matching colours from char_colour_table ($0C22) to colour RAM at $D800, 20 tiles per row pair. Finishes by tail-jumping to recolour_screen."
  },
  {
   "address": 38170,
   "type": "line",
   "text": "Copy the logical sprite list into the hardware sprite tables ($07B4-$07E6) in top-to-bottom order. It starts at slot 0, or slot 1 when place_third_sprite already used slot 0 (spr_enable $07B2 non-zero). It walks sprite_y_buckets ($7CBD) from the top: positions with bit 7 set are skipped, $7F ends the list, any other value is a logical sprite number, and each position it consumes (the $7F included) is reset to $FF. For each sprite it copies the pointer ($0838) to spr_pointer ($07C7), the colour ($0808) to spr_colour ($07B4), and the X low ($0850) and Y ($0880) to the X and Y pair at $07D7/$07D8 (two bytes per slot); it sets the slot's bit in spr_x_msb ($07B1) when the X high byte ($0868) is non-zero; and it sets spr_free_line ($07CF) to Y + $16, or Y + $2B when the colour's bit 7 is set, in which case the slot's bit is also set in spr_expand ($07B3). It stops after eight slots, leaving in sprite_more ($6B) the list position of the last sprite copied, or at the end of the list, leaving 0 there. Then it sets spr_enable from the table at $02A6 (one bit for each slot used). wait_nmi uses $6B to choose the raster interrupt at $95A4 when it is non-zero."
  },
  {
   "address": 38308,
   "type": "line",
   "text": "Raster interrupt that reuses the eight hardware sprites for the logical sprites left over after copy_sprites_to_tables ($951A) filled them. wait_nmi ($8134) puts this address in raster_vector ($07AB) for nmi_frame to install when $6B (sprite_more) is non-zero. It saves A, X, and Y in $68-$6A, acknowledges the raster flag ($D019), and takes Y from $0807 (the position of the last entry placed, $FF at the start of a frame). Each pass of the loop at $95B0 advances Y and loads X from the list at $007E,Y: a logical sprite number, or a negative value that ends the list. The entries are then dealt to hardware sprites 0 to 7 in turn: each takes the next sprite in that order whose free line in $6C-$73 has passed, and the walk wraps back to sprite 0 only after sprite 7. $0200-$0278 hold the logical sprite's colour with bit 7 for double size ($0200), height ($0218), pointer ($0230), X low ($0248), X high ($0260), and Y ($0278)."
  },
  {
   "address": 38320,
   "type": "line",
   "text": "Take the next entry of the leftover list: Y is advanced and X loaded from $007E,Y. A negative entry ends the list and jumps to reuse_end_of_list ($98AA). Reached from the start of sprite_reuse_irq, from the last hardware sprite block, and when reuse_wait_free_sprite finds a free line already passed."
  },
  {
   "address": 38328,
   "type": "line",
   "text": "Try to use hardware sprite 0 for the logical sprite in X. The sprite is free when its free line $6C (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_1 ($9615) with carry set. When free it copies Y ($0278,X) to $D001, X low ($0248,X) to $D000, and X high ($0260,X, non-zero sets the bit) into bit 0 of $D010; the colour ($0200,X) to $D027, with bit 7 setting bit 0 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBF8 and $CFF8 on both screens. It then stores Y plus the height ($0218,X) in $6C as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38421,
   "type": "line",
   "text": "Try to use hardware sprite 1 for the logical sprite in X. The sprite is free when its free line $6D (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_2 ($9672) with carry set. When free it copies Y ($0278,X) to $D003, X low ($0248,X) to $D002, and X high ($0260,X, non-zero sets the bit) into bit 1 of $D010; the colour ($0200,X) to $D028, with bit 7 setting bit 1 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBF9 and $CFF9 on both screens. It then stores Y plus the height ($0218,X) in $6D as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38514,
   "type": "line",
   "text": "Try to use hardware sprite 2 for the logical sprite in X. The sprite is free when its free line $6E (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_3 ($96CF) with carry set. When free it copies Y ($0278,X) to $D005, X low ($0248,X) to $D004, and X high ($0260,X, non-zero sets the bit) into bit 2 of $D010; the colour ($0200,X) to $D029, with bit 7 setting bit 2 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFA and $CFFA on both screens. It then stores Y plus the height ($0218,X) in $6E as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38607,
   "type": "line",
   "text": "Try to use hardware sprite 3 for the logical sprite in X. The sprite is free when its free line $6F (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_4 ($972C) with carry set. When free it copies Y ($0278,X) to $D007, X low ($0248,X) to $D006, and X high ($0260,X, non-zero sets the bit) into bit 3 of $D010; the colour ($0200,X) to $D02A, with bit 7 setting bit 3 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFB and $CFFB on both screens. It then stores Y plus the height ($0218,X) in $6F as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38700,
   "type": "line",
   "text": "Try to use hardware sprite 4 for the logical sprite in X. The sprite is free when its free line $70 (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_5 ($9789) with carry set. When free it copies Y ($0278,X) to $D009, X low ($0248,X) to $D008, and X high ($0260,X, non-zero sets the bit) into bit 4 of $D010; the colour ($0200,X) to $D02B, with bit 7 setting bit 4 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFC and $CFFC on both screens. It then stores Y plus the height ($0218,X) in $70 as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38793,
   "type": "line",
   "text": "Try to use hardware sprite 5 for the logical sprite in X. The sprite is free when its free line $71 (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_6 ($97E6) with carry set. When free it copies Y ($0278,X) to $D00B, X low ($0248,X) to $D00A, and X high ($0260,X, non-zero sets the bit) into bit 5 of $D010; the colour ($0200,X) to $D02C, with bit 7 setting bit 5 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFD and $CFFD on both screens. It then stores Y plus the height ($0218,X) in $71 as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38886,
   "type": "line",
   "text": "Try to use hardware sprite 6 for the logical sprite in X. The sprite is free when its free line $72 (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_hw_sprite_7 ($9843) with carry set. When free it copies Y ($0278,X) to $D00D, X low ($0248,X) to $D00C, and X high ($0260,X, non-zero sets the bit) into bit 6 of $D010; the colour ($0200,X) to $D02D, with bit 7 setting bit 6 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFE and $CFFE on both screens. It then stores Y plus the height ($0218,X) in $72 as the line where the sprite frees up; steps to the next entry and goes to the next hardware sprite, or to reuse_end_of_list when the list has ended."
  },
  {
   "address": 38979,
   "type": "line",
   "text": "Try to use hardware sprite 7 for the logical sprite in X. The sprite is free when its free line $73 (minus one) is below the raster line in $D012; if it is not, the code goes on to reuse_wait_free_sprite ($989B): the walk for this entry has reached the last sprite. When free it copies Y ($0278,X) to $D00F, X low ($0248,X) to $D00E, and X high ($0260,X, non-zero sets the bit) into bit 7 of $D010; the colour ($0200,X) to $D02E, with bit 7 setting bit 7 of both the double-width ($D01D) and double-height ($D017) registers; and the pointer ($0230,X) to $CBFF and $CFFF on both screens. It then stores Y plus the height ($0218,X) in $73 as the line where the sprite frees up and goes back to reuse_next_entry ($95B0), which starts again at sprite 0."
  },
  {
   "address": 39067,
   "type": "line",
   "text": "Reached when hardware sprite 7 is busy at the end of the walk for an entry (the sprites before the walk's starting point were not retested). Y is stepped back so the same entry is tried again, and lowest_free_line ($98C5) returns the earliest free line of all eight in A. When that line minus two is still ahead of the raster line, it jumps to reuse_set_next_irq ($98B8) to schedule the interrupt at that line; otherwise the line is about to pass and it retries at reuse_next_entry ($95B0), from sprite 0."
  },
  {
   "address": 39082,
   "type": "line",
   "text": "The leftover list is finished. It points the interrupt vector ($FFFE/$FFFF) back to irq_panel ($837E), sets X = $D5 for the next raster line and Y = $FF for $0807 (so the next frame starts at the first entry), and falls into reuse_set_next_irq."
  },
  {
   "address": 39096,
   "type": "line",
   "text": "Leave the interrupt: write X to the raster line register $D012 and Y to $0807, restore A, X, and Y from $68-$6A, and return with RTI. Entered with the next line in X and the list position in Y."
  },
  {
   "address": 39109,
   "type": "line",
   "text": "Return in A the smallest of the eight hardware-sprite free lines $6C-$73 (the first sprite to become free), with carry clear. Called once, by reuse_wait_free_sprite."
  },
  {
   "address": 39155,
   "type": "line",
   "text": "Choose the player's two body shapes and offsets each frame from the action number $0905 and the facing flag $18 (bit 3 set for left; $07 right, $0B left, and $05, $06, $09, $0A or $0E in some states). While player_hit ($0292) is non-zero it switches the third sprite off, clears $0900 and sets player_shape_1 and player_shape_2 to $28 and $34, or $29 and $35, by bit 2 of $18. Otherwise actions 0-2 use the table at $0458 or $046C by facing, 3 uses $04C0 or $04CA, 4 uses $04AC or $04B6; 5 and 6 go to $9A2A ($0480, $0490, $04A0) and 7 to $9BAB ($0438, $0448). Each table starts with its length; the frame index $0902 steps by 2 and wraps at it, the shape pair is read at offset 8 plus the index, and bytes 1 to 7 give $0322, $0323, $0900 and $031A-$031D. A step comes after a hold count in $0901, at once when $0903 is set or when the state-and-facing key in $0296 changes ($0902 is kept). While $08FF is non-zero ($9A2A) it plays a transition from $04E8 and $04EC and moves player_y."
  },
  {
   "address": 39926,
   "type": "line",
   "text": "Player terrain probe, one-column variant (sibling of probe_player_tiles at $9C1E, which also adds the second X offset $031B). If $029C is clear and player_screen_x is below $0C (player at the left screen edge), sets the probe results $E2, $E3 and $E4 to 3 and returns without reading the map; 3 is probably a solid attribute, inferred, so the edge acts as a wall. Otherwise falls to $9C0B."
  },
  {
   "address": 39947,
   "type": "line",
   "text": "Computes the probe X position: player_try_x ($08BB/$08BC) plus offset $031A, stored in $E5/$E6, then jumps to $9C50, the Y computation shared with probe_player_tiles."
  },
  {
   "address": 39966,
   "type": "line",
   "text": "Player terrain probe for the box's right-hand edge: looks up the map tile attribute values in the column at player_try_x ($08BB/$08BC) plus offsets $031A and $031B, and stores them in $E1 (top cell of that column), $E2 (the next cell below when the height $031D allows, otherwise the same as $E1) and $E3 (the cell at the lower edge). The top is player_try_y ($08BD/$08BE) plus $031C plus 2 (clamped to 0 if negative); positions are divided by 16 into tile columns and rows; it indexes the row pointer tables at ($2A)/($2C) with the row, then the block map row with the column ($E9), then the tile attribute table at ($30). If the player is on the right side of the screen ($029C set and player_screen_x $029B >= $25) it just sets $E2-$E4 = 3 and returns. probe_player_tiles_one_column ($9BF6) is the left-edge sibling."
  },
  {
   "address": 40215,
   "type": "line",
   "text": "Player terrain probe, one-row variant (sibling of player_probe_tiles_and_platforms at $9D3C, which also adds the second Y offset $031D). Sets $F0 to $FF, computes Y = player_try_y ($08BD/$08BE) plus offset $031C into $EA/$EB, and if the result is negative (above the top of the map) goes to $9D30. Otherwise jumps to probe_columns_from_y ($9D61) to work out the X columns."
  },
  {
   "address": 40240,
   "type": "line",
   "text": "Probe result for a position outside the map: clears the tile attribute results $E1, $E2 and $E3 and $0291 to zero and returns."
  },
  {
   "address": 40252,
   "type": "line",
   "text": "Probes the tile attribute bytes around the player's previous position (player_try_x $08BB/$08BC, player_try_y $08BD/$08BE plus offsets $031A-$031D) and then checks the object list. Y sum goes to $EA/$EB and $EE/$EF, X to $E5/$E6; a negative high byte jumps to $9D30 (outside this stretch, which zeroes $E1-$E3 and $0291). Tile row pointers come from ($2A) and ($2C) indexed by row, tile ids from the row, attribute bytes from table ($30): left column to $E1, second column to $E2 (only when $031B is above $10), column at prev_x+$1F to $0291, right edge column to $E3. Sets $F0 to 0 here; the sibling entry at $9D17 sets it to $FF and joins at $9D61. Callers are not shown."
  },
  {
   "address": 40289,
   "type": "line",
   "text": "Entry for the sibling code at $9D17 (jmp from $9D2D) and fall-in point of $9D3C: starts the x tile computation from player_try_x with offset $031A."
  },
  {
   "address": 40381,
   "type": "line",
   "text": "Runs on every pass of the probe: branched to when $031B is $10 or less (second column not read), and fallen into after the second column. Takes the tile at try X ($08BB/$08BC) plus $1F in the same row and stores its attribute in far_column_prop ($0291), then computes the right edge column (the left X in $E5/$E6 plus $031B, also kept in $EC/$ED) and stores its attribute in $E3."
  },
  {
   "address": 40455,
   "type": "line",
   "text": "If $F0 bit 7 is set (the $9D17 entry), returns at once. If $19 equals $0D, goes to $9E5E. If any of $E3, $E1, or $E2 is nonzero, goes to $9E59 (no platform)."
  },
  {
   "address": 40474,
   "type": "line",
   "text": "Loops over the $0910 entries of the list at $74 (X counts down; negative ends the scan). For each object Y = list entry: needs $EE/$EF minus obj_hit_top $3D48/$3DA5 to be between 0 and 7, then horizontal overlap (obj_hit_right $3C8E/$3CEB at or past $E5/$E6, and $EC/$ED at or past obj_hit_left $3BD4/$3C31). On a match sets bit 7 of obj_flags $364C,y, stores Y in $1A, and returns."
  },
  {
   "address": 40536,
   "type": "line",
   "text": "Return."
  },
  {
   "address": 40537,
   "type": "line",
   "text": "Sets $1A to $FF (no object found) and returns."
  },
  {
   "address": 40542,
   "type": "line",
   "text": "Used when $19 is $0D: sets bit 7 of obj_flags $364C for the object already in $1A, then returns without scanning."
  },
  {
   "address": 40553,
   "type": "line",
   "text": "Looks up the two map tiles under the player's previous position and stores their property bytes. Takes the previous position ($08BB/$08BD plus offsets $22 across and $04 down for the head probe, $25 further down for the feet probe), turns them into tile column and row (divide by 16), reads the tile numbers from the level map through the row pointer tables at $2A/$2C, then looks each tile up in the property table at ($30) and puts the results in $08E8 (head) and $08E9 (feet). If the feet probe is above the top of the map it clears both and returns. Also leaves 8 minus the pixel offset within the tile in $E1/$E2. Used as the player's terrain check; the exact meaning of the property bits is inferred, not shown here."
  },
  {
   "address": 40709,
   "type": "line",
   "text": "Set aim_dir ($0297) when the player is not shooting; update_player skips it while bit 7 of fire_flags ($08C6) is set. In mode 1 with $0B equal to 0 it folds the direction to 0 (up, facing right) when it is below 5 and to 9 (up, facing left) otherwise. In mode 2 it always uses the facing: 7 when bit 3 of $18 is set (left), otherwise 2 (right). In mode 0, and in mode 1 with $0B non-zero, it uses slope_aim_dir ($AB74) when slope_kind ($0C) and stance ($0299) are both non-zero, which picks 3 or 8 for slope kind 2 and 1 or 6 for any other by the facing flag $18; otherwise the same 7 or 2 by facing. The result is the direction that player_fire ($AF34) uses for the next shot."
  },
  {
   "address": 40770,
   "type": "line",
   "text": "Put the player's first two sprites into the logical sprite list. player_sprite_coords ($9FC0) first turns the player's world position into screen coordinates. Then, if the shape number player_shape_1 ($08EA) is non-zero and its Y ($08ED) is between $1A and $D3, it fills entry 0 of the tables at $0808-$0880 (colour from $0914, X from $08F0/$08F3, Y from $08ED, height $15, pointer $FC, which is the shape block at $FF00) and files the entry in sprite_y_buckets ($7CBD) at Y / 2. The same is done for player_shape_2 ($08EB) with pointer $FD (the block at $FF40), colour $0915, and X and Y from $08F1/$08F4 and $08EE. If the bucket at Y / 2 is already taken by the first sprite, the second entry goes in the next bucket. It leaves the number of entries in sprite_count ($12) and the bucket position in sprite_bucket_max ($13), where object_sprites_and_hits carries on."
  },
  {
   "address": 40896,
   "type": "line",
   "text": "Turn the player's world position into sprite coordinates. X of the first sprite ($08F0 low, $08F3 high) is player_x minus view_left ($40/$41) plus $20 plus $0322; Y ($08ED) is player_y minus view_top ($42/$43) plus $37 plus $0323, checked by clamp_sprite_y. The third sprite's X ($08F2/$08F5) and Y ($08EF) are worked out the same way from $08B3 and $08B5, but without $0322 and $0323. The second sprite ($08F1/$08F4, $08EE) goes $18 pixels to the right of the first when $0900 is non-zero, otherwise $15 lines below it. It also leaves X before $0322 in $029B/$029C and a Y in $029D."
  },
  {
   "address": 41105,
   "type": "line",
   "text": "Check a screen Y value passed in A (high byte) and X (low byte): a negative value becomes 0 in both X and Y, a value of $D4 or more becomes $DE in both, and anything else is left as it is (Y unchanged). The callers treat Y values below $1A or from $D4 up as off-screen and do not draw the sprite."
  },
  {
   "address": 41124,
   "type": "line",
   "text": "Put the player's third sprite straight into slot 0 of the hardware sprite tables ($07B4-$07E6). It first clears spr_x_msb ($07B1) and spr_expand ($07B3). If player_third_on ($0913) is non-zero and the Y of the sprite ($08EF) is between $1A and $D3, it writes colour $0916, pointer $FE (the shape block at $FF80, whose shape number is $08EC), free-line Y + $15, X from $08F2, Y from $08EF, the X high bit from $08F5, and sets spr_enable ($07B2) to 1; otherwise spr_enable is 0. copy_sprites_to_tables then starts after slot 0 when spr_enable is 1."
  },
  {
   "address": 41252,
   "type": "line",
   "text": "Blink timer for the goal object whose number is in $08CC, called by wait_frame ($826C) only while the low six bits of $08CB are non-zero. $0290 is a two-phase countdown: while positive it counts down and sets bit 6 ($40, not drawn and not hit) of the object's obj_kind byte ($35EF); when it would go below 0 it becomes $81, and while bit 7 is set it counts down with that bit cleared, until $80 gives 0 again with the bit set. From 0 it cycles 0, $81, $80, so the object shows on two calls in three. Each pass through the clear phase also decrements the low six bits of $08CB (keeping its top two bits), setting it to $80 when it would underflow; $08CB is the time the gauge shows the object's health (track_stage_section), so the object blinks while the gauge is up."
  },
  {
   "address": 41336,
   "type": "line",
   "text": "Once a frame, update the stage's objects (enemies and the like) from obj_first ($14) up to obj_end ($15). First it sets move_mask ($029A) to $FF when bit 7 of $94 is set, otherwise to one bit chosen by the low three bits of frame_count from $029E, clears the count at $0910 (it counts the objects with bits 3 and 4 of obj_state set, whose numbers are listed from $74), and moves obj_first up by one when the first object is retired (bit 5, $20, of obj_state). Then for each object that is not retired: a follower (bit 6, $40, of obj_flags $364C) takes its position from the last object before it with bit 7 set plus its own offsets ($36F4 for X, $3748 for Y), any other object keeps the position in obj_x_lo/obj_x_hi/obj_y_lo/obj_y_hi ($38EC, $3949, $39A6, $3A03). An object whose bit mask in $3484 shares a bit with move_mask is moved this frame (bit 6 of obj_state cleared first): it is skipped if it lies far outside the view, otherwise given jumps and falls by object_arc_step ($88CE) and moved and animated through $B207, $B1F7, and $B57A according to its flags and its motion byte ($32CE); when those set bit 1 or bit 5 of obj_state, the object is marked not drawn and skipped. The new position is stored back. An object that does not move this frame and has bit 1 of obj_state set is skipped. The others are compared with the view window ($40-$47): outside it, bit 7 ($80) of obj_state is set (not drawn; with bit 6 as well when it is above or below the view) and, when bit 4 ($10) of obj_flags is set, bits 7 and 5 ($A0, retired for good); inside it, bit 6 ($40) is set and bit 7 cleared. An object that moved this frame, is inside the view horizontally, and has bit 4 ($10) of obj_state set gets its hit box from set_object_hitbox ($ABC7); one with bit 3 set calls $A990. The frame data it reads is reached through the stage-block pointers $3A and $3C, indexed by obj_anim_num ($33CA)."
  },
  {
   "address": 41919,
   "type": "line",
   "text": "Per frame: draw the objects and test them against the player. Box 1 ($4C-$53: left, right, top, bottom): player_x + $031A, that + $031B, player_y + $031C, that + $031D. Box 2 ($54-$5B): player_third_x + $031E and + $031F, player_third_y + $0320 and + $0321. For obj_first to obj_end, then temp_first to temp_end ($F0 = $FF): unless obj_state bit 7 or obj_kind bit 6 is set, each on-screen part of the current frame ($3B1A/$3B77, count in byte 4) adds a sprite entry at $0808-$0880 (at most $16 in all), filed in sprite_y_buckets at Y/2 or the next free place; $7F goes after the highest. If $A54A's check passes, player_hit is 0 and obj_phase is not negative, phase 0-1 objects meet box 2 first (a miss tries box 1 unless the object is wholly above box 2), others box 1; contact goes by phase and group to $A7A1, $A5B2, $A616, $A741 or $A74E. Objects with obj_state bit 7 clear and obj_kind bit 5 set then meet the six shots: a hit clears the shot and kills a pool object or takes hit points ($A6F0)."
  },
  {
   "address": 43112,
   "type": "line",
   "text": "Low bytes of nine handler addresses, indexed by the low four bits of obj_flags ($364C) at $A7A1: 0 $A7B9 collect item (sound $0C, counts up $089F), 1 $A83C pick up a weapon, 2 $0BBE, 3 $A85A, 4 to 6 none ($0000), 7 $A7F3 open the gate (see script_word_a), 8 $A82A. $A7A1 first stores $A0 in obj_state and jumps through the pair (high bytes in obj_flags_handler_hi)."
  },
  {
   "address": 43121,
   "type": "line",
   "text": "High bytes of the nine handler addresses of obj_flags_handler_lo ($A7, $A8, $0B, $A8, then three zeros, $A7 and $A8)."
  },
  {
   "address": 43130,
   "type": "line",
   "text": "Low bytes of the ten handlers that object_run_type_handler ($A88E) jumps to, indexed by the low four bits of obj_kind. With obj_kind_reaction_hi the addresses are: 0 $A8FA, 1 $A8D8, 2 $A8E0, 3 $A93D (nothing), 4 $A0E1 (in the resident code copied from bank 4), 5 $A93E, 6 $A8A6 (object_type_reset_group), 7 $A96D, 8 $A981, 9 $A902."
  },
  {
   "address": 43140,
   "type": "line",
   "text": "High bytes of the ten handler addresses of obj_kind_reaction_lo ($A884-$A88D)."
  },
  {
   "address": 43150,
   "type": "line",
   "text": "Queue sound $14, then jump through a table indexed by the low four bits of obj_kind ($35EF,x): low bytes at $A87A, high bytes at $A884, ten entries. Called from $A61A (contact: after the jump-on health test at $A600, or from $A5AA when player_effect bit 7 is set), from $A72B (a shot takes the last hit point) and from $BD56 (script command 34, $BD54). By type, the handlers are $A8FA (0, launch up in an arc), $A8D8 (1), $A8E0 (2), $A93D (3, does nothing), $A0E1 (4, resident code from bank 4), $A93E (5), $A8A6 (6), $A96D (7), $A981 (8), and $A902 (9)."
  },
  {
   "address": 43174,
   "type": "line",
   "text": "Handler for object type 6, run through object_run_type_handler ($A88E). Starting with object X, it handles each following object whose obj_flags ($364C) bit 6 is set (a follower) as well. For each object that has neither bit 4 of obj_flags nor bit 5 of obj_state ($3592) set, it calls $A8D8 and then sets bit 4 of obj_flags. X is left at the last object handled."
  },
  {
   "address": 43224,
   "type": "line",
   "text": "Handler for object type 1; also called from object_type_reset_group ($A8B4) and reached by a jump from $A96A. Replace obj_anim_num ($33CA) with the byte at the pointer ($3E) indexed by the old number, then carry on into object_reset_motion ($A8E0)."
  },
  {
   "address": 43232,
   "type": "line",
   "text": "Handler for object type 2, and also reached by a jump from $A98D. Clear obj_arc_state ($3F19), copy the byte at $3376 to the motion byte at $32CE, clear bit 5 of obj_flags (the bit that makes $A2D9 call the table handlers of $B1F7), and set the animation countdown at $3A60 to $FF. Then continue at $A91D with A = $FF."
  },
  {
   "address": 43258,
   "type": "line",
   "text": "Handler for object type 0, and also reached by a jump from $B432. Replace obj_anim_num ($33CA) with the byte at the pointer ($3E) indexed by the old number, then carry on into object_start_rise_arc ($A902)."
  },
  {
   "address": 43266,
   "type": "line",
   "text": "Handler for object type 9, and the second half of type 0. Set the motion byte ($32CE) to $FE, obj_arc_state ($3F19) to $80, and obj_arc_counter ($3F76) to $10, so that object_arc_step ($88CE) makes the object rise. Set bit 4 and clear bit 5 of obj_flags, then continue at $A91D with A = $FF."
  },
  {
   "address": 43293,
   "type": "line",
   "text": "Shared end of the handlers at $A8E0, $A8FA, and $A902. Store A (always $FF here) in obj_move_bits ($3484), clear bits 0, 4, and 6 of obj_state ($3592), clear bits 4 and 5 and set bit 7 of f_35EF, and zero the script position ($379C), the repeat count ($37F0), and the animation index ($3EBC). Bit 4 of obj_state gates the hit box in update_objects and bit 0 gates the animation step at $B585, so both are switched off."
  },
  {
   "address": 43325,
   "type": "line",
   "text": "Handler for object type 3: a bare rts, which is also the end of the code at $A91D."
  },
  {
   "address": 43326,
   "type": "line",
   "text": "Handler for object type 5. Set obj_flags ($364C) of objects 26 and 27 ($3666 and $3667) to $90, zero their obj_state, script position, and repeat count, set their obj_move_bits to $FF, and set their motion bytes ($32E8 and $32E9) to $36 and $37. Then reset the current object through $A8D8. This probably brings two linked objects into play."
  },
  {
   "address": 43373,
   "type": "line",
   "text": "Handler for object type 7. Store $09 in $2D32, $CD in $2D56, and $CE in $2D46 (in the data unpacked once at start-up from entries 12-15, above every stage block; what they hold is unknown), set obj_state of object 51 ($35C5) to $FF, and return."
  },
  {
   "address": 43393,
   "type": "line",
   "text": "Handler for object type 8. Set obj_state of object 51 ($35C5) to $FF, clear $48, and set $49 to $64 (the delay and count that the stage routine at $BD76 reads). Then continue at $A8E0."
  },
  {
   "address": 43408,
   "type": "line",
   "text": "Dispatches on the phase value in $3427,x: 0 and 6 or higher go to apply_dir_and_speed, 1 to phase1_nudge_y, 2 to phase2_flag_countdown, 3 to phase3_start_arc, 4 to phase4_wait_flag7, and 5 to phase5_substate_dispatch."
  },
  {
   "address": 43429,
   "type": "line",
   "text": "Jump stub to apply_dir_and_speed $AB38 for phase 0 and phases 6 or higher."
  },
  {
   "address": 43432,
   "type": "line",
   "text": "Jump stub to $AB49 for phase 1."
  },
  {
   "address": 43435,
   "type": "line",
   "text": "Jump stub to $AAAE for phase 2."
  },
  {
   "address": 43438,
   "type": "line",
   "text": "Jump stub to $AA61 for phase 3."
  },
  {
   "address": 43441,
   "type": "line",
   "text": "Phase 4: returns while bit 7 of obj_flags $364C is clear. When set, copies obj_off_y $3748 into $32CE,x and sets the phase $3427,x back to 0."
  },
  {
   "address": 43458,
   "type": "line",
   "text": "Phase 5: dispatches on obj_off_x $36F4. Value 0 goes to phase5_substate0_wait_flag7, 1 to phase5_substate1_block_check, 3 to phase5_substate3_countdown, and any other value falls into phase5_substate2_countdown."
  },
  {
   "address": 43471,
   "type": "line",
   "text": "Counts down obj_off_y $3748 and returns until it hits zero. Then advances obj_off_x, sets obj_off_y to $0E, masks obj_state $3592 to its low nibble, clears bit 7 of obj_flags $364C, copies $3322,x and $3376,x into obj_y_lo $39A6 and obj_y_hi $3A03, and sets $32CE,x to 2."
  },
  {
   "address": 43517,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43518,
   "type": "line",
   "text": "Counts down obj_off_y $3748 and returns until it hits zero. Then sets bit 4 of obj_state $3592, clears bit 6 of $35EF,x, resets obj_off_x to 0, and sets obj_off_y to 7."
  },
  {
   "address": 43549,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43550,
   "type": "line",
   "text": "Returns while bit 7 of obj_flags $364C is clear. When set, counts down obj_off_y $3748; at zero, reloads it with $4B and joins start_arc_next_substate."
  },
  {
   "address": 43568,
   "type": "line",
   "text": "If bit 7 of obj_flags $364C is set, stores $0D in $19. Then calls block_property_at $9400 with A and Y both $0C; when the result ANDed with $43 is zero, returns. Otherwise sets $32CE,x to 1, clears obj_arc_state $3F19, advances obj_off_x $36F4, masks obj_state $3592 to its low nibble, and sets bit 6 of $35EF,x."
  },
  {
   "address": 43577,
   "type": "line",
   "text": "Loads $0C into A and Y for the block_property_at $9400 call."
  },
  {
   "address": 43617,
   "type": "line",
   "text": "Phase 3: when obj_off_x $36F4 is nonzero, goes to phase3_land_check. When zero, returns unless bit 7 of obj_flags $364C is set, in which case falls into start_arc_next_substate."
  },
  {
   "address": 43627,
   "type": "line",
   "text": "Advances obj_off_x $36F4, sets obj_arc_state $3F19 to $C0, and sets obj_arc_counter $3F76 to 1."
  },
  {
   "address": 43640,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43641,
   "type": "line",
   "text": "Stores $0D in $19, then shifts the 16-bit obj_y_hi:obj_y_lo ($3A03:$39A6) right four bits into $E1. When $E1 equals obj_off_y $3748, clears the low four bits of obj_y_lo, clears obj_arc_state $3F19, and masks obj_state $3592 with $81. Returns if the values differ."
  },
  {
   "address": 43694,
   "type": "line",
   "text": "Phase 2: saves the top three bits of obj_flags $364C in $E1. With bits 6 and 5 clear, goes to phase2_no_timer_bits. With bit 5 set, goes to phase2_wiggle_y. With only bit 6 set, acts on odd frames of frame_count $08F6 by subtracting 1 from the low nibble of obj_flags; when that borrows, goes to phase2_set_flags_a6."
  },
  {
   "address": 43731,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43732,
   "type": "line",
   "text": "If bit 7 of obj_flags $364C is set, stores $C7 in obj_flags. Otherwise returns."
  },
  {
   "address": 43743,
   "type": "line",
   "text": "Stores $A6 in obj_flags $364C."
  },
  {
   "address": 43748,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43749,
   "type": "line",
   "text": "Skips to apply_dir_and_speed when bit 4 of obj_flags $364C is set or frame_count $08F6 is even. Otherwise sets obj_speed $34E1 to 1 and subtracts 1 from the low nibble of obj_flags. On borrow, goes to phase2_wiggle_finish. Else stores the new flags, then bit 0 of the nibble picks decrementing (set) or incrementing (clear) obj_y_lo $39A6, and sets obj_dir $36A0 to $0E or $0D to match."
  },
  {
   "address": 43785,
   "type": "line",
   "text": "Sets obj_dir $36A0 to $0E, decrements obj_y_lo $39A6, and jumps to apply_dir_and_speed."
  },
  {
   "address": 43796,
   "type": "line",
   "text": "Sets obj_dir $36A0 to $0D, increments obj_y_lo $39A6, and jumps to apply_dir_and_speed."
  },
  {
   "address": 43807,
   "type": "line",
   "text": "Stores bit 7 of obj_flags $364C plus $30 back in obj_flags, sets $32CE,x to $FE, obj_arc_state $3F19 to $C0, and obj_arc_counter $3F76 to 0, then falls into apply_dir_and_speed."
  },
  {
   "address": 43832,
   "type": "line",
   "text": "When bit 7 of obj_flags $364C is set, copies obj_dir $36A0 to $19 and obj_speed $34E1 to $0295. Otherwise returns without writing."
  },
  {
   "address": 43849,
   "type": "line",
   "text": "Phase 1: when bit 7 of obj_flags $364C is set, clears that bit, stores $0D in $19 and 1 in $0295, and adds 2 to obj_y_lo $39A6. When clear, goes to phase1_pull_back_y."
  },
  {
   "address": 43878,
   "type": "line",
   "text": "If obj_y_lo $39A6 is below obj_off_x $36F4, returns. Otherwise subtracts 2 from obj_y_lo."
  },
  {
   "address": 43891,
   "type": "line",
   "text": "Shared RTS."
  },
  {
   "address": 43892,
   "type": "line",
   "text": "Chooses an aim direction (0-9, see aim_dir) for a player standing on a slope. Called with X = slope_kind ($0C) from $9F2B and $AF74, only when slope_kind and stance ($0299) are non-zero; the caller stores A in aim_dir ($0297). Bit 3 of player_facing ($18) set means facing left. Slope kind 2: right gives 3 (down-right), left gives 8 (up-left). Any other kind (1): right gives 1 (up-right), left gives 6 (down-left). So the aim follows the slope's incline (inferred from the codes)."
  },
  {
   "address": 43918,
   "type": "line",
   "text": "Table handler for index 0 of the table at $B382. Do nothing when bit 7 of f_35EF is set. Otherwise, when player_x ($08B7/$08B8) lies from about $40 pixels left of the object's X ($E7/$E8) to about $18 pixels right of it (the carry is not set explicitly, so the edges may be off by one), jump to $4C9D, which sets bit 7 of f_35EF and swaps the motion byte at $32CE with the one at $3322."
  },
  {
   "address": 43975,
   "type": "line",
   "text": "Set the hit box of object X from its new position (E7-EA) and the first four bytes of its current frame's part list (pointer $EB/$EC): left = X + byte 0 into $3BD4/$3C31, top = Y + byte 1 into $3D48/$3DA5, right = X + byte 2 into $3C8E/$3CEB, and bottom = Y + byte 3 into $3E02/$3E5F."
  },
  {
   "address": 44038,
   "type": "line",
   "text": "Table handler for index 13. Count down obj_off_y ($3748), used here as a timer. When it reaches zero, reload it with $32 and jump to $4C9D, which sets bit 7 of f_35EF and swaps the motion byte at $32CE with the one at $3322."
  },
  {
   "address": 44051,
   "type": "line",
   "text": "Computes the edges of the player's box at the trial position. $EE/$EF is player_try_y ($08BD/$08BE) plus $031C and $031D (vertical offsets, with carry into the high byte). $E5/$E6 is player_try_x ($08BB/$08BC) plus $031A, and $EC/$ED is that plus $031B. It then jumps to $9E17, which starts a loop over the objects counted in $0910 (inferred to be the overlap test against them). Which offset is the box's near edge and which its size is inferred."
  },
  {
   "address": 44111,
   "type": "line",
   "text": "Per-frame routine over six slots (X=5 down to 0) whose flag byte $06DD,x has bit 7 set. First, if $08E0 is nonzero and frame_count $08F6 is even, counts $08CD down; at zero this clears $08E0 and copies $B8F8 to $28 and $B8FD to $29 (purpose of $28/$29 unknown). Then masks $40 and $42 to multiples of 8 into $E1 and $E2 (the view position, as used for the on-screen test below)."
  },
  {
   "address": 44164,
   "type": "line",
   "text": "Active slot: decrements timer $070D,x and deactivates the slot at zero. Otherwise subtracts the view ($E1/$41 for x, $E2/$43 for y) from the slot position ($06E3/$06E9 x, $06EF/$06F5 y); the slot is deactivated unless the result falls inside 40 character columns (x/8 below $28) and 20 rows (y/8 below $14)."
  },
  {
   "address": 44222,
   "type": "line",
   "text": "Clears the slot flag $06DD,x to 0, then continues with the next slot."
  },
  {
   "address": 44230,
   "type": "line",
   "text": "Slot is on screen: Y = row. Builds the screen address in $E3/$E4 from row table $02E8,y/$02FC,y plus the column in $EB and $08C0 (added to the high byte), and the matching colour RAM address in $E5/$E6 (row-table high byte plus $D8). If char_colour_table $0C22 for the character already at that cell has bit 7 set, the slot is deactivated. Otherwise loads the frame list pointer into $E7/$E8 (tables $0398/$039B indexed by $0713,x) and the frame definition pointer into $E9/$EA (list offset $0719,x). Definition byte 0 picks the draw case: 0 is one cell, 1 is two cells, and 2 or more is a 2x2 block."
  },
  {
   "address": 44310,
   "type": "line",
   "text": "One-cell case: appends a record to the buffer at $0743 using the index in $0904 (old character, a 0 marker, screen address high/low, colour RAM high), then advances $0904 by 5. Writes definition byte 4 to the screen cell and byte 1 to colour RAM. The code that reads the record buffer back is not in this stretch."
  },
  {
   "address": 44357,
   "type": "line",
   "text": "Two-cell case (cells side by side): appends a 6-byte record (two old characters, a 1 marker, screen address high/low, colour RAM high) at $0743 using $0904, then advances $0904 by 6. Writes definition bytes 4 and 5 to the two screen cells and byte 1 to both colour cells."
  },
  {
   "address": 44416,
   "type": "line",
   "text": "Common tail after drawing: restores the slot number from $EB. The slot only animates on frames where frame_count $08F6 AND mask $0725,x is zero; otherwise goes to the next slot."
  },
  {
   "address": 44429,
   "type": "line",
   "text": "If mask $0725,x is nonzero and $90 is zero, queues sound $18 via queue_sound $0B8C ($90 is sound_queue_count)."
  },
  {
   "address": 44443,
   "type": "line",
   "text": "Loads the path pointer from $06FB,x/$0701,x into $EB/$EC. Advances the frame offset $0719,x by 2; when it reaches limit $071F,x the offset wraps to 0 if the mask $0725,x is zero, or to $0A if the mask is nonzero. Stores the new offset and reloads the frame definition pointer $E9/$EA from the list at $E7."
  },
  {
   "address": 44512,
   "type": "line",
   "text": "Reads a 4-byte step from the path at ($EB) offset $0707,x: adds bytes 0 and 1 to slot x ($06E3/$06E9) and bytes 2 and 3 to slot y ($06EF/$06F5), then stores the new path offset in $0707,x. Step byte value $80 at the start of a step is an end marker: with mask $0725,x nonzero the offset goes back 4 bytes to repeat the previous step, and with mask zero it restarts at offset 0. Finally writes $072B,x/$0731,x (x plus definition byte 2) and $0737,x/$073D,x (y plus definition byte 3); their meaning is unknown, and the adds reuse the carry left by the previous add."
  },
  {
   "address": 44590,
   "type": "line",
   "text": "Four-cell (2x2) case: appends an 8-byte record (four old characters, the marker value, screen address high/low, colour RAM high) at $0743 using $0904, then advances $0904 by 8. Writes definition bytes 4, 5, 6, and 7 to the cells at offsets 0, 1, $28, and $29 on the screen, and byte 1 to the same four colour cells."
  },
  {
   "address": 44688,
   "type": "line",
   "text": "Pops the saved-background stack and puts the characters back on the screen and their colours into colour RAM. $0904 holds the top of the stack; it does nothing if it is zero. Each record is 5, 6 or 8 bytes ending at offset X in $073B..$0742: a tag in $073F,x (0 = 1 cell, 1 = 2 cells, 2 or more = 2x2 cells), a screen pointer in $0740/$0741 and a colour RAM pointer in $0741/$0742. Each saved character is stored back at the screen address, and its colour is looked up in char_colour_table ($0C22) and stored at the colour RAM address. It loops until the stack is empty, then clears $0904. Pairs with slot_save_draw_1_cell, _2_cells and _4_cells, which push the records; role inferred."
  },
  {
   "address": 44790,
   "type": "line",
   "text": "Entry for a one-cell record on the saved-background stack: restores the single character at offset 0 and its colour, then pops 5 bytes from the stack pointer in X (ends the routine if that empties it)."
  },
  {
   "address": 44812,
   "type": "line",
   "text": "Entry for a two-cell record on the saved-background stack: restores two adjacent characters (offsets 0 and 1) with their colours, then pops 6 bytes; ends via $AF08 when the stack is empty, else loops back to $AE95."
  },
  {
   "address": 44852,
   "type": "line",
   "text": "Fire a shot; update_player calls it while fire_flags bit 6 is clear (fire pressed). Nothing while $08FF or player_hit is non-zero. player_mode picks how aim_dir is set. Mode 0 on a slope with stance set uses slope_aim_dir; else on the ground joy_bits up gives 0 (9 when player_facing bit 3 is set), up-right 1, right 2, left 7, up-left 8, and anything else 2 or 7 by the facing ($AFAB-$AFBF, for 3-6, is never reached); in the air only the facing (7 or 2). On the ground it then sets fire_flags and $0903 to $80 and $0902 to $FE. Mode 1 goes to $B16B, mode 2 or more straight on. A shot needs shot_delay bit 7 set: it reloads $08DE/$08DF from weapon record ($28) bytes $14/$15 and fills a free shot slot with bytes $16-$19 (frames left, frame-list end, list type, animation mask), a start at player_third_x/_y + shot_start_offsets (rounded down to 8), a corner 8 further on, and a path from record bytes 2 x aim_dir. weapon_level under 3: one shot, sound $1C (not at 2); 3 up: two ($B088), sound $20."
  },
  {
   "address": 45559,
   "type": "line",
   "text": "Jump through a table of handlers indexed by obj_off_x,x: the low bytes are at $B382 and the high bytes at $B3A1 (31 entries). Called from $A2D9 for an object whose obj_flags bit 5 is set and whose obj_state bit 3 is clear. By table index: 0 is $AB8E, 1 is $B3C0, 2 is $B47B, 3 is $B4B3, 6, 10, 20, 21, and 25 share $BD76, 9 is $BDE0, 13 is $AC06, 14 is $B4C4, 18 is $B4C1, and 30 is $BE31. Indexes 4, 5, 8, 11, 12, and 15 point into per-stage RAM ($243A, $23F7, $25E1, $24BA, $2469, and $2705). Indexes 7, 16, 17, 23, 24, and 28 ($BE73, $BF80, $BFCB, $BE91, $BEB3, and $BE8D) lie past the end of the first stage's code at $BE6A and are probably used by the later stages, which load different code from $BD76. Indexes 19 and 27 ($BDBD and $BE34) enter part-way through the routines at $BD76 and $BE31, and indexes 22, 26, and 29 ($BD86, $BD84, and $BE2E) land inside instructions of the first stage's code."
  },
  {
   "address": 45575,
   "type": "line",
   "text": "Advance the movement script of object X. The script is found through the stage-block pointers ($36) and ($38) and the position f_379C,x. A byte below $80 is a command: it is looked up in the address tables at $B33C and $B35F and run through $88AF, and a carry means the command has finished, so the script position moves on. A byte with bit 7 set ($B23C) is a move: its low four bits are a direction in the joystick pattern ($0B left, $07 right, $0E up, $0D down, $06, $05, $09, and $0A for the diagonals, where the sideways steps count twice), the next byte is the repeat count (f_37F0,x), and each step adds or subtracts obj_speed ($34E1) on the position in $E7/$E8 and $E9/$EA. Then, when bit 6 of obj_flags is set, it stores the offset from $08DA and $08DC in obj_off_x and obj_off_y. The direction is also kept in obj_dir ($36A0). Called from $A2B4."
  },
  {
   "address": 45657,
   "type": "line",
   "text": "Runs one step of an object's movement script. A holds the script byte (low nibble is the direction), X is the object slot. A repeat counter at $37F0,x is loaded from the next script byte when unset and counted down; the direction is stored in obj_dir ($36A0,x) and the object's 16-bit X ($E7/$E8) and Y ($E9/$EA) working position is moved by obj_speed ($34E1,x). Used for enemies and objects on fixed paths."
  },
  {
   "address": 45677,
   "type": "line",
   "text": "Stores the direction nibble in obj_dir and dispatches on it: $0B left, $07 right, $06 up-right, $05 down-right, $09 down-left, $0A up-left, $0E up, $0D down; any other value moves up. Diagonals move twice as far horizontally as vertically."
  },
  {
   "address": 45722,
   "type": "line",
   "text": "Moves the object left: subtracts obj_speed from its 16-bit X position ($E7/$E8) with borrow."
  },
  {
   "address": 45735,
   "type": "line",
   "text": "Moves the object right: adds obj_speed to its 16-bit X position ($E7/$E8) with carry."
  },
  {
   "address": 45748,
   "type": "line",
   "text": "Diagonal move up and right: Y ($E9/$EA) decreases by obj_speed, X ($E7/$E8) increases by twice obj_speed."
  },
  {
   "address": 45773,
   "type": "line",
   "text": "Diagonal move down and right: Y ($E9/$EA) increases by obj_speed, X ($E7/$E8) increases by twice obj_speed."
  },
  {
   "address": 45798,
   "type": "line",
   "text": "Diagonal move down and left: Y ($E9/$EA) increases by obj_speed, X ($E7/$E8) decreases by twice obj_speed."
  },
  {
   "address": 45828,
   "type": "line",
   "text": "Diagonal move up and left: Y ($E9/$EA) decreases by obj_speed, X ($E7/$E8) decreases by twice obj_speed."
  },
  {
   "address": 45858,
   "type": "line",
   "text": "Moves the object up: subtracts obj_speed from its 16-bit Y position ($E9/$EA). Also the default for unknown direction codes."
  },
  {
   "address": 45871,
   "type": "line",
   "text": "Moves the object down: adds obj_speed to its 16-bit Y position ($E9/$EA)."
  },
  {
   "address": 45884,
   "type": "line",
   "text": "Low bytes of the 35 script command routines that object_script_step runs for a script byte below $80 (index y): 35 bytes $B33C-$B35E. The high bytes are script_cmd_hi. Most targets lie between $B5xx and $B8xx and in $BCxx and $BDxx; command 5 is $0BA0, command $15 is $9150 (path_start_from_record) and command $18 is $4CC7."
  },
  {
   "address": 45919,
   "type": "line",
   "text": "High bytes of the 35 script command routines: $B35F-$B381, partner of script_cmd_lo (values $B5 to $B8, $BC and $BD, except command 5 ($0B), command $15 ($91) and command $18 ($4C))."
  },
  {
   "address": 45954,
   "type": "line",
   "text": "Low bytes of a second table of 31 routine addresses, $B382-$B3A0, read by object_run_script_handler; the high bytes are in script_cmd2_hi. Indexes 0-3, 13, 14 and 18 are resident code ($AB8E, $B3C0, $B47B, $B4B3, $AC06, $B4C4, $B4C1). The rest are not fixed: $23F7-$2705 (indexes 4, 5, 8, 11, 12, 15) hold data in the saved state, and $BD76 and up are stage code that changes with the stage; some of those targets ($BE73, $BE8D, $BE91, $BEB3, $BF80, $BFCB) lie past the first stage code ($BD76-$BE6A) or inside one of its instructions, so they belong to other stages."
  },
  {
   "address": 45985,
   "type": "line",
   "text": "High bytes of the 31 routine addresses of script_cmd2_lo, $B3A1-$B3BF: $AB to $BF, except $23 to $27 for indexes 4, 5, 8, 11, 12 and 15."
  },
  {
   "address": 46016,
   "type": "line",
   "text": "Table handler for index 1. While obj_off_y ($3748) is nonzero it counts that down; when it reaches zero it starts a rising arc (obj_arc_counter $30, obj_arc_state $80) and sets obj_anim_num ($33CA) and obj_dir ($36A0) to face the player (0 and $07 when the object is left of player_x + $1F, otherwise 1 and $0B). At other times, with obj_speed ($34E1) nonzero it walks through $B5D5, which moves the object by obj_speed (left when bit 3 of obj_dir is set) and flips bits $0C of obj_dir at a block with property bit 0 beside it or at X 0, and then sets obj_anim_num from that bit. While falling (bit 6 of obj_arc_state) it tests the block under it with block_property_at ($9400), property AND 3: 2 or 3 jumps to $A8FA, 1 lands the object and sets obj_off_y to $0A (the wait before the next hop), and 0 clears bit 0 of obj_state when obj_arc_counter is 7. When bit 6 is clear, bit 0 of obj_state is set while obj_arc_counter is below $10."
  },
  {
   "address": 46130,
   "type": "line",
   "text": "Block property 2 or 3: launch the object upward through $A8FA."
  },
  {
   "address": 46203,
   "type": "line",
   "text": "Table handler for index 2. Do nothing when bit 7 of obj_kind ($35EF) is set or the animation index ($3EBC) is nonzero, and count obj_off_y ($3748) down when it is nonzero. Otherwise subtract the object's X from player_box_left ($4C/$4D): when bit 3 of $18 is clear, jump to $4C9D if the player is left of the object by 1 to $40, and when it is set, if the player is level with it or right of it by up to $3F (only the low byte of the difference is compared with the limit). Before jumping it sets obj_off_y to $0A. $4C9D sets bit 7 of obj_kind and swaps the motion byte at $32CE with the one at $3322."
  },
  {
   "address": 46259,
   "type": "line",
   "text": "Table handler for index 3. Walk sideways through $B5D5, then run object_land_bounce ($B4C4). When that reports a final landing (carry set), set the motion byte ($32CE) to zero."
  },
  {
   "address": 46273,
   "type": "line",
   "text": "Table handler for index 18. Walk sideways through $B5D5, then fall into object_land_bounce ($B4C4)."
  },
  {
   "address": 46276,
   "type": "line",
   "text": "Table handler for index 14, and the second half of indexes 3 and 18. While the object falls (bit 6 of obj_arc_state $3F19), test the block under it with block_property_at ($9400). On a hit, snap the object's Y ($E9/$EA) to a block boundary. If obj_off_y ($3748) is nonzero, it becomes the new obj_arc_counter and is halved, and obj_arc_state is set to $80 so the object bounces up again, with carry clear. Otherwise obj_arc_state is cleared, bit 5 of obj_flags is cleared (so $A2D9 stops calling the table handlers), and carry is set. With no hit, or when the object is not falling, carry is clear."
  },
  {
   "address": 46306,
   "type": "line",
   "text": "Bounce: obj_off_y becomes the rise counter and is then halved."
  },
  {
   "address": 46324,
   "type": "line",
   "text": "No bounce height left: land for good, and stop the table handler by clearing bit 5 of obj_flags."
  },
  {
   "address": 46458,
   "type": "line",
   "text": "Advances one object's animation. X is the object slot. The object's obj_anim_num indexes the pointer tables at ($3A) and ($3C), giving the animation data block in $E5/$E6. If bit 0 of obj_state is set, the per-object delay $3A60,x counts down; when it passes zero it is reloaded from $3535,x and the frame index $3EBC,x goes up by one, wrapping to 0 at the count in the block's first byte."
  },
  {
   "address": 46503,
   "type": "line",
   "text": "Alternate entry (no caller found in this range): reloads the data block pointer $E5/$E6 for the object's obj_anim_num without advancing the frame index, then falls into the common code at $B5B2."
  },
  {
   "address": 46514,
   "type": "line",
   "text": "Common end: store the frame index, then read that frame's pair of bytes (at offset 5 + 2 x index of the data block) into $3B1A,x and $3B77,x (and copies in $EB/$EC), and set $3ABD,x to $37 minus the block's byte 4 ($38 with sbc and the carry clear). What those fields are drawn from (offsets or sizes) is inferred, not traced."
  },
  {
   "address": 47311,
   "type": "line",
   "text": "Count down a timed player effect, once a frame. While player_effect ($08B1) is non-zero, on every second frame it decrements player_effect_timer ($08CE); when that reaches zero it clears player_effect and player_effect_flash ($08B2). While the timer is below $24 it sets bit 7 of player_effect_flash from bit 0 of the timer, so the flag toggles with each tick. player_pose uses the flag (bit 7 of $08B2) to change the third sprite's colour to $0E and its shape number, and the contact code at $A5A7 tests bit 7 of $08B1. The routine at $0BBE starts it: it queues sound 8 and sets $08B1 and $08B2 to $FF and the timer to $E0 (448 frames); init_round_state clears it at $4EF5. It is probably an invulnerability or power-up timer."
  },
  {
   "address": 47352,
   "type": "line",
   "text": "Low bytes of the addresses of the five weapon records, indexed by the number in $3322,x of the weapon item: $C9, $E3, $02, $FD and $2B. The pick-up handler at $A83C copies the pair into weapon_ptr ($28/$29) and stores the number in $08E0."
  },
  {
   "address": 47357,
   "type": "line",
   "text": "High bytes of the five weapon record addresses ($B9 each), so the records are at $B9C9, $B9E3, $B902, $B9FD and $B92B."
  },
  {
   "address": 48353,
   "type": "line",
   "text": "Raster interrupt at line $DE: after a short delay, $D011 = $17 turns the black mode off, so the status panel shows from here (24 rows)."
  },
  {
   "address": 48477,
   "type": "line",
   "text": "Converts the five score digit tiles ($08D0-$08D4) to plain digit values (tile minus $C1) and stores them at $FFF5-$FFF9. Called from round_start at $8075 when the lives count has run out, just before the jump to title_entry ($4000), and from stage_intro_start at $4057 when the stage number has reached 5, just before the jump to game_start. What reads the stored digits is not established here, so the name is neutral. The zero bytes after the final return at $BD6C onward are padding."
  },
  {
   "address": 48502,
   "type": "line",
   "text": "Table handler for indexes 6, 10, 20, 21, and 25. The code at $BD76 and above is stage code loaded from the cartridge, and this description covers the code present in the snapshot, the first stage. When $49 with bit 7 masked off is zero it does nothing. Otherwise that value is the index Y, and $48 counts down; at zero, $49 is decremented and $48 reloaded with 5, and the entries at index Y + $47 of the object arrays are filled in: for example $3F60 is obj_arc_state plus $47, set to $80, with obj_arc_counter $10, obj_state $D0, obj_flags $20, obj_off_y $AC, and y $0016. If bit 7 of $49 is clear, obj_dir is $07, X is $01A8, and the frame is 0. Otherwise obj_dir is $0B, X is $02F0, and the frame is 1. It is started by object type 8 ($A981), which sets $49 to $64."
  },
  {
   "address": 48608,
   "type": "line",
   "text": "Table handler for index 9, in the stage code of the first stage. Count down obj_off_y ($3748). At zero, set obj_state to $FF and stop. Otherwise move the object's X ($E7/$E8) by 4, left when bit 3 of obj_dir ($36A0) is set and right when clear. While it falls (bit 6 of obj_arc_state) and (Y + $15) AND $0C is zero, it tests the block under it with block_property_at ($9400) and on a hit starts a new rise (obj_arc_state $80, obj_arc_counter $30). It is probably the handler for the objects that $BD76 creates, which have obj_off_y $AC and a direction of $07 or $0B."
  },
  {
   "address": 48689,
   "type": "line",
   "text": "Table handler for index 30, in the stage code of the first stage. Take the object's Y minus $15 ($E9) and, for each of objects 27, 28, and 29 whose obj_state bit 0 is set ($35AD, $35AE, and $35AF), store it in their obj_y_lo ($39C1-$39C3) and store the low byte of the object's X ($E7) plus $18, $08, and $3E in their obj_x_lo ($3907-$3909). There is no clc, so a sum is one more when the carry is set; for the first that is when Y is $15 or more. This places three attached objects relative to this one."
  },
  {
   "address": 48930,
   "type": "line",
   "text": "Byte patched to $19 by stage3_patch (with $00 at $BF23, $01 at $BF24 and $00 at $BF25). Zero in the saved stage 0 state; this lies in the part of the stage code area that other stages fill. The bytes read as two words, $0019 and $0001. No instruction in the saved state reads them (the stage code that would is not loaded), so their use is not known."
  },
  {
   "address": 48931,
   "type": "line",
   "text": "Second byte of the stage 3 patch group at $BF22: stage3_patch clears it to $00 (the high byte of the word $0019)."
  },
  {
   "address": 48932,
   "type": "line",
   "text": "Third byte of the stage 3 patch group at $BF22: stage3_patch stores $01 here, the low byte of the word $0001 that $BF24-$BF25 form."
  },
  {
   "address": 48933,
   "type": "line",
   "text": "Fourth byte of the stage 3 patch group at $BF22: stage3_patch stores $00 here, the high byte of the word $0001."
  },
  {
   "address": 49150,
   "type": "line",
   "text": "Start of a ten-byte block $BFFE-$C007 that stage2_tail fills in stage 2: $FF, $00, $00, $00, $01, $80, $06, $FF, $FF, $00. The last eight bytes are the first eight bytes of the character set at $C000. No routine in the listing reads them as a record, and the meaning of the values is not established."
  },
  {
   "address": 49151,
   "type": "line",
   "text": "Second byte of the stage 2 block (stage2_tail stores $00)."
  },
  {
   "address": 49152,
   "type": "line",
   "text": "The character set of the playfield: 2048 bytes $C000-$C7FF, eight pixel rows for each of 256 characters (VIC bank 3, $D018 $21 or $31). stage_load copies each stage's set to $C000 from the cartridge at stage start (directory entries 17, 20, 23, 26 and 29), and entry 6 adds $C7A0-$C7F7. stage2_tail writes $00, $00, $01, $80, $06, $FF, $FF and $00 to character 0 for stage 2 (all $FF, a solid character, in the saved state)."
  },
  {
   "address": 50176,
   "type": "line",
   "text": "Characters $80 to $8F of the playfield character set ($C400-$C47F), eight bytes each. Same layout as charset_start, and copied with it from the cartridge by the stage's directory entry at stage start."
  },
  {
   "address": 50303,
   "type": "line",
   "text": "Last pixel row of character $8F. The routine at $51FD writes zeros to $C47F+X for X from $C0 down to 1, so this byte is only the base address; the cleared bytes are $C480-$C53F."
  },
  {
   "address": 50304,
   "type": "line",
   "text": "The 192 bytes $C480-$C53F (characters $90 to $A7) that the routine at $51FD fills with $00 while it saves $FFBF-$FFFE to $44E1. The bytes are characters $90 to $A7 of the stage character set: each stage's directory entry 17 overwrites them, so in play 186 of the 192 are non-zero and the clearing is only the start-up state."
  },
  {
   "address": 51072,
   "type": "line",
   "text": "Shapes of characters $F0-$F3 (32 bytes $C780-$C79F): patch_stage_code copies them from $20C0 for stage 0, or clears them if bit 5 of $35A8 is set. In stage 0 the routine at $0BBE (which starts the timed player effect) also clears them, at $0BD9."
  },
  {
   "address": 51200,
   "type": "line",
   "text": "Character screen buffer A: 40 columns by 21 rows of character codes, $C800-$CB47 (840 bytes). It is shown when $10 is 0 (D018 $21). The saved state shows blocks of the map as pairs of characters. recolour_c800_0 to _3 read it character by character to set colour RAM; those loops read the addresses $C800-$C81F, $C900-$C91F, $CA00-$CA1F and $CA48-$CA6B directly and the rest by stepping Y, so the symbols the disassembler put inside the buffer, and the 40 bytes $CA20-$CA47, are all part of it."
  },
  {
   "address": 52040,
   "type": "line",
   "text": "The 176 bytes $CB48-$CBF7 after the 840 playfield characters of screen_buffer_c800 (the screen's rows 21 to 24 and 16 unused bytes). The saved state holds 28 tile codes ($12, $29, $92, $98 and $9A) at $CB4E-$CB69 and zeros after them. No routine in the listing addresses them directly."
  },
  {
   "address": 52216,
   "type": "line",
   "text": "The eight sprite pointers of the screen at $C800 (screen base + $3F8): copy_sprite_shadows ($4D47) copies the shadow pointers from $07E7 here and to sprite_pointers_cc00, so both screens show the same sprites. The loop at $81E5 sets both screens' pointers to $F4-$FB (sprites 0 to 7) with sprite colour 1. The saved state holds $C7, $5D, $5B, $FC, $FD, $5C, $FF, $00."
  },
  {
   "address": 52224,
   "type": "line",
   "text": "Character screen buffer B: the same 40 by 21 layout as screen_buffer_c800 at $CC00-$CF47, shown when $10 is 1 (D018 $31). recolour_cc00_0 to _3 read it, by fixed address at $CC00-$CC1F, $CD00-$CD1F, $CE00-$CE1F and $CE48-$CE5F (the fourth loop is 24 bytes wide, where recolour_c800_3 is 36) and the rest by stepping Y; the bytes $CE20-$CE47 are part of it."
  },
  {
   "address": 53064,
   "type": "line",
   "text": "The 120 bytes $CF48-$CFBF after the 840 playfield characters of screen_buffer_cc00 (screen rows 21 to 23). Row 21 holds tile codes in the saved state; no routine in the listing addresses them directly."
  },
  {
   "address": 53184,
   "type": "line",
   "text": "Fifty-six bytes $CFC0-$CFF7, all $27 in the saved state (the blank character the playfield uses): screen row 24 ($CFC0-$CFE7) of the screen at $CC00 and the 16 unused bytes before its sprite pointers. game_init writes $CFC0-$CFFF at $5218 from $8000-$803F of cartridge bank 13; no other routine in the listing names them."
  },
  {
   "address": 53248,
   "type": "line",
   "text": "Sprite shapes $40-$4F, sixteen blocks of 64 bytes at $D000-$D3FF (a shape is 21 rows of 3 bytes, multicolour two bits per pixel, plus one padding byte). This RAM lies under the I/O area, so the CPU reaches it only with the port $01 set to all RAM. The first routine game_start runs ($51FB) copies the first two blocks, $D000 from $8300 and $D040 from $9282 of cartridge bank 13, and the background loader fills the rest. The VIC-II sees these blocks in bank 3 as shape numbers $40-$4F. Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $40-$4F: GATE_OF_MOORNAH (bank 10 $8B03). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 54272,
   "type": "line",
   "text": "Sprite shapes $50-$5F at $D400-$D7FF. The saved state's sprite pointers ($0230 and $07E7) use shapes $5B, $5C and $5D ($D6C0, $D700, $D740). Filled by the background loader; the CPU reaches this RAM only with the port $01 set to all RAM. Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $50-$54: GATE_OF_MOORNAH (bank 10 $8F03); $55-$5E: Herbamo going left - #1 to Herbamo going right - #4 (bank 9 $8305); $5F: Blastums going left - death #1 (bank 9 $89C9). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 55296,
   "type": "line",
   "text": "Sprite shapes $60-$6F at $D800-$DBFF. With the I/O area visible the same addresses are the colour RAM, which recolour_screen fills ($D800-$DB47) and the status line writes ($DBA8-$DBAC); those writes go to the colour RAM chip, not to this RAM. This RAM is reached only with the port $01 set to all RAM and is filled by the background loader. Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $60-$63: Blastums going left - death #2 to Blastums going left - #1 (bank 9 $8A09); $64-$67: Blastums going right - #1 to Blastums going right - death #2 (bank 9 $88C8); $68-$6D: Wobalin #1 to Wobalin spear (bank 9 $924E); $6E-$6F: Spider #1 to Spider #2 (bank 9 $910C). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 56320,
   "type": "line",
   "text": "Sprite shapes $70-$7F at $DC00-$DFFF. With the I/O area visible, $DC00-$DCFF are CIA 1, $DD00-$DDFF CIA 2 and $DE00-$DFFF the cartridge I/O areas. This RAM is reached only with the port $01 set to all RAM and is filled by the background loader. Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $70-$71: Spider #3 to Spider #4 (bank 9 $918C); $72-$76: Seesaw to 16 ton weight (bank 9 $8586); $77-$7B: PLATFORM_GIANT_HEAD to PLATFORM_YIELDING (bank 8 $9DCE); $7C: PLATFORM_MOVING_1 (bank 8 $9D4C); $7D-$7F: Thorpedo head to Thorpedo body #2 (bank 9 $8184). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 56832,
   "type": "line",
   "text": "Cartridge bank-select register in the I/O 1 area (write $80 + bank number to select a bank at $8000). The game writes it as $DE00 with the I/O area visible; the RAM under this address belongs to sprite_shapes_70_7f."
  },
  {
   "address": 57344,
   "type": "line",
   "text": "Sprite shape area $E000-$E3FF, shapes $80-$8F, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $80-$82: Thorpedo body #3 to Thorpedo death #2 (bank 9 $8244); $83-$8E: Kalgatrobe - going right #1 to Kalgatrobe - going right #12 - body (bank 9 $8E0B); $8F: Spider shot (bank 9 $920D). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 58368,
   "type": "line",
   "text": "Sprite shape area $E400-$E7FF, shapes $90-$9F, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $90-$9B: Kalgatrobe - going left #1 to Kalgatrobe - going left #12 (bank 9 $8B0A); $9C-$9D: PLATFORM_GIANT_HEAD (bank 8 $9F51); $9E-$9F: (bank 7 $9F2C). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 59392,
   "type": "line",
   "text": "Sprite shape area $E800-$EBFF, shapes $A0-$AF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $A0-$A7: KILLER_HARNAS (bank 8 $8001); $A8-$AF: SHARTOESI (bank 8 $8484). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 60416,
   "type": "line",
   "text": "Sprite shape area $EC00-$EFFF, shapes $B0-$BF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $B0-$B3: COIN (bank 8 $8202); $B4-$BB: Shardu going left - #1 to Shardu going right - #3 (bank 9 $86C7); $BC-$BF: GEESHERGAM (bank 8 $8685). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 61440,
   "type": "line",
   "text": "Sprite shape area $F000-$F3FF, shapes $C0-$CF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $C0-$C5: GEESHERGAM (bank 8 $8785); $C6-$CD: (bank 11 $9D88); $CE-$CF: Helmet (bank 10 $8001). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 62464,
   "type": "line",
   "text": "Sprite shape area $F400-$F7FF, shapes $D0-$DF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $D0-$D1: Helmet (bank 10 $8081); $D2-$DB: (not found in the cartridge); $DC-$DD: (bank 12 $9F01); $DE-$DF: (not found in the cartridge). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 63488,
   "type": "line",
   "text": "Sprite shape area $F800-$FBFF, shapes $E0-$EF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $E0-$E1: (not found in the cartridge); $E2: continue from BankC - ; Screen Intro Bitmaps (bank 13 $9A01); $E3-$E9: (not found in the cartridge); $EA-$EC: continue from BankC - ; Screen Intro Bitmaps (bank 13 $9B26); $ED: (not found in the cartridge). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 64512,
   "type": "line",
   "text": "Sprite shape area $FC00-$FFFF, shapes $F0-$FF, 64 bytes each (RAM under the KERNAL ROM; the VIC-II reads it in bank 3). Shapes present in the saved state, with the cartridge bank and address they match byte for byte and Euan's label for that place in his annotated bank sources: $F4-$F7: TOKI $90C0 - Vicotry pose - body left to TOKI $9180 - Vicotry pose - legs right (bank 13 $90C0); $FC: TOKI $89C0 - Bum hit facing right (bank 13 $89C0); $FD: TOKI (bank 13 $8CC0); $FE: TOKI $9282 - Neutral right (bank 13 $9282); $FF: (not found in the cartridge; $FFC0-$FFFF holds score records and the processor vectors). Blank shapes are omitted; shapes marked not found are not a copy of cartridge data (built at run time or from a packed stream, origin not established)."
  },
  {
   "address": 64768,
   "type": "line",
   "text": "A 256-byte page copied from cartridge bank 13 ($90C0-$91BF) to $FD00 when a stage starts (b_0B25 in the stage-start routine at $0AFF). It is sprite shapes $F4-$F7 of VIC bank 3, the player's victory pose (see sprite_shapes_f0_ff). No routine in the listing reads it by address."
  },
  {
   "address": 65024,
   "type": "line",
   "text": "A 256-byte page, sprite shapes $F8-$FB of VIC bank 3: the between-stage screen routine at $4016 clears it, then runs $8C07 with the ROM visible and $E1/$E2 = $FE00, $E3/$E4 = $8B27 (STAGE CLEAR in bank 0), probably drawing that text into it (inferred). All zero in the saved state; only that clear loop names it by address."
  },
  {
   "address": 65280,
   "type": "line",
   "text": "Shape block of the player's first sprite, 63 bytes $FF00-$FF3E (sprite pointer $FC): the routine at $50D4 copies the shape named by player_shape_1 ($08EA) from the cartridge here."
  },
  {
   "address": 65344,
   "type": "line",
   "text": "Shape block of the player's second sprite, 63 bytes $FF40-$FF7E (sprite pointer $FD): the routine at $50F5 copies the shape named by $08EB here."
  },
  {
   "address": 65408,
   "type": "line",
   "text": "Shape block of the player's third sprite, 63 bytes $FF80-$FFBE (sprite pointer $FE): the routine at $50B3 copies the shape named by $08EC here."
  },
  {
   "address": 65470,
   "type": "line",
   "text": "Base of the copy loop at $51FD, which reads $FFBE+X for X from $C0 down to 1 and stores it at $44E0+X: the 192 bytes $FFBF-$FFFE are saved to $44E1-$45A0. $FFBE itself is the last byte of sprite_shape_block_3."
  },
  {
   "address": 65471,
   "type": "line",
   "text": "First byte of the 192 bytes saved by the loop at $51FD; b_525D writes it."
  },
  {
   "address": 65474,
   "type": "line",
   "text": "Five label character bytes of the first 9-byte record read by draw_status_label (X steps 0, 9, 18 and so on): the codes are added to $A5 to give tile codes ($1E, $1C, $1C, $1C, $1C in the first). Six records are visible in the saved state."
  },
  {
   "address": 65479,
   "type": "line",
   "text": "Byte tested for bit 6 by draw_status_label: records whose byte has bit 6 set are skipped. All the records in the saved state hold $FF here except the last, $80."
  },
  {
   "address": 65525,
   "type": "line",
   "text": "Five bytes $FFF5-$FFF9 ($1C each in the saved state), written by b_BD60 (store_score_digits at $BD5D) with the final score as digit values 0 to 9. They follow the six 9-byte records that draw_status_label reads (the last record ends with its flag at $FFF4); what reads them is not established."
  },
  {
   "address": 65530,
   "type": "line",
   "text": "The processor vectors in RAM under the KERNAL ROM: NMI $4D1D (nmi_frame), reset $0000, IRQ $837E (irq_panel). The ROM is hidden while the game runs, so the CPU reads these RAM bytes."
  }
 ]
}
