{
 "schema": 1,
 "platform": "c64",
 "game": "radar-rat-race",
 "build": "COMMODORE V.02",
 "source": "regenerator2000 live",
 "regions": {
  "exclude": [
   [
    256,
    511,
    "stack"
   ],
   [
    53248,
    57343,
    "I/O and colour RAM"
   ],
   [
    1024,
    2047,
    "screen RAM"
   ]
  ],
  "extra": [
   [
    14336,
    16383,
    "character set"
   ]
  ]
 },
 "blocks": [
  {
   "start": 0,
   "end": 53271,
   "type": "Undefined"
  },
  {
   "start": 53272,
   "end": 53272,
   "type": "Byte"
  },
  {
   "start": 53273,
   "end": 56575,
   "type": "Undefined"
  },
  {
   "start": 56576,
   "end": 56576,
   "type": "Byte"
  },
  {
   "start": 56577,
   "end": 57398,
   "type": "Undefined"
  },
  {
   "start": 57399,
   "end": 58315,
   "type": "Code"
  },
  {
   "start": 58316,
   "end": 58336,
   "type": "Undefined"
  },
  {
   "start": 58337,
   "end": 60931,
   "type": "Code"
  },
  {
   "start": 60932,
   "end": 60943,
   "type": "Undefined"
  },
  {
   "start": 60944,
   "end": 62319,
   "type": "Code"
  },
  {
   "start": 62320,
   "end": 62783,
   "type": "Undefined"
  },
  {
   "start": 62784,
   "end": 62817,
   "type": "Code"
  },
  {
   "start": 62818,
   "end": 65535,
   "type": "Undefined"
  }
 ],
 "symbols": [
  {
   "address": 0,
   "name": "zpa_00",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1,
   "name": "zpa_01",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2,
   "name": "red_rat_glyph_bl",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 6,
   "name": "red_rat_glyph_br",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 10,
   "name": "red_rat_glyph_tl",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 14,
   "name": "red_rat_glyph_tr",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 18,
   "name": "red_rat_clip_left_tr",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 22,
   "name": "red_rat_clip_left_br",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 26,
   "name": "red_rat_clip_right_tl",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 30,
   "name": "red_rat_clip_right_bl",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 34,
   "name": "red_rat_x",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 42,
   "name": "red_rat_y",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 50,
   "name": "red_rat_step_count",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 58,
   "name": "red_rat_dir",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 66,
   "name": "red_rat_facing",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 74,
   "name": "red_rat_stun_timer",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 82,
   "name": "star_x_queue",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 97,
   "name": "star_y_queue",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 112,
   "name": "star_life_queue",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 127,
   "name": "tick_flag",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 128,
   "name": "move_cycle_interval",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 129,
   "name": "red_rat_count_minus1",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 130,
   "name": "zpp_82",
   "type": "ZeroPagePointer",
   "kind": "auto"
  },
  {
   "address": 131,
   "name": "zpa_83",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 132,
   "name": "zpa_84",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 133,
   "name": "zpa_85",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 134,
   "name": "zpa_86",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 135,
   "name": "zpa_87",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 136,
   "name": "zpa_88",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 137,
   "name": "zpa_89",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 138,
   "name": "zpa_8A",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 139,
   "name": "zpa_8B",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 140,
   "name": "zpa_8C",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 141,
   "name": "zpa_8D",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 142,
   "name": "zpa_8E",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 143,
   "name": "player_dir",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 144,
   "name": "zpp_90",
   "type": "ZeroPagePointer",
   "kind": "auto"
  },
  {
   "address": 145,
   "name": "zpa_91",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 146,
   "name": "player_x",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 147,
   "name": "player_y",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 148,
   "name": "player_facing",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 149,
   "name": "player_step_count",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 150,
   "name": "star_burst_left",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 151,
   "name": "player_turned_flag",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 152,
   "name": "eaten_slot",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 153,
   "name": "bonus_life_latch",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 154,
   "name": "player_caught",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 155,
   "name": "move_cycle_countdown",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 156,
   "name": "lives",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 157,
   "name": "star_last_index",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 158,
   "name": "cat_template_x_ptr",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 159,
   "name": "zpa_9F",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 160,
   "name": "cat_template_y_ptr",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 161,
   "name": "zpa_A1",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 162,
   "name": "maze_bitmap_ptr",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 163,
   "name": "zpa_A3",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 164,
   "name": "zpa_A4",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 165,
   "name": "zpa_A5",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 166,
   "name": "zpa_A6",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 167,
   "name": "chase_suggestion",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 168,
   "name": "red_rat_move_countdown",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 170,
   "name": "meal_x_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 180,
   "name": "meal_y_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 190,
   "name": "meals_remaining",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 191,
   "name": "bonus_cheese_eaten",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 192,
   "name": "score_doubler",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 193,
   "name": "x2_flash_timer",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 194,
   "name": "cat_x_table",
   "type": "ZeroPageField",
   "kind": "user"
  },
  {
   "address": 210,
   "name": "cat_y_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 226,
   "name": "round_number_bcd",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 227,
   "name": "round_index",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 228,
   "name": "round_timer",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 229,
   "name": "joystick_dir",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 230,
   "name": "fire_pressed",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 231,
   "name": "score_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 232,
   "name": "hiscore_hi",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 233,
   "name": "score_mid",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 234,
   "name": "hiscore_mid",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 235,
   "name": "score_lo",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 236,
   "name": "hiscore_lo",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 237,
   "name": "zpa_ED",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 238,
   "name": "zpa_EE",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 247,
   "name": "game_in_progress",
   "type": "ZeroPageAbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 512,
   "name": "x2_flash_phase",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 513,
   "name": "cat_count_minus1",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 514,
   "name": "fill_colour",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 515,
   "name": "slices_eaten",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 516,
   "name": "time_drain_interval",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 517,
   "name": "time_drain_countdown",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 518,
   "name": "low_time_beeps_left",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 519,
   "name": "low_time_beep_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 520,
   "name": "timeout_check_countdown",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 521,
   "name": "fanfare_note_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 522,
   "name": "cheese_sfx_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 523,
   "name": "music_note_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 524,
   "name": "music_phrase_count",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 525,
   "name": "music_note_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 526,
   "name": "sfx3_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 527,
   "name": "bonus_sfx_index",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 528,
   "name": "speed_run_number",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 529,
   "name": "speed_run_step_timer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 530,
   "name": "speed_run_note_timer",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 531,
   "name": "speed_run_letter_index",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 532,
   "name": "speed_run_note_index",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 533,
   "name": "cold_start_clear_pending",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 534,
   "name": "star_sound_gate",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 535,
   "name": "new_hiscore_flag",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 536,
   "name": "prng_lo",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 537,
   "name": "prng_hi",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 1067,
   "name": "f_042B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1074,
   "name": "time_bar_cells",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 1087,
   "name": "f_043F",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1207,
   "name": "f_04B7",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1230,
   "name": "f_04CE",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1309,
   "name": "f_051D",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1347,
   "name": "f_0543",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1376,
   "name": "f_0560",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1387,
   "name": "f_056B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1389,
   "name": "f_056D",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1429,
   "name": "f_0595",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1456,
   "name": "a_05B0",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1457,
   "name": "a_05B1",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1458,
   "name": "a_05B2",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1459,
   "name": "a_05B3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1461,
   "name": "a_05B5",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1462,
   "name": "a_05B6",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1474,
   "name": "f_05C2",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1477,
   "name": "a_05C5",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1508,
   "name": "a_05E4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1510,
   "name": "f_05E6",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1587,
   "name": "f_0633",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1639,
   "name": "a_0667",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1668,
   "name": "a_0684",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1678,
   "name": "a_068E",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1680,
   "name": "a_0690",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1709,
   "name": "f_06AD",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1719,
   "name": "a_06B7",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1758,
   "name": "f_06DE",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1776,
   "name": "f_06F0",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1819,
   "name": "a_071B",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1820,
   "name": "a_071C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 1947,
   "name": "f_079B",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 1961,
   "name": "a_07A9",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2040,
   "name": "a_07F8",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 2041,
   "name": "f_07F9",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 14336,
   "name": "charset_base",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14344,
   "name": "font_letters_AZ",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14552,
   "name": "font_keycaps_SPL",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14592,
   "name": "font_space_solid",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14600,
   "name": "font_bright_CEDRUN",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14648,
   "name": "font_punct_quote_parens",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14672,
   "name": "font_star_single",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14680,
   "name": "font_bright_O",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14688,
   "name": "font_punct_comma_slash",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14720,
   "name": "font_digits",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14800,
   "name": "font_colon_semicolon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14816,
   "name": "font_bright_GAMV",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14848,
   "name": "tile_rat_4dir",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 14976,
   "name": "tile_cheese_2x",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15008,
   "name": "tile_star_cluster",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15040,
   "name": "tile_black_cat",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15072,
   "name": "tile_eeek",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15104,
   "name": "tile_radar_blips",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15136,
   "name": "tile_life_icon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15168,
   "name": "font_blank_codes",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15288,
   "name": "tile_time_bar",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15360,
   "name": "radar_sprite_shapes",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15440,
   "name": "sprite_block_tail",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15488,
   "name": "copy_viewport_row_lo",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15506,
   "name": "copy_viewport_row_hi",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15524,
   "name": "copy_viewport_colour_row_hi",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15542,
   "name": "copy_radar_row_addr_lo",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15556,
   "name": "copy_radar_row_addr_hi",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15570,
   "name": "copy_bit_select_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15578,
   "name": "copy_str_hi_score",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15586,
   "name": "copy_str_score",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15594,
   "name": "copy_str_time_bar",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15601,
   "name": "copy_time_bar_cells",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15611,
   "name": "copy_str_copyright",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15646,
   "name": "copy_str_next_meal",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15659,
   "name": "copy_str_game_over",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15671,
   "name": "copy_str_speed_run",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15685,
   "name": "copy_str_no",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15690,
   "name": "copy_stamp_offsets_4x2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15698,
   "name": "copy_str_push",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15715,
   "name": "copy_str_bonus_rat",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15727,
   "name": "copy_str_for_20000_pts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15740,
   "name": "copy_str_version",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15754,
   "name": "copy_str_star_screen",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15765,
   "name": "copy_str_move_rat",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15776,
   "name": "copy_stamp_offsets_legend",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15791,
   "name": "copy_rat_and_eeek_codes",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15811,
   "name": "copy_probe_ptrs",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15819,
   "name": "copy_red_rat_glyph_source",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15851,
   "name": "copy_dir_tables",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15859,
   "name": "copy_red_rat_spawn",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 15872,
   "name": "copy_fe00_tables",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 16091,
   "name": "copy_round_tables",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 16136,
   "name": "copy_round_flags",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 16166,
   "name": "copy_filler",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 16378,
   "name": "copy_cpu_vectors",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32681,
   "name": "a_7FA9",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55346,
   "name": "f_D832",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 55500,
   "name": "a_D8CC",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55507,
   "name": "a_D8D3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55746,
   "name": "f_D9C2",
   "type": "Field",
   "kind": "auto"
  },
  {
   "address": 55747,
   "name": "a_D9C3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55748,
   "name": "a_D9C4",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55787,
   "name": "a_D9EB",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 55788,
   "name": "a_D9EC",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 57344,
   "name": "vic_register_init",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 57374,
   "name": "sid_register_init",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 57399,
   "name": "cold_start",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 57406,
   "name": "b_E03E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57417,
   "name": "b_E049",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57480,
   "name": "move_all_red_rats",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 57484,
   "name": "b_E08C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57495,
   "name": "b_E097",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57506,
   "name": "j_E0A2",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57519,
   "name": "b_E0AF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57527,
   "name": "b_E0B7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57569,
   "name": "b_E0E1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57581,
   "name": "b_E0ED",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57585,
   "name": "b_E0F1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57624,
   "name": "j_E118",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57633,
   "name": "b_E121",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57641,
   "name": "b_E129",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57649,
   "name": "b_E131",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57651,
   "name": "b_E133",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57659,
   "name": "b_E13B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57665,
   "name": "b_E141",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57671,
   "name": "b_E147",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57677,
   "name": "j_E14D",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57681,
   "name": "j_E151",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57684,
   "name": "j_E154",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57690,
   "name": "b_E15A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57693,
   "name": "draw_red_rats_in_viewport",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 57695,
   "name": "j_E15F",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57711,
   "name": "b_E16F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57736,
   "name": "b_E188",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57748,
   "name": "b_E194",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57772,
   "name": "b_E1AC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57784,
   "name": "b_E1B8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57805,
   "name": "b_E1CD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57828,
   "name": "b_E1E4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57860,
   "name": "j_E204",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 57868,
   "name": "red_rat_can_step",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 57912,
   "name": "r_E238",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 57913,
   "name": "b_E239",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57916,
   "name": "red_rat_chase_direction",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 57925,
   "name": "b_E245",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57936,
   "name": "b_E250",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57944,
   "name": "b_E258",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57954,
   "name": "r_E262",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 57955,
   "name": "b_E263",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57966,
   "name": "b_E26E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57974,
   "name": "b_E276",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 57982,
   "name": "r_E27E",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 57983,
   "name": "maze_bitmap_ptr_from_world_xy",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58004,
   "name": "b_E294",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58019,
   "name": "r_E2A3",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 58020,
   "name": "red_rat_hit_test",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58023,
   "name": "b_E2A7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58030,
   "name": "b_E2AE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58035,
   "name": "b_E2B3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58044,
   "name": "b_E2BC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58046,
   "name": "b_E2BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58055,
   "name": "b_E2C7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58060,
   "name": "b_E2CC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58071,
   "name": "b_E2D7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58075,
   "name": "b_E2DB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58082,
   "name": "b_E2E2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58087,
   "name": "b_E2E7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58098,
   "name": "b_E2F2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58100,
   "name": "b_E2F4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58102,
   "name": "r_E2F6",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 58103,
   "name": "draw_meals_on_radar",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58105,
   "name": "b_E2F9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58118,
   "name": "b_E306",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58128,
   "name": "b_E310",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58150,
   "name": "b_E326",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58153,
   "name": "radar_ptr_from_world_xy",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58183,
   "name": "r_E347",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 58184,
   "name": "clear_meal_blip_on_radar",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58206,
   "name": "radar_sprite_player",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 58228,
   "name": "b_E374",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58236,
   "name": "b_E37C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58252,
   "name": "radar_sprites_red_rats",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58263,
   "name": "b_E397",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58286,
   "name": "b_E3AE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58295,
   "name": "b_E3B7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58316,
   "name": "sprite_msb_set",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 58323,
   "name": "sprite_msb_clear",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 58330,
   "name": "sprite_enable_for_count",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 58337,
   "name": "draw_maze_viewport",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58381,
   "name": "b_E40D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58383,
   "name": "b_E40F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58399,
   "name": "maze_viewport_column_setup",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58420,
   "name": "b_E434",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58432,
   "name": "b_E440",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58485,
   "name": "b_E475",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58493,
   "name": "b_E47D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58508,
   "name": "b_E48C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58572,
   "name": "b_E4CC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58595,
   "name": "b_E4E3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58606,
   "name": "b_E4EE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58612,
   "name": "maze_viewport_rows_halfcell_x",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 58616,
   "name": "b_E4F8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58664,
   "name": "b_E528",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58679,
   "name": "maze_viewport_next_row",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58691,
   "name": "b_E543",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58702,
   "name": "b_E54E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58713,
   "name": "b_E559",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58724,
   "name": "b_E564",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58734,
   "name": "r_E56E",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 58735,
   "name": "maze_viewport_draw_cell_row",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58747,
   "name": "maze_viewport_draw_span",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 58753,
   "name": "b_E581",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58765,
   "name": "b_E58D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58780,
   "name": "b_E59C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58782,
   "name": "b_E59E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58800,
   "name": "b_E5B0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58822,
   "name": "b_E5C6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58830,
   "name": "b_E5CE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58832,
   "name": "b_E5D0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58848,
   "name": "draw_cats_in_viewport",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 58851,
   "name": "j_E5E3",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 58884,
   "name": "b_E604",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58908,
   "name": "b_E61C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58929,
   "name": "b_E631",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58952,
   "name": "b_E648",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58986,
   "name": "b_E66A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 58992,
   "name": "draw_cheese_in_viewport",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 58994,
   "name": "j_E672",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 59027,
   "name": "b_E693",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59051,
   "name": "b_E6AB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59072,
   "name": "b_E6C0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59095,
   "name": "b_E6D7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59127,
   "name": "b_E6F7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59135,
   "name": "b_E6FF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59140,
   "name": "draw_2x_marker",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 59156,
   "name": "b_E714",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59162,
   "name": "b_E71A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59182,
   "name": "b_E72E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59191,
   "name": "r_E737",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 59192,
   "name": "viewport_ptr_from_world_xy",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59218,
   "name": "b_E752",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59242,
   "name": "b_E76A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59273,
   "name": "b_E789",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59276,
   "name": "move_player",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59288,
   "name": "b_E798",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59333,
   "name": "b_E7C5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59345,
   "name": "b_E7D1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59358,
   "name": "b_E7DE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59380,
   "name": "b_E7F4",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59392,
   "name": "j_E800",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 59401,
   "name": "b_E809",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59409,
   "name": "b_E811",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59417,
   "name": "b_E819",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59419,
   "name": "b_E81B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59421,
   "name": "b_E81D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59425,
   "name": "j_E821",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 59446,
   "name": "b_E836",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59470,
   "name": "b_E84E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59473,
   "name": "j_E851",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 59485,
   "name": "b_E85D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59494,
   "name": "b_E866",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59503,
   "name": "b_E86F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59506,
   "name": "b_E872",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59509,
   "name": "read_screen_in_direction",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59524,
   "name": "draw_rat_facing_up",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59526,
   "name": "b_E886",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59538,
   "name": "draw_rat_facing_right",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59540,
   "name": "b_E894",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59552,
   "name": "draw_rat_facing_down",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59554,
   "name": "b_E8A2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59566,
   "name": "draw_rat_facing_left",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59568,
   "name": "b_E8B0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59580,
   "name": "draw_eeek_text",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59582,
   "name": "b_E8BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59594,
   "name": "colour_rat_blue",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59609,
   "name": "star_screen_update",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59617,
   "name": "b_E8E1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59664,
   "name": "drop_star",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59669,
   "name": "b_E915",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59700,
   "name": "b_E934",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59732,
   "name": "b_E954",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59742,
   "name": "age_and_draw_stars",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 59752,
   "name": "b_E968",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59757,
   "name": "b_E96D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59764,
   "name": "b_E974",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59797,
   "name": "b_E995",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59821,
   "name": "b_E9AD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59842,
   "name": "b_E9C2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59865,
   "name": "b_E9D9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59899,
   "name": "b_E9FB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59905,
   "name": "r_EA01",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 59906,
   "name": "per_tick_sound_and_timers",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 59937,
   "name": "b_EA21",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59947,
   "name": "music_tick",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 59953,
   "name": "kernal_irq_vector_value",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59993,
   "name": "b_EA59",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 59996,
   "name": "sfx_voice3_tick",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 60020,
   "name": "b_EA74",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60034,
   "name": "b_EA82",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60052,
   "name": "low_time_warning",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 60078,
   "name": "b_EAAE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60096,
   "name": "timeout_handler",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 60118,
   "name": "b_EAD6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60129,
   "name": "b_EAE1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60132,
   "name": "round_complete_jingle",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60136,
   "name": "b_EAE8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60160,
   "name": "b_EB00",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60162,
   "name": "b_EB02",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60184,
   "name": "b_EB18",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60200,
   "name": "b_EB28",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60212,
   "name": "speed_run_intro",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60264,
   "name": "b_EB68",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60305,
   "name": "b_EB91",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60315,
   "name": "b_EB9B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60324,
   "name": "print_speed_run_number",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60334,
   "name": "b_EBAE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60367,
   "name": "game_start_fanfare",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 60385,
   "name": "b_EBE1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60418,
   "name": "b_EC02",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60426,
   "name": "clear_screen_and_draw_hud",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60446,
   "name": "b_EC1E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60466,
   "name": "b_EC32",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60477,
   "name": "b_EC3D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60488,
   "name": "b_EC48",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60501,
   "name": "b_EC55",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60509,
   "name": "b_EC5D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60520,
   "name": "b_EC68",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60542,
   "name": "b_EC7E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60551,
   "name": "print_round_and_start_life",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60573,
   "name": "b_EC9D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60607,
   "name": "b_ECBF",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60703,
   "name": "b_ED1F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60753,
   "name": "clear_maze_window",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60759,
   "name": "fill_maze_window_colour",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60780,
   "name": "fill_rect",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60782,
   "name": "b_ED6E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60809,
   "name": "b_ED89",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60813,
   "name": "read_controls",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60823,
   "name": "b_ED97",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60844,
   "name": "b_EDAC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60853,
   "name": "b_EDB5",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60862,
   "name": "b_EDBE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60871,
   "name": "KERNAL_TKSAj",
   "type": "Predefined",
   "kind": "system"
  },
  {
   "address": 60881,
   "name": "b_EDD1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60883,
   "name": "b_EDD3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60889,
   "name": "b_EDD9",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60907,
   "name": "b_EDEB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60915,
   "name": "b_EDF3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60931,
   "name": "r_EE03",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 60932,
   "name": "key_row_select",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 60936,
   "name": "key_column_mask",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 60940,
   "name": "key_direction",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 60944,
   "name": "irq_tick",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60962,
   "name": "wait_80_ticks",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 60964,
   "name": "b_EE24",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 60974,
   "name": "prng_next",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 60976,
   "name": "b_EE30",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61006,
   "name": "b_EE4E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61015,
   "name": "setup_cats",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61033,
   "name": "b_EE69",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61059,
   "name": "b_EE83",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61066,
   "name": "b_EE8A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61089,
   "name": "b_EEA1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61096,
   "name": "place_meal_items",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 61098,
   "name": "j_EEAA",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 61100,
   "name": "b_EEAC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61139,
   "name": "b_EED3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61146,
   "name": "b_EEDA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61178,
   "name": "b_EEFA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61182,
   "name": "b_EEFE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61184,
   "name": "b_EF00",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61191,
   "name": "b_EF07",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61196,
   "name": "b_EF0C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61205,
   "name": "b_EF15",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61207,
   "name": "b_EF17",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61214,
   "name": "b_EF1E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61246,
   "name": "b_EF3E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61260,
   "name": "r_EF4C",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 61261,
   "name": "draw_spare_life_icons",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61271,
   "name": "b_EF57",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61305,
   "name": "r_EF79",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 61306,
   "name": "attract_screen",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 61323,
   "name": "b_EF8B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61334,
   "name": "b_EF96",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61345,
   "name": "b_EFA1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61362,
   "name": "b_EFB2",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61373,
   "name": "b_EFBD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61425,
   "name": "b_EFF1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61431,
   "name": "attract_wait_for_f1",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 61455,
   "name": "b_F00F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61474,
   "name": "b_F022",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61482,
   "name": "add_score",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61532,
   "name": "b_F05C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61536,
   "name": "score_display_and_hiscore_update",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 61542,
   "name": "b_F066",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61587,
   "name": "print_hiscore",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61599,
   "name": "b_F09F",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61613,
   "name": "r_F0AD",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 61614,
   "name": "print_bcd_byte_2digits",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 61625,
   "name": "print_bcd_digit",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61635,
   "name": "b_F0C3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61640,
   "name": "b_F0C8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61642,
   "name": "check_meal_eaten",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61644,
   "name": "b_F0CC",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61651,
   "name": "b_F0D3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61655,
   "name": "b_F0D7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61696,
   "name": "b_F100",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61698,
   "name": "b_F102",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61713,
   "name": "b_F111",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61726,
   "name": "b_F11E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61728,
   "name": "score_slice",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 61751,
   "name": "print_next_meal_value",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 61769,
   "name": "b_F149",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61776,
   "name": "score_tenth_slice",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 61796,
   "name": "r_F164",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 61797,
   "name": "tick_round_timer",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 61803,
   "name": "b_F16B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61819,
   "name": "b_F17B",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61833,
   "name": "b_F189",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61836,
   "name": "b_F18C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61840,
   "name": "time_bonus",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 61847,
   "name": "b_F197",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61854,
   "name": "b_F19E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61866,
   "name": "b_F1AA",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61886,
   "name": "b_F1BE",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61892,
   "name": "cold_start_game_state",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 61894,
   "name": "b_F1C6",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 61922,
   "name": "game_over_reset",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 61949,
   "name": "setup_round",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 62006,
   "name": "start_life",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 62036,
   "name": "b_F254",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62049,
   "name": "b_F261",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62056,
   "name": "b_F268",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62059,
   "name": "play_life",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 62065,
   "name": "main_loop",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 62087,
   "name": "b_F287",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62105,
   "name": "b_F299",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62119,
   "name": "b_F2A7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62143,
   "name": "next_round",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 62155,
   "name": "b_F2CB",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62167,
   "name": "b_F2D7",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62174,
   "name": "player_caught_sequence",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 62205,
   "name": "b_F2FD",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62217,
   "name": "b_F309",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62248,
   "name": "game_over_banner",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62250,
   "name": "b_F32A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62276,
   "name": "player_collision_check",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62279,
   "name": "b_F347",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62285,
   "name": "b_F34D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62290,
   "name": "b_F352",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62298,
   "name": "b_F35A",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62300,
   "name": "b_F35C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62306,
   "name": "b_F362",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62311,
   "name": "b_F367",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62317,
   "name": "collision_flag_inc",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 62319,
   "name": "r_F36F",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 62320,
   "name": "maze_bitmap_a",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62544,
   "name": "maze_bitmap_b",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62768,
   "name": "paramset_to_maze_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 62770,
   "name": "paramset_to_maze_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 62784,
   "name": "music_pick_note",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 62802,
   "name": "b_F552",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62805,
   "name": "b_F555",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 62811,
   "name": "set_voice1_freq",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 64640,
   "name": "viewport_row_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64658,
   "name": "viewport_row_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64676,
   "name": "viewport_colour_row_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64694,
   "name": "radar_row_addr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64708,
   "name": "radar_row_addr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64722,
   "name": "bit_select_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 64730,
   "name": "str_hi_score",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64738,
   "name": "str_score",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64738,
   "name": "KERNAL_RESET_VECTOR",
   "type": "Predefined",
   "kind": "system"
  },
  {
   "address": 64746,
   "name": "str_time_bar",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64763,
   "name": "str_copyright",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64798,
   "name": "str_next_meal",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64806,
   "name": "str_round",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64811,
   "name": "str_game_over",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64819,
   "name": "str_speed_run",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64839,
   "name": "str_no",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64842,
   "name": "stamp_offsets_4x2",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64850,
   "name": "str_push",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64854,
   "name": "str_f1_to_run",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64866,
   "name": "str_bonus_rat",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64879,
   "name": "str_for_20000_pts",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64892,
   "name": "str_version",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64906,
   "name": "str_star_screen",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64917,
   "name": "str_move_rat",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64928,
   "name": "stamp_offsets_legend",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64939,
   "name": "stamp_offsets_2x2",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64940,
   "name": "meal_probe_offsets",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64943,
   "name": "rat_up_codes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64947,
   "name": "rat_right_codes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64951,
   "name": "rat_down_codes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64955,
   "name": "rat_left_codes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64959,
   "name": "eeek_codes",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64963,
   "name": "probe_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64967,
   "name": "probe_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 64971,
   "name": "red_rat_glyph_source",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65003,
   "name": "dir_dx_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65007,
   "name": "dir_dy_table",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65011,
   "name": "red_rat_spawn_x",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65018,
   "name": "red_rat_spawn_y",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65025,
   "name": "red_rat_chase_axis",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65032,
   "name": "cat_template0_x",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 65048,
   "name": "cat_template0_y",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 65064,
   "name": "cat_template1_x",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 65080,
   "name": "cat_template1_y",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 65096,
   "name": "paramset_to_cat_x_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65098,
   "name": "paramset_to_cat_x_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65100,
   "name": "paramset_to_cat_y_ptr_lo",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65102,
   "name": "paramset_to_cat_y_ptr_hi",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65104,
   "name": "tune_round_complete",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65111,
   "name": "tune_cheese_eaten",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65115,
   "name": "music_phrase_a",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65131,
   "name": "music_phrase_b",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65147,
   "name": "tune_bonus_2x",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65180,
   "name": "tune_speed_run",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65196,
   "name": "tune_game_start",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65243,
   "name": "round_to_red_rat_count_minus1",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65258,
   "name": "round_to_red_rat_move_ticks",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65273,
   "name": "round_to_cat_count_minus1",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65288,
   "name": "round_is_speed_run",
   "type": "Field",
   "kind": "user"
  },
  {
   "address": 65303,
   "name": "round_to_paramset",
   "type": "Field",
   "kind": "user"
  }
 ],
 "comments": [
  {
   "address": 0,
   "type": "line",
   "text": "The 6510 processor port: $00 is its data-direction register and $01 the port itself. cold_start writes $2F and $E5, banking BASIC and the KERNAL out (RAM at $A000-$BFFF and $E000-$FFFF) while leaving I/O visible at $D000."
  },
  {
   "address": 1,
   "type": "line",
   "text": "The 6510 processor port itself. cold_start writes $E5: LORAM=1, HIRAM=0, CHAREN=1, which maps RAM at $A000-$BFFF and $E000-$FFFF with I/O at $D000-$DFFF. The game runs entirely in that configuration. See zpa_00."
  },
  {
   "address": 2,
   "type": "line",
   "text": "Red rat glyph tables, eight 4-byte tables at $02-$21, one byte per facing (0=up, 1=right, 2=down, 3=left). Each table holds one quadrant of the 2x2 rat tile: $02 bottom-left ($42/$46/$4A/$4E), $06 bottom-right, $0A top-left, $0E top-right, then four more used when the tile is clipped at the edge of the viewport ($12 top-right and $16 bottom-right for a left-edge clip, $1A top-left and $1E bottom-left for a right-edge clip). They live in zero page, copied from red_rat_glyph_source ($FDCB) at power-on, because move_all_red_rats zeroes all 32 bytes to erase the red rats (drawing glyph $00, the empty floor cell) and then reloads them to redraw. Read by draw_red_rats_in_viewport."
  },
  {
   "address": 6,
   "type": "line",
   "text": "Bottom-right quadrant codes per facing. See red_rat_glyph_bl."
  },
  {
   "address": 10,
   "type": "line",
   "text": "Top-left quadrant codes per facing. See red_rat_glyph_bl."
  },
  {
   "address": 14,
   "type": "line",
   "text": "Top-right quadrant codes per facing. See red_rat_glyph_bl."
  },
  {
   "address": 18,
   "type": "line",
   "text": "Top-right quadrant codes, used when the red rat's left half is off the viewport. See red_rat_glyph_bl."
  },
  {
   "address": 22,
   "type": "line",
   "text": "Bottom-right quadrant codes, used when the red rat's left half is off the viewport. See red_rat_glyph_bl."
  },
  {
   "address": 26,
   "type": "line",
   "text": "Top-left quadrant codes, used when the red rat's right half is off the viewport. See red_rat_glyph_bl."
  },
  {
   "address": 30,
   "type": "line",
   "text": "Bottom-left quadrant codes, used when the red rat's right half is off the viewport. See red_rat_glyph_bl."
  },
  {
   "address": 34,
   "type": "line",
   "text": "Red rat X positions, one byte per red rat, index 0 to red_rat_count_minus1 (at most 7 red rats; the eighth byte is loaded but never used). World units are half-cells: 0-63 across the 32-cell maze. Loaded from red_rat_spawn_x at the start of every life."
  },
  {
   "address": 42,
   "type": "line",
   "text": "Red rat Y positions in half-cells, 0-111 down the 56-row maze. Loaded from red_rat_spawn_y at the start of every life. See red_rat_x."
  },
  {
   "address": 50,
   "type": "line",
   "text": "Per-rat step counter, incremented once per half-cell step. Its low bit says whether the red rat is between cells; move_all_red_rats only picks a new direction when it is even (cell-aligned). Zeroed at the start of every life."
  },
  {
   "address": 58,
   "type": "line",
   "text": "Per-rat direction of travel, 0=up 1=right 2=down 3=left. Zeroed (up) at the start of every life."
  },
  {
   "address": 66,
   "type": "line",
   "text": "Per-rat drawn facing, 0-3, used to pick the tile from the red rat glyph tables. Normally equal to red_rat_dir; differs for one move during a U-turn (drawn a quarter-turn short) and cycles 3,2,1,0 while the red rat is stunned, making it spin."
  },
  {
   "address": 74,
   "type": "line",
   "text": "Per-rat stun countdown, in red rat moves. Written by red_rat_hit_test: 15 when the red rat lands on one of the player's stars, 7 when it lands on a black cat or on another red rat. While nonzero the red rat does not move; it spins in place and the counter drops by one each red rat move. At zero it carries on from where it stood. Nothing ever removes a red rat from play."
  },
  {
   "address": 82,
   "type": "line",
   "text": "Star Screen queue, X positions: 15 slots ($52-$60), slot 0 newest. drop_star shifts every entry up one slot and writes the new star at slot 0. Paired with star_y_queue and star_life_queue; star_last_index says how many are live."
  },
  {
   "address": 97,
   "type": "line",
   "text": "Star Screen queue, Y positions (15 slots, $61-$6F). See star_x_queue."
  },
  {
   "address": 112,
   "type": "line",
   "text": "Star Screen queue, remaining life of each star (15 slots, $70-$7E). A new star gets 50; age_and_draw_stars takes one off every live star once per player move cycle, so a star lasts 51 move cycles, about 5 seconds at the default pace. See star_x_queue."
  },
  {
   "address": 127,
   "type": "line",
   "text": "Set to 1 by the timer interrupt (irq_tick, about 60 times a second) and cleared by whichever loop is waiting for the next tick. Every timing loop in the game polls it. The main loop also clears it after each pass ($F2D7), so a pass that overruns a tick drops that tick rather than catching up."
  },
  {
   "address": 128,
   "type": "line",
   "text": "Player speed: ticks between player moves. Set when a life starts: 6 normally, 4 in a SPEED RUN. The player moves one half-cell per move cycle, so 6 means a whole maze cell every 12 ticks. Once round_timer reaches 0 it grows by 1 every 40 ticks up to 18, slowing the player to a crawl. star_screen_update also treats a value of exactly 4 as 'SPEED RUN in progress' and refuses to drop stars."
  },
  {
   "address": 129,
   "type": "line",
   "text": "Number of red rats in play MINUS ONE (loops run X from here down to 0). Set per round from round_to_red_rat_count_minus1: 3 to 7 red rats. Also selects how many radar sprites are enabled."
  },
  {
   "address": 130,
   "type": "line",
   "text": "zpp_82/zpa_83: general scratch pointer, reused by many routines with a different meaning in each: the maze bitmap row pointer in the viewport renderer and maze_bitmap_ptr_from_world_xy, the screen address of an object's tile in viewport_ptr_from_world_xy and its callers, the rat tile address ($05C3) when drawing the player, and the source pointer in setup_cats."
  },
  {
   "address": 131,
   "type": "line",
   "text": "High byte of the scratch pointer zpp_82."
  },
  {
   "address": 132,
   "type": "line",
   "text": "zpa_84/zpa_85: scratch. In the viewport renderer a screen-row pointer; in viewport_ptr_from_world_xy two clip flags ($FF when the object's left column, or top row, lies one cell outside the window); in the score printers the destination screen pointer; in setup_cats the Y-template pointer; in red_rat_can_step a saved red rat index."
  },
  {
   "address": 133,
   "type": "line",
   "text": "High byte / second clip flag paired with zpa_84: see zpa_84."
  },
  {
   "address": 134,
   "type": "line",
   "text": "zpa_86/zpa_87: scratch. Second screen-row pointer in the viewport renderer; the object's window column and row in viewport_ptr_from_world_xy ($11 = the last column/row, where only half a tile shows); a candidate world X/Y in place_meal_items and red_rat_can_step; a radar cell pointer in radar_ptr_from_world_xy."
  },
  {
   "address": 135,
   "type": "line",
   "text": "High byte / window row paired with zpa_86: see zpa_86."
  },
  {
   "address": 136,
   "type": "line",
   "text": "zpa_88: scratch counter/argument. Viewport cell index, loop counters, the saved slot in draw_meals_on_radar, and the BCD amount passed to add_score."
  },
  {
   "address": 137,
   "type": "line",
   "text": "zpa_89: scratch. Bitmap row start in draw_maze_viewport, world X in radar_ptr_from_world_xy, loop counters in the attract screen and time bonus."
  },
  {
   "address": 138,
   "type": "line",
   "text": "zpa_8A: scratch. Row-pass counter in the viewport renderer, world Y in radar_ptr_from_world_xy."
  },
  {
   "address": 139,
   "type": "line",
   "text": "zpa_8B: byte index into the current maze bitmap row while the viewport renderer unpacks it."
  },
  {
   "address": 140,
   "type": "line",
   "text": "zpa_8C: scratch. The previous direction in the red rat AI, a radar-cell coordinate in place_meal_items."
  },
  {
   "address": 141,
   "type": "line",
   "text": "zpa_8D: scratch. Red rat index, the direction behind the player in star_screen_update, the modulus passed to prng_next, and the fill character for fill_rect."
  },
  {
   "address": 142,
   "type": "line",
   "text": "zpa_8E: object X passed to viewport_ptr_from_world_xy (object Y goes in A)."
  },
  {
   "address": 143,
   "type": "line",
   "text": "The player's direction of travel, 0=up 1=right 2=down 3=left. Changed by move_player when the joystick asks for an open direction, or automatically when the way ahead is blocked. Reset to up at the start of every life."
  },
  {
   "address": 144,
   "type": "line",
   "text": "zpp_90/zpa_91: scratch colour-RAM pointer, always the twin of the screen pointer in zpp_82 so a tile's character and colour are written together."
  },
  {
   "address": 145,
   "type": "line",
   "text": "High byte of the colour-RAM scratch pointer zpp_90."
  },
  {
   "address": 146,
   "type": "line",
   "text": "Player X in half-cells (0-63). Starts at $1E (cell 15) every life. The maze viewport is centred on it."
  },
  {
   "address": 147,
   "type": "line",
   "text": "Player Y in half-cells (0-111). Starts at $64 (row 50) every life, near the red rat spawn points at the bottom of the maze."
  },
  {
   "address": 148,
   "type": "line",
   "text": "Facing used to draw the player's tile, normally player_dir. During a U-turn it is drawn a quarter-turn short for one move."
  },
  {
   "address": 149,
   "type": "line",
   "text": "Half-cell steps taken this life. Odd means the player is between cells: move_player then keeps going without reading the controls, and stars and cheese are not checked."
  },
  {
   "address": 150,
   "type": "line",
   "text": "Stars still to drop in the current Star Screen burst. Fire sets 3; drop_star takes one off per star."
  },
  {
   "address": 151,
   "type": "line",
   "text": "Set by move_player when the player made a 90-degree turn this move instead of stepping. star_screen_update skips a drop on those moves."
  },
  {
   "address": 152,
   "type": "line",
   "text": "Meal-table slot of the cheese just eaten, set by check_meal_eaten for clear_meal_blip_on_radar."
  },
  {
   "address": 153,
   "type": "line",
   "text": "Set when the bonus life is awarded at 20,000 points. Only game_over_reset clears it, so the bonus is given once per game."
  },
  {
   "address": 154,
   "type": "line",
   "text": "Nonzero once player_collision_check finds the player on a red rat or a black cat. The main loop checks it after the player moves and again after the red rats move, and starts player_caught_sequence."
  },
  {
   "address": 155,
   "type": "line",
   "text": "Counts ticks down to the next player move; reloaded from move_cycle_interval. The star sound is also cut when it reaches 3."
  },
  {
   "address": 156,
   "type": "line",
   "text": "Lives, including the one in play. 3 at the start of a game; +1 at 20,000 points; -1 each time the player is caught. The HUD shows lives-1 spare-rat icons."
  },
  {
   "address": 157,
   "type": "line",
   "text": "Index of the oldest live star in the star queue, $FF when there are none. Also the loop bound for drawing stars and for red_rat_hit_test's star check."
  },
  {
   "address": 158,
   "type": "line",
   "text": "Pointer ($9E/$9F) to this round's 16-byte cat X template, set by setup_round from paramset_to_cat_x_ptr_lo/hi."
  },
  {
   "address": 159,
   "type": "line",
   "text": "High byte of cat_template_x_ptr."
  },
  {
   "address": 160,
   "type": "line",
   "text": "Pointer ($A0/$A1) to this round's 16-byte cat Y template, set by setup_round."
  },
  {
   "address": 161,
   "type": "line",
   "text": "High byte of cat_template_y_ptr."
  },
  {
   "address": 162,
   "type": "line",
   "text": "Pointer ($A2/$A3) to this round's maze bitmap, maze_bitmap_a ($F370) or maze_bitmap_b ($F450), set by setup_round. Read by draw_maze_viewport and maze_bitmap_ptr_from_world_xy."
  },
  {
   "address": 163,
   "type": "line",
   "text": "High byte of maze_bitmap_ptr."
  },
  {
   "address": 164,
   "type": "line",
   "text": "zpa_A4/zpa_A5/zpa_A6: viewport renderer scratch. A4 = current destination column, A5 = maze bitmap row being drawn (compared against 56 to fill rows outside the maze with border), A6 = the column to stop at."
  },
  {
   "address": 165,
   "type": "line",
   "text": "Maze bitmap row currently being drawn by the viewport renderer; rows 56 and above (including negative rows, which wrap) are filled with border. See zpa_A4."
  },
  {
   "address": 166,
   "type": "line",
   "text": "Column at which the viewport renderer's inner loop stops. See zpa_A4."
  },
  {
   "address": 167,
   "type": "line",
   "text": "Direction red_rat_chase_direction wants the current red rat to take, or $FF for no preference."
  },
  {
   "address": 168,
   "type": "line",
   "text": "Ticks until the red rats next move; reloaded from round_to_red_rat_move_ticks (6, or 5 from round 8). At the start of a life it is 79, a grace period of about 1.3 seconds before the red rats set off. In a SPEED RUN it starts at $FF, which the main loop treats as 'frozen': the red rats do not move at all until the round timer runs out, when timeout_handler sets it to 1. While it is 9 or more the red rats are also redrawn every time the viewport is, so frozen or waiting red rats stay visible."
  },
  {
   "address": 170,
   "type": "line",
   "text": "Cheese X positions, 10 slots. Placed at round setup by place_meal_items. Slot 0 is the special '2x' cheese; slots 1 to meals_remaining are ordinary cheese. Eating an ordinary one compacts it out of the table; eating the 2x one leaves it in place and sets bonus_cheese_eaten. Positions are always even (cell-aligned)."
  },
  {
   "address": 180,
   "type": "line",
   "text": "Cheese Y positions, 10 slots, paired with meal_x_table."
  },
  {
   "address": 190,
   "type": "line",
   "text": "Ordinary cheese still to eat this round, 9 at round setup. The round is complete when this is 0 and bonus_cheese_eaten is set, i.e. all ten are gone."
  },
  {
   "address": 191,
   "type": "line",
   "text": "Set when the 2x cheese (meal slot 0) is eaten; cleared at round setup. Stops slot 0 being drawn in the maze or on the radar, and is half of the round-complete test."
  },
  {
   "address": 192,
   "type": "line",
   "text": "Set together with bonus_cheese_eaten when the 2x cheese is eaten, but cleared at the start of every life. While set, every cheese scores twice, the 2x cheese included."
  },
  {
   "address": 193,
   "type": "line",
   "text": "Drives the flashing 'X2' next to the NEXT MEAL value: set to 1 when the 2x cheese is eaten, then per_tick_sound_and_timers reloads it with 20 and toggles the text each time it expires. $FF (off) at the start of every life."
  },
  {
   "address": 194,
   "type": "line",
   "text": "Black cat X positions, 16 slots. setup_cats copies them from one of two 16-entry templates; in normal rounds it then deletes 8 entries at random, leaving 8 cats in slots 0-7 in template order. SPEED RUN rounds keep all 16. The cats never move. Touching one kills the player (player_collision_check); a red rat that touches one is stunned. Cats are drawn only in the viewport, never on the radar."
  },
  {
   "address": 210,
   "type": "line",
   "text": "Black cat Y positions, 16 slots, paired with cat_x_table."
  },
  {
   "address": 226,
   "type": "line",
   "text": "The round number shown under ROUND on the HUD, in BCD. 1 at game start, +1 per completed round, never wrapped by the game (round_index is what wraps)."
  },
  {
   "address": 227,
   "type": "line",
   "text": "Index into the per-round tables, 0-14. +1 per completed round and back to 0 after 14, so round 16 uses exactly the same settings as round 1: the game's difficulty repeats on a 15-round cycle."
  },
  {
   "address": 228,
   "type": "line",
   "text": "TIME, 0-80, drawn as the ten-cell bar at the top left (8 steps per cell). Set to 80 at the start of every life. Drops by one every time_drain_interval ticks (70, or 35 in a SPEED RUN, so about 95 or 47 seconds from full), by one for every star dropped, and by one per step of the end-of-round time bonus. At 12 the low-time beeps play. At 0 no more stars can be dropped, and timeout_handler starts slowing the player down (or, in a SPEED RUN, releases the red rats)."
  },
  {
   "address": 229,
   "type": "line",
   "text": "Direction requested by read_controls this move, 0-3, or $FF for none."
  },
  {
   "address": 230,
   "type": "line",
   "text": "Nonzero when read_controls saw fire (joystick button, or S on the keyboard)."
  },
  {
   "address": 231,
   "type": "line",
   "text": "Score, most significant BCD byte. The score is three BCD bytes, score_hi/score_mid/score_lo, interleaved with the high score bytes at $E8/$EA/$EC. The display appends a fixed trailing '0', so the stored value is the score divided by ten."
  },
  {
   "address": 232,
   "type": "line",
   "text": "High score, most significant BCD byte. Interleaved with the score bytes; see score_hi. Set to 002000 (shown as 20000) at power-on and kept across games."
  },
  {
   "address": 233,
   "type": "line",
   "text": "Score, middle BCD byte. add_score awards the bonus life when this is exactly $20, i.e. the score is 20,000-20,990."
  },
  {
   "address": 234,
   "type": "line",
   "text": "High score, middle BCD byte."
  },
  {
   "address": 235,
   "type": "line",
   "text": "Score, least significant BCD byte; add_score adds its argument here and carries upwards."
  },
  {
   "address": 236,
   "type": "line",
   "text": "High score, least significant BCD byte."
  },
  {
   "address": 237,
   "type": "line",
   "text": "zpa_ED/zpa_EE: the second colour-RAM row pointer in the viewport renderer, twin of zpa_86/87."
  },
  {
   "address": 238,
   "type": "line",
   "text": "High byte of the colour-RAM row pointer zpa_ED. The bytes after it, $EF-$F6, are not used by the game."
  },
  {
   "address": 247,
   "type": "line",
   "text": "0 while the title screen is up, 1 during a game. start_life shows the attract screen instead of starting play when it is 0. Set by game_start_fanfare, cleared by game_over_reset."
  },
  {
   "address": 512,
   "type": "line",
   "text": "Toggle counter for the flashing 'X2' text; its low bit chooses between 'X2' and blanks."
  },
  {
   "address": 513,
   "type": "line",
   "text": "Number of black cats MINUS ONE, from round_to_cat_count_minus1: 7 (8 cats) normally, 15 (16 cats) in a SPEED RUN."
  },
  {
   "address": 514,
   "type": "line",
   "text": "Colour used by fill_rect."
  },
  {
   "address": 515,
   "type": "line",
   "text": "Cheese eaten this life (reset at the start of every life). The next slice is worth (slices_eaten+1) x 100 points, shown as NEXT MEAL; the tenth is worth 1,000."
  },
  {
   "address": 516,
   "type": "line",
   "text": "Ticks per unit of TIME lost: $46 (70) normally, $23 (35) in a SPEED RUN."
  },
  {
   "address": 517,
   "type": "line",
   "text": "Counts down to the next unit of TIME lost; reloaded from time_drain_interval."
  },
  {
   "address": 518,
   "type": "line",
   "text": "Low-time warning: set to 3 when TIME reaches 12, giving four two-tone beeps; $FF when idle."
  },
  {
   "address": 519,
   "type": "line",
   "text": "Low-time warning beat: a beep starts when it reaches 0 (reload 24) and stops when it reaches 5."
  },
  {
   "address": 520,
   "type": "line",
   "text": "Counts 40 ticks between checks of round_timer in timeout_handler."
  },
  {
   "address": 521,
   "type": "line",
   "text": "Ticks until the next note of the game-start fanfare (6 per note)."
  },
  {
   "address": 522,
   "type": "line",
   "text": "Cheese-eaten sound: set to 3 per slice, counts down through tune_cheese_eaten one note per 4 ticks; $FF when idle."
  },
  {
   "address": 523,
   "type": "line",
   "text": "Background music tempo: 5 ticks per note."
  },
  {
   "address": 524,
   "type": "line",
   "text": "Background music phrase counter, 4 down to 1: counts 4, 3 and 2 play music_phrase_a, count 1 plays music_phrase_b."
  },
  {
   "address": 525,
   "type": "line",
   "text": "Background music position within the current 16-note phrase, counting 15 down to 0."
  },
  {
   "address": 526,
   "type": "line",
   "text": "4-tick divider for the cheese-eaten sound on voice 3."
  },
  {
   "address": 527,
   "type": "line",
   "text": "2x cheese sound: set to 32 when it is eaten, counts down through tune_bonus_2x one note per tick; $FF when idle."
  },
  {
   "address": 528,
   "type": "line",
   "text": "SPEED RUN counter, printed as 'NO.n' during the SPEED RUN intro and incremented after it. 1 at game start. Incremented in binary but printed as one digit, so a tenth SPEED RUN would show the glyph after '9'."
  },
  {
   "address": 529,
   "type": "line",
   "text": "3-tick divider for the SPEED RUN intro animation."
  },
  {
   "address": 530,
   "type": "line",
   "text": "10-tick divider for the SPEED RUN intro tune."
  },
  {
   "address": 531,
   "type": "line",
   "text": "SPEED RUN intro: index into str_speed_run, counting down as the red rat runs across and the banner appears."
  },
  {
   "address": 532,
   "type": "line",
   "text": "SPEED RUN intro: position in tune_speed_run, counting down."
  },
  {
   "address": 533,
   "type": "line",
   "text": "Set to 1 at power-on so the first pass through start_life clears the screen and draws the HUD before the attract screen appears."
  },
  {
   "address": 534,
   "type": "line",
   "text": "Nonzero while the star-drop sound plays on voice 2; per_tick_sound_and_timers silences voice 2 and clears it when move_cycle_countdown reaches 3."
  },
  {
   "address": 535,
   "type": "line",
   "text": "Set when the score passes the high score, cleared at game over. Nothing reads it."
  },
  {
   "address": 536,
   "type": "line",
   "text": "Random number state, low byte ($0218/$0219 form a 16-bit shift register; see prng_next). Set to $11 at power-on; the high byte is never initialised by the game and holds whatever the machine left there. prng_next is called once per tick while the title screen waits for F1, so later cheese and cat layouts depend on how long the player waits."
  },
  {
   "address": 537,
   "type": "line",
   "text": "Random number state, high byte. See prng_lo. The bytes after it, up to $0258, are not used by the game."
  },
  {
   "address": 1074,
   "type": "line",
   "text": "Screen row 1, column 10: the ten cells of the TIME bar. tick_round_timer writes cell round_timer>>3 each time TIME drops."
  },
  {
   "address": 14336,
   "type": "line",
   "text": "CUSTOM CHARACTER SET at $3800 (the VIC-II is pointed here by $D018=$1E). The game draws glyphs $00-$7F. The 2KB block is loaded as one piece and never written at run time; everything from $3C00 up is not character artwork: $3C00-$3C7F holds the two radar sprite shapes, and $3C80-$3FFF is an identical copy of the engine's data tables at $FC80-$FFFF, which the code never reads here (it reads the $FCxx copy). The two copies differ in one byte, $3E01 versus $FE01, because red_rat_chase_axis is written at run time. Glyph $00 is empty: the floor cell of the maze."
  },
  {
   "address": 14344,
   "type": "line",
   "text": "Letters A-Z, codes $01-$1A, stored inverted: a solid cell with the letter punched out. The set pixels take the colour-RAM colour and the holes show the background, so HUD text reads as white letters on a blue panel."
  },
  {
   "address": 14552,
   "type": "line",
   "text": "Five glyphs in the OPPOSITE polarity - bright shape on a transparent cell - at codes $1B-$1F: S, P, L, ';' and '.'. Those are exactly the game's five keyboard controls (S = fire, P/./L/; = up/down/left/right), so this is the key-legend alphabet. Codes $1B-$1C ('S','P') double as letters in the banner alphabet below."
  },
  {
   "address": 14592,
   "type": "line",
   "text": "Code $20, the space of the inverted alphabet: a completely solid block. Inverted text needs a filled cell for a blank, which is why the whole screen is paved with $20 rather than left empty."
  },
  {
   "address": 14600,
   "type": "line",
   "text": "Six more bright-on-transparent letters at codes $21-$26: C, E, D, R, U, N. Together with $1B/$1C (S,P), $2B (O) and $3C-$3F (G,A,M,V) they form a second, partial alphabet holding exactly the letters needed for the two banner words stored at $3D2B and $3D37 - 'GAME OVER' and 'SPEED RUN'."
  },
  {
   "address": 14648,
   "type": "line",
   "text": "Inverted punctuation: apostrophe (code $27), '(' ($28) and ')' ($29). Used by the attract-screen strings \"PUSH'F1' TO RUN\" and \"(C) 1982 COMMODORE...\"."
  },
  {
   "address": 14672,
   "type": "line",
   "text": "Code $2A: a small four-pointed star. The viewport draws it in yellow for every cell beyond the edge of the maze, and move_player treats it as a wall along with $7F. A decorative border, not an object."
  },
  {
   "address": 14680,
   "type": "line",
   "text": "Code $2B: the letter O in bright-on-transparent polarity, part of the banner alphabet (the 'O' of GAME OVER)."
  },
  {
   "address": 14688,
   "type": "line",
   "text": "Inverted punctuation, codes $2C-$2F: comma, hyphen, full stop, slash. The hyphen is the one in 'HI-SCORE'."
  },
  {
   "address": 14720,
   "type": "line",
   "text": "Digits 0-9 at codes $30-$39, inverted like the letters. Screen codes for digits land here naturally, which is why the score, timer and round number can be poked straight into screen RAM as '0'+value."
  },
  {
   "address": 14800,
   "type": "line",
   "text": "Codes $3A and $3B: colon and semicolon, inverted. The colon is the one in the 'TIME : ' label."
  },
  {
   "address": 14816,
   "type": "line",
   "text": "Codes $3C-$3F: G, A, M and V in bright-on-transparent polarity - the last four letters the 'GAME OVER' banner needs."
  },
  {
   "address": 14848,
   "type": "line",
   "text": "THE RAT, in four facings, as four 2x2 tiles: $40-$43 up, $44-$47 right, $48-$4B down, $4C-$4F left. Each tile is stamped at screen offsets 0, 1, 40, 41. The bitmap is unmistakably a rodent - a round head with two ear lobes, a body, and a single-pixel tail trailing behind - but nothing in the pixels distinguishes a rat from a mouse, so the name follows the game's own text (MOVE RAT, BONUS RAT) rather than the c64-wiki, which says mouse. IMPORTANT: this is the ONLY rodent artwork in the entire character set. There is no second set for the enemies, which is direct evidence that the blue player rat and the red follower rats are the same glyphs drawn in different colour-RAM values. The gameplay snapshot confirms the player half: the $40-$43 tile sits in the maze with colour 6 (blue) while the surrounding walls are colour $0C."
  },
  {
   "address": 14976,
   "type": "line",
   "text": "Cheese tile, codes $50-$53. $50, $51 and $52 are the wedge, drawn with $00 in the bottom-right cell for an ordinary cheese. $53 is a small red '2x' that draw_2x_marker puts in that corner for the special cheese (meal slot 0)."
  },
  {
   "address": 15008,
   "type": "line",
   "text": "Star tile, codes $54-$57: a scatter of small bursts, the player's STAR SCREEN weapon, drawn in black by age_and_draw_stars."
  },
  {
   "address": 15040,
   "type": "line",
   "text": "The black cat, a 2x2 tile ($58-$5B). The bitmap supports the identification: two pointed triangular ears at the top (a rat's are round), a pair of eye notches below them, a narrow neck, then a wide seated body with a tail curling out to the lower left. A cat seen head-on."
  },
  {
   "address": 15072,
   "type": "line",
   "text": "The 'EEEK' tile ($5C-$5F), drawn when the player is caught. The middle five pixel rows literally spell E, E, E, K in 3-pixel-wide letters, framed above and below by little burst marks - a comic-book shout."
  },
  {
   "address": 15104,
   "type": "line",
   "text": "The four radar blips, codes $60-$63. These are NOT a 2x2 tile: each is an independent cell that is solid except for one 4x4 pixel hole, placed in a different corner - $60 top-left, $61 top-right, $62 bottom-left, $63 bottom-right. The radar panel is paved with solid blocks and a blip is a 4x4 hole showing through, so the radar gets twice the resolution of the character grid: each cell can mark a contact in any of its four quadrants. In the gameplay snapshot these codes appear only inside the radar window (screen rows 8-21, columns 23-31) and nowhere in the maze."
  },
  {
   "address": 15136,
   "type": "line",
   "text": "The spare-life icon ($64-$67): a pixel-for-pixel INVERTED copy of the rat-facing-up tile at $40-$43. Inverting it lets the same artwork be shown as a dark silhouette on the coloured status panel instead of a bright sprite on the black maze. In the snapshot one of these sits at screen rows 13-14, columns 32-33 in blue."
  },
  {
   "address": 15168,
   "type": "line",
   "text": "Codes $68-$76 are all-zero glyphs - fifteen interchangeable blank cells. Code $68 in particular is used as a filler value in the tables further up this block."
  },
  {
   "address": 15288,
   "type": "line",
   "text": "TIME bar glyphs $77-$7F. Each has a solid top and bottom row. $77 has no fill between them (time remaining); $78 is filled except for its leftmost column, and each code after that has one column less, down to $7E with only the rightmost column. Drawn in black on the white background, so a cell empties of white from the right as TIME drops. $7F is fully solid and doubles as the maze wall; tick_round_timer writes $20 (also solid) for a fully used cell."
  },
  {
   "address": 15360,
   "type": "line",
   "text": "Hardware sprite data, not glyphs. $3C00 (sprite pointer $F0): a solid 4x4 square in the top-left corner, the player's radar dot. $3C40 (pointer $F1): a 4x4 'X', the red rats' radar dots. The rest of each 63-byte sprite block is empty."
  },
  {
   "address": 15440,
   "type": "line",
   "text": "Empty remainder of the second sprite block, up to $3C7F."
  },
  {
   "address": 15488,
   "type": "line",
   "text": "Start of the copy of the engine tables: $3C80-$3FFF matches $FC80-$FFFF byte for byte (see viewport_row_lo and following). The code never reads this copy."
  },
  {
   "address": 15506,
   "type": "line",
   "text": "Copy of viewport_row_hi ($FC92); not read."
  },
  {
   "address": 15524,
   "type": "line",
   "text": "Copy of viewport_colour_row_hi ($FCA4); not read."
  },
  {
   "address": 15542,
   "type": "line",
   "text": "Copy of radar_row_addr_lo ($FCB6); not read."
  },
  {
   "address": 15556,
   "type": "line",
   "text": "Copy of radar_row_addr_hi ($FCC4); not read."
  },
  {
   "address": 15570,
   "type": "line",
   "text": "Copy of bit_select_table ($FCD2); not read."
  },
  {
   "address": 15578,
   "type": "line",
   "text": "Copy of str_hi_score ($FCDA); not read."
  },
  {
   "address": 15586,
   "type": "line",
   "text": "Copy of str_score ($FCE2); not read."
  },
  {
   "address": 15594,
   "type": "line",
   "text": "Copy of str_time_bar ($FCEA), 'TIME : ' plus the full bar; not read."
  },
  {
   "address": 15601,
   "type": "line",
   "text": "Copy of the bar part of str_time_bar ($FCF1); not read."
  },
  {
   "address": 15611,
   "type": "line",
   "text": "Copy of str_copyright ($FCFB); not read."
  },
  {
   "address": 15646,
   "type": "line",
   "text": "Copy of str_next_meal and str_round ($FD1E, $FD26); not read."
  },
  {
   "address": 15659,
   "type": "line",
   "text": "Copy of str_game_over ($FD2B); not read."
  },
  {
   "address": 15671,
   "type": "line",
   "text": "Copy of the letters of str_speed_run ($FD37); not read."
  },
  {
   "address": 15685,
   "type": "line",
   "text": "Copy of the end of str_speed_run and of str_no ($FD45-$FD49, 'NO.'); not read."
  },
  {
   "address": 15690,
   "type": "line",
   "text": "Copy of stamp_offsets_4x2 ($FD4A); not read."
  },
  {
   "address": 15698,
   "type": "line",
   "text": "Copy of str_push and str_f1_to_run ($FD52, $FD56), two separate strings; not read."
  },
  {
   "address": 15715,
   "type": "line",
   "text": "Copy of the end of str_bonus_rat ($FD63); not read."
  },
  {
   "address": 15727,
   "type": "line",
   "text": "Copy of str_for_20000_pts ($FD6F); not read."
  },
  {
   "address": 15740,
   "type": "line",
   "text": "Copy of str_version ($FD7C), 'COMMODORE V.02'; not read."
  },
  {
   "address": 15754,
   "type": "line",
   "text": "Copy of str_star_screen ($FD8A); not read."
  },
  {
   "address": 15765,
   "type": "line",
   "text": "Copy of str_move_rat ($FD95); not read."
  },
  {
   "address": 15776,
   "type": "line",
   "text": "Copy of stamp_offsets_legend and stamp_offsets_2x2 ($FDA0-$FDAE); not read."
  },
  {
   "address": 15791,
   "type": "line",
   "text": "Copy of the rat and EEEK tile code lists ($FDAF-$FDC2); not read."
  },
  {
   "address": 15811,
   "type": "line",
   "text": "Copy of probe_ptr_lo/probe_ptr_hi ($FDC3); not read."
  },
  {
   "address": 15819,
   "type": "line",
   "text": "Copy of red_rat_glyph_source ($FDCB); not read."
  },
  {
   "address": 15851,
   "type": "line",
   "text": "Copy of dir_dx_table/dir_dy_table ($FDEB); not read."
  },
  {
   "address": 15859,
   "type": "line",
   "text": "Copy of red_rat_spawn_x/red_rat_spawn_y ($FDF3); not read."
  },
  {
   "address": 15872,
   "type": "line",
   "text": "Copy of $FE00-$FEDA: the end of red_rat_spawn_y, red_rat_chase_axis (here with its load-time value), the two cat templates, their pointer tables and all the tune tables; not read."
  },
  {
   "address": 16091,
   "type": "line",
   "text": "Copy of round_to_red_rat_count_minus1, round_to_red_rat_move_ticks and round_to_cat_count_minus1 ($FEDB-$FF07); not read."
  },
  {
   "address": 16136,
   "type": "line",
   "text": "Copy of round_is_speed_run and round_to_paramset ($FF08-$FF25); not read."
  },
  {
   "address": 16166,
   "type": "line",
   "text": "Copy of the $FF/$00 filler at $FF26-$FFF9. The filler holds two odd bytes, $08 at $FF7D and $F1 at $FF7F, whose origin is not known; nothing reads them."
  },
  {
   "address": 16378,
   "type": "line",
   "text": "Copy of the CPU vectors at $FFFA-$FFFF: NMI $EE21 (an RTI), RESET $E037 (cold_start), IRQ $EE10 (irq_tick). The $FFFA copy is the one the CPU uses."
  },
  {
   "address": 32681,
   "type": "line",
   "text": "Not a real reference. At $E59B the viewport renderer uses the BIT-skip idiom: 'lda #$00' followed by the bytes $2C $A9 $7F, which read as 'bit $7FA9' when falling through (skipping the load) but as 'lda #$7F' when branched into at $E59C. The disassembler shows the operand as an address and so mints a symbol here. The game never touches $7FA9."
  },
  {
   "address": 57344,
   "type": "line",
   "text": "30 values copied into VIC-II registers $D011-$D02E by cold_start: text mode, 25 rows, screen on ($D011=$1B); all eight sprites enabled ($D015=$FF); character set at $3800 with screen at $0400 ($D018=$1E); border blue ($D020=6), background grey ($D021=$0C, replaced by white once the attract screen or a SPEED RUN intro runs); sprite 0 colour cyan (3), sprites 1-7 purple (4)."
  },
  {
   "address": 57374,
   "type": "line",
   "text": "25 values copied into SID registers $D400-$D418 by cold_start. All three voices: frequency 0, pulse width $0800 (square wave), control $41 = pulse waveform with the gate ON, attack/decay 0, sustain 14, release 0. Volume 0. These are written once and never again: from here on every sound in the game is produced by changing only the frequency registers, with frequency 0 as silence, and game_start_fanfare turns the volume up to 15."
  },
  {
   "address": 57399,
   "type": "line",
   "text": "Power-on entry: the RAM reset vector at $FFFC points here (the ROMs are banked out). Resets the stack, loads the VIC-II and SID registers from vic_register_init and sid_register_init, disables all CIA1 interrupts, sets CIA1 port A as output and port B as input for keyboard and joystick scanning, and writes $E5 to the processor port: RAM at $A000-$BFFF and $E000-$FFFF with I/O visible. Programs CIA1 timer A with $411B (16,667 cycles, about 59 Hz on a PAL machine) and enables its interrupt; that interrupt is the game's only clock (irq_tick). Seeds prng_lo with $11 and continues at cold_start_game_state."
  },
  {
   "address": 57480,
   "type": "line",
   "text": "THE RED RATS. Called from the main loop each time red_rat_move_countdown expires: every 6 ticks, or every 5 from round 8. Erase / move / redraw: zeroes the eight red rat glyph tables and calls draw_red_rats_in_viewport, which stamps glyph $00 (empty floor) over every red rat; reloads the tables from red_rat_glyph_source; moves each red rat one half-cell; updates the radar sprites; and falls through into draw_red_rats_in_viewport to draw them again. Colour RAM gets 2 (red) for every red rat cell, while the player's tile is coloured 6 (blue): the same rat artwork in two colours."
  },
  {
   "address": 57506,
   "type": "line",
   "text": "Per-rat loop, X from red_rat_count_minus1 down to 0. A stunned red rat (red_rat_stun_timer nonzero) does not move: its facing is set to the timer's low two bits, so over successive moves it cycles through all four tiles and appears to spin, and the timer drops by one."
  },
  {
   "address": 57519,
   "type": "line",
   "text": "A red rat only chooses a direction when it is cell-aligned (red_rat_step_count even); halfway between cells it just keeps going."
  },
  {
   "address": 57527,
   "type": "line",
   "text": "The chase. red_rat_chase_direction suggests a direction toward the player on one axis. The suggestion is taken only if it differs from the current direction and red_rat_can_step says the cell that way is open (not a wall in the maze bitmap); otherwise the old direction is restored and the wall-following fallback at $E0F1 decides. The red rats have no knowledge of the maze beyond the single cell they are about to enter."
  },
  {
   "address": 57555,
   "type": "line",
   "text": "Turning costs a move: a red rat that changes direction does not step on that move. A reversal is animated with one intermediate frame, drawn a quarter-turn short of the new direction."
  },
  {
   "address": 57585,
   "type": "line",
   "text": "Wall-following fallback, used when there was no usable suggestion. If the cell ahead is open, step. Otherwise turn right if that cell is open; otherwise turn left without checking. A red rat that meets a wall therefore prefers to turn right, and in a dead end it takes a couple of moves to get turned round."
  },
  {
   "address": 57624,
   "type": "line",
   "text": "The step: one half-cell in red_rat_dir (0 decrements Y, 1 increments X, 2 increments Y, 3 decrements X), then red_rat_step_count+1. The clamps that follow keep X within 0-63 and Y within 0-111; the maze border normally makes them unnecessary. The CLV/BVC pairs are an unconditional branch."
  },
  {
   "address": 57677,
   "type": "line",
   "text": "Set the drawn facing from the direction and run red_rat_hit_test, which stuns this red rat if it has landed on a star, a black cat or another red rat. Stunned red rats skip this."
  },
  {
   "address": 57690,
   "type": "line",
   "text": "All red rats moved: reposition their radar sprites (radar_sprites_red_rats), then fall through to draw_red_rats_in_viewport to redraw them with the reloaded glyph tables."
  },
  {
   "address": 57693,
   "type": "line",
   "text": "Draws every red rat into the maze viewport (screen rows 3-20, columns 3-20) in colour 2, red. For each red rat, viewport_ptr_from_world_xy turns its position into the screen address of its 2x2 tile relative to the player; red rats outside the window are skipped. A red rat fully inside is drawn with all four quadrants from the red rat glyph tables, indexed by red_rat_facing. A red rat half outside (one column past the left or right edge, or one row past the top or bottom) is drawn with just its visible half. When a red rat is clipped on both axes at once the left/right branches do not check the top-row clip, so one quadrant can land a row low or be missed; this only affects a red rat sitting on a corner of the window. Also used, with the glyph tables zeroed, to erase the red rats."
  },
  {
   "address": 57868,
   "type": "line",
   "text": "Can red rat X step one whole cell in red_rat_dir? Adds dir_dx_table/dir_dy_table (+-2 half-cells) to its position, rejects anything outside the 64x112 half-cell world, and tests that cell's bit in the maze bitmap via maze_bitmap_ptr_from_world_xy and bit_select_table. Returns Z set when the cell is open, Z clear for a wall or out of bounds. The red rats consult the bitmap directly; the player's movement reads the rendered screen instead (move_player)."
  },
  {
   "address": 57916,
   "type": "line",
   "text": "Suggests a direction for red rat X toward the player, in chase_suggestion ($FF = none). Each red rat works on one axis at a time, chosen by its byte in red_rat_chase_axis: 0 closes the horizontal gap (right if the red rat's X is less than player_x, left if greater), nonzero closes the vertical gap (down or up). When the red rat is level with the player on its axis, the latch flips and the other axis is used. The result is a staircase pursuit. No randomness."
  },
  {
   "address": 57983,
   "type": "line",
   "text": "Turns a world position (zpa_86 = X, zpa_87 = Y, in half-cells) into the address of the maze bitmap byte holding that cell, in zpp_82/zpa_83: row (Y>>1) x 4 bytes, plus X>>4 because each byte packs 8 cells. The caller selects the bit with (X>>1) AND 7. Used by red_rat_can_step and place_meal_items."
  },
  {
   "address": 58020,
   "type": "line",
   "text": "Stun test for red rat X, exact-position matches only. (1) Every active black cat (cat_x_table/cat_y_table): stun 7. (2) Every live star (star_x_queue/star_y_queue): stun 15. (3) Every other red rat: stun 7. Writes red_rat_stun_timer; nothing else changes. Stars and cats slow the red rats down; they never remove them."
  },
  {
   "address": 58103,
   "type": "line",
   "text": "Draws every cheese not yet eaten as a blip on the radar panel (8x14 characters at screen rows 8-21, columns 23-30; one character covers 4x4 maze cells). The blip glyph $60-$63 is a solid block with a 4x4 hole in one corner: bit 2 of the item's Y chooses top or bottom, bit 2 of X left or right, so each blip shows which quarter of its radar cell the cheese is in. Slot 0 (the 2x cheese) is skipped once it has been eaten. Called once when a life starts; eaten cheese is then rubbed out individually by clear_meal_blip_on_radar."
  },
  {
   "address": 58153,
   "type": "line",
   "text": "Turns a world position (zpa_89 = X, zpa_8A = Y) into a screen address inside the radar panel, in zpa_86/zpa_87: row Y>>3 via radar_row_addr_lo/hi, column X>>3. One radar character per 8x8 half-cells."
  },
  {
   "address": 58184,
   "type": "line",
   "text": "Rubs the eaten cheese's blip off the radar: writes $20 (a solid, blip-free block) at the radar cell of meal slot eaten_slot. place_meal_items never puts two cheeses in the same radar cell, so this cannot erase another cheese's blip. The cheese disappears from the maze by itself, because the viewport is redrawn from the meal tables on every move. Called from check_meal_eaten."
  },
  {
   "address": 58206,
   "type": "line",
   "text": "Positions hardware sprite 0, the player's dot on the radar: X register = (player_x AND $FC) + $D0, Y = (player_y AND $FC) + $72, with the X overflow into $D010. Those offsets put world (0,0) at the top-left pixel of the radar panel (column 23, row 8) at one pixel per half-cell, snapped to 4 pixels. The sprite pointer is $F0, i.e. shape data at $3C00: a solid 4x4 square, coloured cyan. The radar's moving dots are sprites and its cheese blips are characters. Reached from the end of per_tick_sound_and_timers, once per tick."
  },
  {
   "address": 58252,
   "type": "line",
   "text": "Positions hardware sprites 1 to red_rat_count_minus1+1 as the red rats' dots on the radar, with the same mapping as radar_sprite_player, and enables exactly that many sprites plus sprite 0 via sprite_enable_for_count. Pointer $F1 = shape data at $3C40: a 4x4 'X', coloured purple. The table order means sprite n+1 always follows red rat n."
  },
  {
   "address": 58316,
   "type": "line",
   "text": "OR masks for sprites 1-7 in $D010 (the sprite X high-bit register), indexed by red rat number."
  },
  {
   "address": 58323,
   "type": "line",
   "text": "AND masks for sprites 1-7 in $D010, indexed by red rat number."
  },
  {
   "address": 58330,
   "type": "line",
   "text": "$D015 values indexed by red_rat_count_minus1: sprite 0 plus sprites 1..count, e.g. $0F for three red rats."
  },
  {
   "address": 58337,
   "type": "line",
   "text": "THE MAZE VIEWPORT, redrawn on every player move. Paints a 9x9-cell window of the current maze bitmap, centred on the player, into screen rows 3-20, columns 3-20, each cell as a 2x2 block of characters: $7F (solid) in grey for a wall, $00 (empty, showing the white background) for floor, and $2A (a small star glyph) in yellow for anything beyond the edge of the maze. The view scrolls one character (half a cell) at a time; odd positions draw half-cells at the edges. Then draws the cats, the cheese and the 2x marker on top (from $E5E0), and the red rats if they are waiting or frozen. This first part works out the starting bitmap row, (player_y>>1)-4; rows above the maze are handled later as border."
  },
  {
   "address": 58399,
   "type": "line",
   "text": "Second half of draw_maze_viewport (renamed from 'redraw_radar_terrain_near_rat' -- it draws the playfield, not the radar; the radar is the separate 8x14 panel at rows 8-21 / cols 23-30). Horizontal offset: the starting cell is (rat_X>>1)-4 and the byte holding it is cell>>3, because 8 cells are packed per byte; that byte offset is added to the maze_bitmap pointer. It then aims four fixed destination pointers at the top-left of the playfield window -- screen $047B (row 3, col 3) and $04A3 (row 4, col 3) plus their colour-RAM twins $D87B/$D8A3 -- and runs 9 passes of {maze_viewport_draw_cell_row, maze_viewport_next_row}. Each pass paints two screen rows and 18 columns, so 9 passes cover rows 3-20 x cols 3-20 exactly. THE VIEW SCROLLS ONE CHARACTER AT A TIME, i.e. half a maze cell, and the two tests at $E468 (is rat_Y odd?) and $E46D (is rat_X odd?) choose between three paths for that: both even = the clean path here; odd Y = $E48C, which paints a half-height tile row at the top, then 8 full rows, then pulls the second destination pointer back one screen row at $E4D8 and paints a final half row at the bottom; odd X = maze_viewport_rows_halfcell_x. VERIFIED against the gameplay snapshot: screen rows 3-20 / cols 3-20 reproduce maze_bitmap rows 35-43, cells 11-19, character for character, with the rat's own 2x2 tile at the dead centre (rows 11-12, cols 11-12)."
  },
  {
   "address": 58612,
   "type": "line",
   "text": "The horizontally half-shifted variant of draw_maze_viewport's row loop, used when the rat's world X is odd -- i.e. when the view sits half a maze cell (one character) off the tile grid. Each of the 9 row passes is drawn in three pieces instead of one: first a 2-column sliver (zpa_A6=$02), the right-hand half of the cell hanging off the left edge; then, after skipping 8 cells ahead ($E503-$E508), another sliver at columns 16-17 for the right edge; then the 8 whole cells in between, re-entered at maze_viewport_draw_span with X=1 so they land one character to the right ($E511-$E528, including the 'dec zpa_8B' fix-up for when the cell index crosses a byte boundary backwards). For the player this is what makes the maze slide smoothly in single-character steps rather than jumping a whole 2x2 tile at a time."
  },
  {
   "address": 58679,
   "type": "line",
   "text": "Advances draw_maze_viewport's pointers from one tile row to the next: the maze_bitmap source pointer by 4 (4 bytes = 32 packed cells = one whole bitmap row -- this is NOT column subsampling, as an earlier reading of this routine guessed), and all four destinations (2 screen + 2 colour) by $50 = 80 = two screen rows, because every pass paints a tile two characters tall."
  },
  {
   "address": 58735,
   "type": "line",
   "text": "Unpacks one row of 9 maze cells from the bitmap into two screen rows. For each cell it tests bit (cell AND 7) of the bitmap byte: set gives $7F, clear gives $00 (the 'bit $7FA9' at $E59B is the skip idiom that selects between them). A cell index of 32 or more gives $2A border. Colour $0C (grey) for maze cells, 7 (yellow) for border. Rows outside the maze's 56 fill all 18 columns with yellow border at $E5CE."
  },
  {
   "address": 58747,
   "type": "line",
   "text": "Resumable inner span of maze_viewport_draw_cell_row: everything except the 'start at the left edge' setup. Entered directly at $E50E and $E528 with X preloaded (the first destination column) and zpa_A6 preloaded (the stop column), which is how maze_viewport_rows_halfcell_x draws partial tiles at the left and right edges when the view is offset by one character. X advances by 2 per cell because each cell is 2 characters wide, and zpa_8B (the bitmap byte index) steps every 8 cells. $E5CE is the off-the-map filler: 18 columns of $2a border in colour $07."
  },
  {
   "address": 58848,
   "type": "line",
   "text": "Draws the black cats (active entries of cat_x_table/cat_y_table) into the viewport as the 2x2 tile $58-$5B in colour 0, black, clipping to the window edge the same way draw_red_rats_in_viewport does. Cats are only ever visible here: there is no cat on the radar, which is how they stay hidden until you come round the corner."
  },
  {
   "address": 58992,
   "type": "line",
   "text": "Draws every cheese not yet eaten into the viewport as the tile $50,$51 over $52,$00 in colour 7, yellow. Slot 0, the 2x cheese, is skipped once eaten."
  },
  {
   "address": 59140,
   "type": "line",
   "text": "If the last cheese drawn, slot 0, was in view and has not been eaten, overwrite its bottom-right cell with glyph $53 (a small '2x') in colour 2, red. That red corner is the only thing that distinguishes the 2x cheese. Then, while red_rat_move_countdown is 9 or more (the red rats are waiting at the start of a life, or frozen in a SPEED RUN), draw the red rats too, since move_all_red_rats will not be redrawing them."
  },
  {
   "address": 59192,
   "type": "line",
   "text": "For an object at X = zpa_8E, Y = A: column = X - player_x + 8 and row = Y - player_y + 8, which put the player's own tile at window column/row 8 (screen column 11, row 11). Valid range 0-17. A value of -1 is accepted as a clipped edge: the matching flag (zpa_84 for X, zpa_85 for Y) is set to $FF and the coordinate treated as 0. Returns Y=0 (Z set) with zpp_82 = screen address and zpp_90 = colour-RAM address of the tile's top-left, from viewport_row_lo/hi, or Y=$FF (Z clear) when the object is out of view. Column and row 17 are left to callers to clip (only the left half, or top half, is on screen)."
  },
  {
   "address": 59276,
   "type": "line",
   "text": "THE PLAYER, once per move cycle. Halfway between cells it simply steps on in player_dir. At a cell boundary it reads the controls: a requested direction is taken if the screen cell that way (read_screen_in_direction) is not a wall ($7F) or border ($2A); any turn replaces this move's step, and a reversal is also drawn with one intermediate facing. With no usable request it steps ahead if open, otherwise turns right if that is open, otherwise turns left. The player never stops: the joystick only chooses between openings. Then redraws the viewport, checks for cheese under the rat, recolours and draws the rat, and continues into star_screen_update."
  },
  {
   "address": 59392,
   "type": "line",
   "text": "Step one half-cell in player_dir and count it in player_step_count. The movement test above read the rendered screen, not the maze bitmap; the two agree because the screen is painted from the bitmap."
  },
  {
   "address": 59425,
   "type": "line",
   "text": "Redraw the viewport. Then, if the player is cell-aligned, look at two cells of the rat's own 2x2 position ($05C3+1 and +40) in what was just drawn: a code $50-$54 there means a cheese tile is under the rat, so check_meal_eaten is called. Then colour the rat's four cells blue and draw its tile for player_facing at $05C3 (screen row 11, column 11)."
  },
  {
   "address": 59509,
   "type": "line",
   "text": "Returns the screen character one step beyond the player's 2x2 tile in direction X: above ($059B), right ($05C5), below ($0613) or left ($05C2), from probe_ptr_lo/hi. Because the viewport keeps the player at a fixed screen position, these four addresses never change. Callers treat $7F and $2A as blocked and anything else as open."
  },
  {
   "address": 59524,
   "type": "line",
   "text": "The four draw_rat_facing_* routines each stamp the player's 2x2 tile through zpp_82 using the screen offsets 0, 1, 40, 41 (stamp_offsets_2x2) and four character codes: $40-$43 up, $44-$47 right, $48-$4B down, $4C-$4F left (rat_up_codes etc.). The player is character graphics, like the rest of the cast."
  },
  {
   "address": 59538,
   "type": "line",
   "text": "Stamps the player tile facing right, codes $44-$47. See draw_rat_facing_up."
  },
  {
   "address": 59552,
   "type": "line",
   "text": "Stamps the player tile facing down, codes $48-$4B. See draw_rat_facing_up."
  },
  {
   "address": 59566,
   "type": "line",
   "text": "Stamps the player tile facing left, codes $4C-$4F. See draw_rat_facing_up."
  },
  {
   "address": 59580,
   "type": "line",
   "text": "Stamps the 'EEEK' tile, codes $5C-$5F, over the player when caught. Called from player_caught_sequence."
  },
  {
   "address": 59594,
   "type": "line",
   "text": "Writes colour 6 (blue) to the colour RAM of the player's four cells ($D9C3, $D9C4, $D9EB, $D9EC)."
  },
  {
   "address": 59609,
   "type": "line",
   "text": "STAR SCREEN, once per move cycle, straight after move_player. A star can be dropped only when the player is cell-aligned, did not just turn, is not in a SPEED RUN (move_cycle_interval 4), has TIME left, and the cell BEHIND it is not a wall or border. Then, if a burst is in progress, drop the next star; otherwise, if fire was pressed, start a burst of 3. The stars go down behind the player, one per cell, as a trail for the chasing red rats to run into. Always finishes by ageing and drawing the stars (age_and_draw_stars)."
  },
  {
   "address": 59664,
   "type": "line",
   "text": "Drops one star: costs one unit of TIME (tick_round_timer), shifts the star queue up a slot, puts the new star in slot 0 one cell behind the player (player position plus the dir_dx/dir_dy step for the reverse direction), with a life of 50 move cycles, and starts the star sound on voice 2."
  },
  {
   "address": 59742,
   "type": "line",
   "text": "Takes one off every live star's life; when the oldest reaches 0 it drops off the end of the queue. Then draws each live star into the viewport as the tile $54-$57 in colour 0, black, clipped at the window edges. Runs once per move cycle, so star lifetimes are measured in player moves, not ticks."
  },
  {
   "address": 59806,
   "type": "line",
   "text": "Star tile variants for stars clipped at the right, top or bottom edge of the viewport, and the unclipped case. See age_and_draw_stars."
  },
  {
   "address": 59906,
   "type": "line",
   "text": "Called once per tick from the main loop. In order: flashes 'X2' beside NEXT MEAL (screen row 10, columns 37-38) every 20 ticks after the 2x cheese is eaten; advances the background music on voice 1 (music_tick); plays the cheese-eaten notes and the 2x-cheese arpeggio on voice 3; cuts the star sound on voice 2; plays the low-time beeps on voices 2 and 3; runs timeout_handler; and finishes by positioning the player's radar sprite."
  },
  {
   "address": 59947,
   "type": "line",
   "text": "THREE BLIND MICE, the background music on voice 1. One note per 5 ticks. Each 16-note phrase is read backwards, index 15 down to 0. music_phrase_count runs 4, 3, 2, 1: the first three passes play music_phrase_a, the fourth plays music_phrase_b (the carry from 'cmp #$02' tells music_pick_note which). 4 phrases x 16 notes x 5 ticks = 320 ticks, about 5.4 seconds per loop at the PAL tick rate. Only the frequency is written; with the gate left on, two consecutive entries at the same pitch sound as one longer note, and a 0 is a rest."
  },
  {
   "address": 59953,
   "type": "line",
   "text": "Not an entry point. This address is the operand byte of 'lda #$05' at $EA30. It carries a label because $EA31 is the C64 KERNAL's standard IRQ handler address, and that value is still sitting in the RAM vector at $0314/$0315. The game never uses that vector: with the ROMs banked out the CPU takes interrupts through $FFFE/$FFFF, which point at irq_tick ($EE10)."
  },
  {
   "address": 59996,
   "type": "line",
   "text": "Voice 3 effects. Every 4 ticks, the cheese-eaten sound steps backwards through tune_cheese_eaten (three falling notes, then silence). Every tick, the 2x-cheese sound steps backwards through tune_bonus_2x, a fast repeated arpeggio lasting 33 ticks. Also entered here from round_complete_jingle, which lets these finish while it waits."
  },
  {
   "address": 60034,
   "type": "line",
   "text": "Star sound cut-off: when star_sound_gate is set and move_cycle_countdown reaches 3, silence voice 2."
  },
  {
   "address": 60052,
   "type": "line",
   "text": "Low-time warning, armed by tick_round_timer when TIME reaches 12: four two-tone beeps (voice 2 $1C00 with voice 3 $2A00), each about 19 ticks on and 5 off."
  },
  {
   "address": 60096,
   "type": "line",
   "text": "Every 40 ticks, if round_timer is 0: if the red rats are frozen (a SPEED RUN), release them by setting red_rat_move_countdown to 1; and add 1 to move_cycle_interval, up to 18, so the player gets slower and slower. Running out of TIME never costs a life by itself. Ends by jumping to radar_sprite_player."
  },
  {
   "address": 60132,
   "type": "line",
   "text": "All ten cheeses eaten. Waits 20 ticks while the voice 3 effects finish, silences all voices, plays tune_round_complete on voice 3 (seven notes, 12 ticks each, the last held for 36), pauses 12 ticks, then pays the time bonus (time_bonus)."
  },
  {
   "address": 60212,
   "type": "line",
   "text": "SPEED RUN announcement, played before rounds 3, 7, 11 and 15 (round_is_speed_run). The background turns yellow and the viewport is filled with empty cells in red. One red rat is placed at the right-hand end of window rows 5-6 and runs left one character every 3 ticks; as it goes, the banner str_speed_run is written into the row behind it one character at a time, so 'SPEED  RUN' appears in its wake on screen row 9 while its trail on row 8 is wiped. When the banner is complete, 'NO.' and the SPEED RUN number are printed on row 11. Meanwhile tune_speed_run plays on voice 1, one note per 10 ticks. Finally speed_run_number is incremented and the background set back to white. start_life then clears the screen and the SPEED RUN round begins."
  },
  {
   "address": 60290,
   "type": "line",
   "text": "Copy the next banner character into row 9 just behind the running red rat, and write into row 8 above it an empty cell, or a solid block for the banner's last two entries ($20)."
  },
  {
   "address": 60324,
   "type": "line",
   "text": "Prints the low digit of speed_run_number at screen row 11, column 13, right after 'NO.'."
  },
  {
   "address": 60334,
   "type": "line",
   "text": "Every 10 ticks, play the next note of tune_speed_run on voice 1; when the tune is finished, end the intro."
  },
  {
   "address": 60367,
   "type": "line",
   "text": "F1 was pressed on the title screen. Silences all voices, sets the SID volume to 15, and plays tune_game_start on voice 1: 47 steps of 6 ticks each (about 4.8 seconds), the opening of Three Blind Mice. Partway through, the screen is cleared and the first life is set up (clear_screen_and_draw_hud). Then sets game_in_progress and starts play at play_life."
  },
  {
   "address": 60426,
   "type": "line",
   "text": "Starts every life. Clears the whole screen to $20 (a solid block in this font) in colour 6, so the screen is a blue field; screen pages $07 down to $04 and colour pages $DB down to $D8 are cleared together (one cell, $0700, is skipped by the loop but lies inside the maze window, which is redrawn anyway). Then writes the HUD text: HI-SCORE, SCORE, 'TIME : ' with the full bar (bar colour black), the copyright line, NEXT over MEAL, '00' under them, and ROUND. Falls through into print_round_and_start_life."
  },
  {
   "address": 60551,
   "type": "line",
   "text": "Prints round_number_bcd under ROUND (screen row 19, columns 35-36, leading zero suppressed), clears the radar panel to solid black cells, and resets everything that belongs to a life: all eight red rat slots from red_rat_spawn_x/y with direction, facing, step count and stun cleared; the player at ($1E,$64) facing up; the viewport, rat and red rats drawn; music and effect timers restarted; round_timer 80; red_rat_move_countdown 79, or $FF (frozen) in a SPEED RUN; no stars, no pending sounds, slices_eaten 0, score_doubler off. Then prints the score, the high score, the spare-rat icons, the cheese blips on the radar and the NEXT MEAL value. Cheese already eaten this round stays eaten."
  },
  {
   "address": 60753,
   "type": "line",
   "text": "Fills the maze viewport (18x18 cells from screen row 3, column 3) with $20 in colour 0: a solid black window, used as the backdrop for the attract screen text. Enter at fill_maze_window_colour with a colour in A and a character already in zpa_8D."
  },
  {
   "address": 60759,
   "type": "line",
   "text": "Fills the maze viewport with character zpa_8D in colour A. The SPEED RUN intro uses it to paint the window with empty cells in red."
  },
  {
   "address": 60780,
   "type": "line",
   "text": "Fills a rectangle: zpa_8D is the character, fill_colour the colour, zpp_82/zpp_90 the top-left screen and colour addresses, zpa_88 the width minus one and X the height minus one. Also used directly to clear the radar panel."
  },
  {
   "address": 60813,
   "type": "line",
   "text": "Reads the controls into joystick_dir ($FF = none) and fire_pressed. Joystick in port 1 first ($DC01 bits 0-4, read twice until stable): up, down, left and right give 0, 2, 3 and 1, a later bit overriding an earlier one, and bit 4 is fire. Only when the joystick is completely idle does it scan the keyboard: P = up, '.' = down, L = left (all row 5), ';' = right (row 6), and S = fire (row 1). Called only at cell boundaries."
  },
  {
   "address": 60932,
   "type": "line",
   "text": "Keyboard rows to select on $DC00 for the four direction keys: row 5, 5, 5, 6."
  },
  {
   "address": 60936,
   "type": "line",
   "text": "Column bit for each direction key on $DC01: P, '.', L, ';'."
  },
  {
   "address": 60940,
   "type": "line",
   "text": "Direction produced by each key: P=0 up, '.'=2 down, L=3 left, ';'=1 right."
  },
  {
   "address": 60944,
   "type": "line",
   "text": "The interrupt handler: the RAM vector $FFFE/$FFFF points here. Saves A/X/Y, sets tick_flag to 1, reads $DC0D to acknowledge CIA1, restores and returns. That is all; every piece of per-frame work runs in the foreground loops that wait for tick_flag. The NMI vector ($FFFA) points at the RTI at $EE21, so RESTORE does nothing. A BRK would also arrive here."
  },
  {
   "address": 60962,
   "type": "line",
   "text": "Waits 80 ticks, about 1.35 seconds. Used for the pause before play, after being caught, and before the game over reset."
  },
  {
   "address": 60974,
   "type": "line",
   "text": "Random number: 11 rounds of shifting the 16-bit register prng_lo/prng_hi left, feeding back NOT(bit15 XOR bit1 XOR bit0), a sequence of 65,534 states. Then reduces the low byte modulo zpa_8D by repeated subtraction (always subtracting at least once, which only gives an exact modulus when zpa_8D divides 256) and doubles the result, returning an even number. Callers pass 32 or 56 to get an even half-cell coordinate, or 16 down to 9 when choosing cats."
  },
  {
   "address": 61015,
   "type": "line",
   "text": "Round setup, called from setup_round. Copies the 16-entry cat template for this round's parameter set into cat_x_table/cat_y_table. Normal rounds then delete 8 entries at random (each time removing one of the first 16, 15, ... 9 entries and closing the gap), leaving 8 cats in slots 0-7 in their template order. SPEED RUN rounds skip the deletion and keep all 16. Falls through into place_meal_items."
  },
  {
   "address": 61096,
   "type": "line",
   "text": "Places the round's ten cheeses, slots 9 down to 0. For each, draws a random even position (X from 32 cells, Y from 56) and rejects it if: the maze bitmap has a wall there; another cheese is already in the same radar cell; a black cat is on exactly that spot; or it shares a radar cell with one of the seven red rat spawn points. There is no retry limit. Runs at round setup, which for round 1 is before the title screen waits for F1."
  },
  {
   "address": 61118,
   "type": "line",
   "text": "Wall test: the candidate cell's bit in the maze bitmap, the same test red_rat_can_step uses."
  },
  {
   "address": 61139,
   "type": "line",
   "text": "Rejects the candidate if a cheese placed earlier (slots above this one) is in the same radar cell (coordinates >>3). This keeps every cheese as its own blip on the radar."
  },
  {
   "address": 61182,
   "type": "line",
   "text": "Rejects the candidate if it is exactly on any of the 16 slots of cat_x_table/cat_y_table: the active cats plus, in a normal round, the leftover entries in slots 8-15 that setup_cats shifted down but did not clear."
  },
  {
   "address": 61205,
   "type": "line",
   "text": "Rejects the candidate if it is in the same radar cell as any of the seven red rat spawn points in red_rat_spawn_x/red_rat_spawn_y, so cheese is never dropped where the red rats start."
  },
  {
   "address": 61246,
   "type": "line",
   "text": "Accepted: store the position in this slot and go on to the next."
  },
  {
   "address": 61261,
   "type": "line",
   "text": "Draws one spare-rat icon (glyphs $64/$65 over $66/$67, an inverted copy of the rat tile) for each life beyond the one in play, from screen row 13, column 32, two columns apart. Called when a life starts and when the bonus life is awarded."
  },
  {
   "address": 61306,
   "type": "line",
   "text": "The title screen, shown when start_life finds game_in_progress clear. Blacks out the maze viewport, sets the border blue and background white, and prints over the black window: PUSH (row 5), 'F1' TO RUN (row 7), BONUS RAT / FOR 20000 PTS (rows 9-10), COMMODORE V.02 with a banner-alphabet C before it (row 12), a line of hyphens (row 14), and a control legend: the keys P, L, ';' and '.' arranged as a cross in the bright key glyphs ($1C-$1F) above MOVE RAT, and S above STAR SCREEN. The rest of the screen still shows the HUD from the last game."
  },
  {
   "address": 61431,
   "type": "line",
   "text": "Title screen loop, once per tick: stir the random number generator (prng_next), then test F1 (keyboard row 0, column 4 on $DC01) and go to game_start_fanfare when it is down. Joystick fire in port 1 pulls the same $DC01 bit low, so it starts the game too. Every 10 ticks two colour-RAM cells on row 5 ($D8CC and $D8D3, columns 4 and 11, either side of PUSH) swap between red and purple, which flashes the prompt."
  },
  {
   "address": 61482,
   "type": "line",
   "text": "Adds the BCD amount in zpa_88 to the score (score_lo, carrying into score_mid and score_hi). Because the display appends a '0', an amount of $10 is 100 points. If score_mid is now exactly $20 (20,000-20,990 points) and bonus_life_latch is clear, awards the bonus life: lives+1, latch set, spare-rat icons redrawn. No single call adds more than 900 points, so the 20,000 band cannot be skipped. Falls through to print the score and update the high score."
  },
  {
   "address": 61532,
   "type": "line",
   "text": "Prints the score at screen $04E0 (row 5, from column 24): six digits from score_hi/mid/lo with leading zeros suppressed (the last digit always printed), plus a fixed trailing '0'. Positions that are suppressed are not blanked, so digits from a longer earlier score are only cleared by the full-screen clear at the start of a life. Then compares score with high score; if the score is higher it is copied to the high score, new_hiscore_flag is set and the high score is reprinted."
  },
  {
   "address": 61536,
   "type": "line",
   "text": "VERIFIED digit order (superseding the earlier 'not fully nailed down' note): the outer loop's Y increases by 2 per byte (each print_bcd_byte_2digits call increments Y twice, once per nibble), so LDA zpa_E7,Y with Y=0,2,4 reads bytes E7,E9,EB in that order. Digit positions (screen offset from the $04E0 pointer): pos0=hi(E7), pos1=lo(E7), pos2=hi(E9), pos3=lo(E9), pos4=hi(EB), pos5=lo(EB) -- with leading-zero suppression, so pos0-3 are blank/stale unless the score is large. CRITICAL extra detail: after the loop exits (Y=6), $F070-$F072 unconditionally writes a literal '0' character at pos6 ($04E6) regardless of suppression state -- always one trailing zero appended. Same applies to the hi-score loop (s_F093, pointer $0468, bytes E8,EA,EC, trailing zero at $046E). VERIFIED against the live 'HI-SCORE 20000' example: bytes E8=00,EA=20,EC=00 -> suppressed,suppressed,'2'(nonzero starts here),'0','0','0' + unconditional trailing '0' = '20000', exact match. This also explains the earlier confusing live score read ('100' shown while score bytes were all zero): pos4 ($04E4) held STALE leftover '1' from a previous round's larger score that was never cleared (suppressed positions are simply left untouched, not blanked), while pos5 ($04E5) got a fresh forced '0' (last real digit, CPY#$05 exception) and pos6 ($04E6) got the unconditional trailing '0' -- '1','0','0' was two different mechanisms coincidentally adjacent, not a live 3-digit score of 100."
  },
  {
   "address": 61587,
   "type": "line",
   "text": "Prints the high score at screen $0468 (row 2, from column 24) in the same format as the score."
  },
  {
   "address": 61614,
   "type": "line",
   "text": "Prints the two BCD digits of A through zpa_84/85 at offset Y, advancing Y by 2. X counts digits printed so far: a leading 0 is skipped (position left untouched) until a nonzero digit appears, except at position 5, the last, which is always printed."
  },
  {
   "address": 61625,
   "type": "line",
   "text": "Prints one BCD digit (A, 0-9) as a screen-code digit at offset Y unless it is a leading zero; advances Y. See print_bcd_byte_2digits."
  },
  {
   "address": 61642,
   "type": "line",
   "text": "The rat is on a cheese: find which. Searches meal slots meals_remaining down to 0 for the player's exact position. There is always a match, because this is only called when a cheese tile has just been drawn under the rat; a failed search would reach the BRK at $F0D6, which would return into the middle of the next instruction. On a match: slices_eaten+1, start the cheese sound, rub the blip off the radar. If it is slot 0, the 2x cheese: set bonus_cheese_eaten and score_doubler, start the 2x arpeggio and the flashing X2. Otherwise remove the slot from both tables and meals_remaining-1. Then score it."
  },
  {
   "address": 61728,
   "type": "line",
   "text": "Scores the slice just eaten: (slices_eaten) x 100 points, so 100, 200, 300 and so on, doubled while score_doubler is set. The tenth slice of a life would compute $A0, which is not BCD, so it is special-cased at score_tenth_slice."
  },
  {
   "address": 61751,
   "type": "line",
   "text": "Prints NEXT MEAL, the value of the next slice: (slices_eaten+1) x 100, drawn as one or two digits at screen row 10, columns 32-33, in front of the fixed '00' at columns 34-35."
  },
  {
   "address": 61776,
   "type": "line",
   "text": "The tenth slice of a life scores 1,000 points (two adds of 500), or 2,000 while score_doubler is set."
  },
  {
   "address": 61797,
   "type": "line",
   "text": "Takes one unit off round_timer (not below 0) and redraws the partly used cell of the TIME bar: cell round_timer>>3 gets glyph $77+(round_timer AND 7), or $20 when that is 0. Each bar cell therefore steps through eight fill levels, and the black fill grows from right to left as TIME runs out. When TIME reaches exactly 12 it arms low_time_warning. Called by the main loop every time_drain_interval ticks, by drop_star, and by time_bonus."
  },
  {
   "address": 61840,
   "type": "line",
   "text": "End-of-round time bonus. For every unit of TIME left: a blip on voice 3, one unit off the bar (tick_round_timer), and 6 ticks each adding $01 = 10 points, so 60 points per unit and up to 4,800 for a full bar. (The amount comes from A, which the waiting loop before this leaves at 1.) When TIME is empty, waits 80 ticks and returns to next_round."
  },
  {
   "address": 61892,
   "type": "line",
   "text": "Power-on setup, reached from cold_start. Copies red_rat_glyph_source into the zero-page red rat glyph tables; sets the high score to 20,000; marks the first screen clear as pending (cold_start_clear_pending); then falls into game_over_reset, so power-on and game over share one path. Round 1's cats and cheese are therefore placed before the title screen ever appears."
  },
  {
   "address": 61922,
   "type": "line",
   "text": "Resets a game: 3 lives, round 1 (round_number_bcd and round_index), speed_run_number 1, score zero, game_in_progress 0, bonus life available again, new_hiscore_flag clear. The high score is kept. Falls into setup_round, which sets up round 1 and then shows the title screen, since game_in_progress is 0."
  },
  {
   "address": 61949,
   "type": "line",
   "text": "Sets up the round given by round_index. round_to_paramset picks parameter set 0 or 1, which selects the maze bitmap (paramset_to_maze_ptr_lo/hi) and the cat templates (paramset_to_cat_x/y_ptr_lo/hi). round_to_red_rat_count_minus1 and round_to_cat_count_minus1 give this round's numbers of red rats and cats. Then setup_cats (which places the cheese as well), bonus_cheese_eaten cleared and meals_remaining set to 9. Falls into start_life."
  },
  {
   "address": 62006,
   "type": "line",
   "text": "Starts a life, either at the beginning of a round or after being caught. Sets time_drain_interval 70 and move_cycle_interval 6; in a SPEED RUN round (round_is_speed_run negative) first plays speed_run_intro and uses 35 and 4 instead. Then, if the title screen is due (game_in_progress 0), shows attract_screen; otherwise clears the screen, draws the HUD and resets the life (clear_screen_and_draw_hud)."
  },
  {
   "address": 62059,
   "type": "line",
   "text": "Waits 80 ticks with the new life on screen, positions the red rats' radar sprites, and enters the main loop."
  },
  {
   "address": 62065,
   "type": "line",
   "text": "THE MAIN LOOP, one pass per tick. (1) Every move_cycle_interval ticks: move_player (which includes stars and eating), then player_collision_check. (2) Unless the red rats are frozen, every round_to_red_rat_move_ticks ticks after the start-of-life delay: move_all_red_rats. (3) Every time_drain_interval ticks: one unit of TIME off. (4) per_tick_sound_and_timers, then player_collision_check again, since the red rats may have walked into the player. Caught at either check: player_caught_sequence. (5) If all ten cheeses are gone: round_complete_jingle and time bonus, then the next round."
  },
  {
   "address": 62143,
   "type": "line",
   "text": "round_index+1, wrapping from 15 back to 0; round_number_bcd+1; set up the new round. Also where a SPEED RUN goes when the player is caught in it."
  },
  {
   "address": 62167,
   "type": "line",
   "text": "End of a pass: clear tick_flag, dropping any tick that arrived while this pass was running, and wait for the next."
  },
  {
   "address": 62174,
   "type": "line",
   "text": "The player touched a red rat or a black cat. Silences the music and effects, redraws the red rats, stamps EEEK over the rat, plays a 16-tick rising sweep on voice 1, and waits 80 ticks. lives-1; if none are left, game_over_banner. Otherwise, in a SPEED RUN round the SPEED RUN is over and play moves to the next round; in a normal round the same round restarts with a new life (start_life), keeping the cheese already eaten."
  },
  {
   "address": 62248,
   "type": "line",
   "text": "Out of lives. Writes GAME over OVER (str_game_over, bright banner letters) at screen rows 11-12, columns 10-13, in black, waits 160 ticks and resets the game (game_over_reset)."
  },
  {
   "address": 62276,
   "type": "line",
   "text": "Is the player exactly on a black cat or a red rat? Checks every active entry of cat_x_table/cat_y_table and then of red_rat_x/red_rat_y against player_x/player_y; any match increments player_caught. Cats and red rats are equally deadly to the player. The test is an exact position match, but every step is a single half-cell and the check runs after the player moves and again after the red rats move, so a player and a red rat cannot pass through each other."
  },
  {
   "address": 62320,
   "type": "line",
   "text": "Maze A, used by parameter set 0 (rounds 1-3 and 8-11 of each 15-round cycle). 224 bytes: 56 rows of 4 bytes, 32 cells per row, most significant bit = leftmost cell, 1 = wall. draw_maze_viewport renders a 9x9-cell window of it; the red rats and the cheese placer test it directly."
  },
  {
   "address": 62544,
   "type": "line",
   "text": "Maze B, used by parameter set 1 (rounds 4-7 and 12-15 of each 15-round cycle). Same format as maze_bitmap_a."
  },
  {
   "address": 62768,
   "type": "line",
   "text": "Low bytes of the maze bitmap address for parameter sets 0 and 1: $70, $50. Read by setup_round."
  },
  {
   "address": 62770,
   "type": "line",
   "text": "High bytes of the maze bitmap address for parameter sets 0 and 1: $F3, $F4, giving $F370 and $F450. The $FF/$00 bytes that follow, to $F53F, are unused filler."
  },
  {
   "address": 62784,
   "type": "line",
   "text": "Chooses the next background music note for music_tick, which passes the note index in Y and carry set for phrase A. Phrase A: the note is music_phrase_a[Y] (already in X) with a frequency low byte of 0. Phrase B: music_phrase_b[Y] with low byte 0, except notes 4 and 5 (the two $11 entries that end the phrase), which play the full frequency $10C4 instead. Returns the frequency high byte in X."
  },
  {
   "address": 62811,
   "type": "line",
   "text": "Writes A to both voice 1 frequency bytes. Called with 0 to silence the music when the player is caught."
  },
  {
   "address": 64640,
   "type": "line",
   "text": "Low bytes of the 18 viewport row addresses, screen rows 3-20 at column 3 ($047B, $04A3, ...). Paired with viewport_row_hi for screen RAM and viewport_colour_row_hi for colour RAM. Read by viewport_ptr_from_world_xy."
  },
  {
   "address": 64658,
   "type": "line",
   "text": "High bytes of the 18 viewport row addresses in screen RAM ($04-$07)."
  },
  {
   "address": 64676,
   "type": "line",
   "text": "High bytes of the same 18 rows in colour RAM ($D8-$DB)."
  },
  {
   "address": 64694,
   "type": "line",
   "text": "Low bytes of the 14 radar panel row addresses, screen rows 8-21 at column 23 ($0557 ...). Read by radar_ptr_from_world_xy."
  },
  {
   "address": 64708,
   "type": "line",
   "text": "High bytes of the 14 radar panel row addresses."
  },
  {
   "address": 64722,
   "type": "line",
   "text": "Bit masks $80 $40 $20 $10 $08 $04 $02 $01: selects the bit for cell (n AND 7) in a maze bitmap byte. Read by the viewport renderer, red_rat_can_step and place_meal_items."
  },
  {
   "address": 64730,
   "type": "line",
   "text": "'HI-SCORE', 8 screen codes, drawn at row 1, column 23."
  },
  {
   "address": 64738,
   "type": "line",
   "text": "'SCORE' plus three blanks, drawn at row 4, column 23."
  },
  {
   "address": 64746,
   "type": "line",
   "text": "'TIME : ' followed by the full TIME bar, 17 screen codes drawn at row 1, column 3: nine $77 cells (empty of fill, i.e. time remaining) and one $7E, the last cell already one step used, matching the first unit taken off as a life starts."
  },
  {
   "address": 64763,
   "type": "line",
   "text": "'(C) 1982 COMMODORE ELECTRONICS LTD.', 35 screen codes, drawn at row 23, column 3."
  },
  {
   "address": 64798,
   "type": "line",
   "text": "'NEXT' and 'MEAL', drawn as a 4x2 block at row 8, column 32 using stamp_offsets_4x2."
  },
  {
   "address": 64806,
   "type": "line",
   "text": "'ROUND', drawn at row 18, column 32."
  },
  {
   "address": 64811,
   "type": "line",
   "text": "'GAME' and 'OVER' in the bright banner alphabet ($3C G, $3D A, $3E M, $22 E, $2B O, $3F V, $24 R), stamped as a 4x2 block by game_over_banner."
  },
  {
   "address": 64819,
   "type": "line",
   "text": "The SPEED RUN banner, 20 codes indexed by speed_run_letter_index and written right to left by speed_run_intro: blanks ($00), 'SPEED' in the bright alphabet ($1B S, $1C P, $22 E, $22 E, $23 D), two blanks, 'RUN' ($24 R, $25 U, $26 N), blanks, and two $20 at the end."
  },
  {
   "address": 64839,
   "type": "line",
   "text": "'NO.' in the bright alphabet ($26 N, $2B O, $1F '.'), printed before the SPEED RUN number."
  },
  {
   "address": 64842,
   "type": "line",
   "text": "Screen offsets 0, 1, 2, 3, 40, 41, 42, 43: a block four characters wide and two rows tall. Used for NEXT/MEAL and GAME/OVER."
  },
  {
   "address": 64850,
   "type": "line",
   "text": "'PUSH', title screen, row 5, column 6."
  },
  {
   "address": 64854,
   "type": "line",
   "text": "\"'F1' TO RUN \", title screen, row 7, column 5."
  },
  {
   "address": 64866,
   "type": "line",
   "text": "' BONUS RAT', title screen, row 9, column 5."
  },
  {
   "address": 64879,
   "type": "line",
   "text": "'FOR 20000 PTS', title screen, row 10, column 5. The bonus life is awarded once per game (add_score)."
  },
  {
   "address": 64892,
   "type": "line",
   "text": "'COMMODORE V.02', title screen, row 12, column 6. The build identifier of this release."
  },
  {
   "address": 64906,
   "type": "line",
   "text": "'STAR SCREEN', the name of the player's weapon, drawn in two lines ('STAR ', 'SCREEN') at rows 17-18, column 5 of the title screen's control legend."
  },
  {
   "address": 64917,
   "type": "line",
   "text": "'MOVE RAT', drawn in two lines at rows 18-19, column 14 of the control legend, under the direction keys."
  },
  {
   "address": 64928,
   "type": "line",
   "text": "Screen offsets 0-4 then 40-45: splits an 11-character string into a 5-character line and a 6-character line below it. Used for STAR SCREEN and MOVE RAT."
  },
  {
   "address": 64939,
   "type": "line",
   "text": "Screen offsets 0, 1, 40, 41: the 2x2 tile stamp used for the rat and EEEK."
  },
  {
   "address": 64940,
   "type": "line",
   "text": "Offsets 1 and 40 (the rat tile's top-right and bottom-left cells) are the two cells move_player looks at for a cheese tile under the rat. The table's third byte, 41, is not used by that loop."
  },
  {
   "address": 64943,
   "type": "line",
   "text": "Rat tile facing up: $40 $41 / $42 $43."
  },
  {
   "address": 64947,
   "type": "line",
   "text": "Rat tile facing right: $44-$47."
  },
  {
   "address": 64951,
   "type": "line",
   "text": "Rat tile facing down: $48-$4B."
  },
  {
   "address": 64955,
   "type": "line",
   "text": "Rat tile facing left: $4C-$4F."
  },
  {
   "address": 64959,
   "type": "line",
   "text": "EEEK tile: $5C-$5F."
  },
  {
   "address": 64963,
   "type": "line",
   "text": "Low bytes of the four screen cells just beyond the rat tile, for up/right/down/left: $059B, $05C5, $0613, $05C2. Read by read_screen_in_direction."
  },
  {
   "address": 64967,
   "type": "line",
   "text": "High bytes of the four probe cells."
  },
  {
   "address": 64971,
   "type": "line",
   "text": "The 32 bytes copied into the eight zero-page red rat glyph tables ($02-$21) at power-on and after each red rat erase. See red_rat_glyph_bl."
  },
  {
   "address": 65003,
   "type": "line",
   "text": "Per-direction X step for actors, indexed by the direction code (0=up, 1=right, 2=down, 3=left): 0, +2, 0, -2. The magnitude is 2 because world coordinates are counted in half-cells and one maze cell is 2 units. Paired with dir_dy_table at $FDEF."
  },
  {
   "address": 65007,
   "type": "line",
   "text": "Per-direction Y step for actors (0=up, 1=right, 2=down, 3=left): -2, 0, +2, 0. Y grows downwards, so 'up' is negative. Paired with dir_dx_table at $FDEB; both are read by enemy_can_step."
  },
  {
   "address": 65011,
   "type": "line",
   "text": "Spawn X positions of the seven red rats: $1A $1E $22 $26 $16 $1E $26 (in half-cells). Copied into red_rat_x at the start of every life."
  },
  {
   "address": 65018,
   "type": "line",
   "text": "Spawn Y positions: $68 for red rats 0-4 (the bottom of the maze) and $06 for red rats 5-6 (the top). The byte read as the eighth slot is not a spawn point."
  },
  {
   "address": 65025,
   "type": "line",
   "text": "One byte per red rat (7): which axis red_rat_chase_direction is closing, 0 = horizontal, nonzero = vertical. Flipped at run time and not reset between lives or games."
  },
  {
   "address": 65032,
   "type": "line",
   "text": "Cat template for parameter set 0 (maze A): 16 X positions. Paired with cat_template0_y; sorted by Y."
  },
  {
   "address": 65048,
   "type": "line",
   "text": "Cat template for parameter set 0: 16 Y positions."
  },
  {
   "address": 65064,
   "type": "line",
   "text": "Cat template for parameter set 1 (maze B): 16 X positions. Paired with cat_template1_y; sorted by Y."
  },
  {
   "address": 65080,
   "type": "line",
   "text": "Cat template for parameter set 1: 16 Y positions."
  },
  {
   "address": 65096,
   "type": "line",
   "text": "Low bytes of the cat X template address for parameter sets 0 and 1 ($08, $28). High bytes at paramset_to_cat_x_ptr_hi."
  },
  {
   "address": 65098,
   "type": "line",
   "text": "High bytes ($FE, $FE) of the cat X template addresses: $FE08 and $FE28."
  },
  {
   "address": 65100,
   "type": "line",
   "text": "Low bytes of the cat Y template address ($18, $38)."
  },
  {
   "address": 65102,
   "type": "line",
   "text": "High bytes ($FE, $FE) of the cat Y template addresses: $FE18 and $FE38."
  },
  {
   "address": 65104,
   "type": "line",
   "text": "Round-complete jingle, seven voice 3 frequency high bytes played forwards, 12 ticks each: $1E $20 $23 $23 $20 $1B $18."
  },
  {
   "address": 65111,
   "type": "line",
   "text": "Cheese-eaten sound, played backwards on voice 3 one note per 4 ticks: $44, $3C, $36, then 0 (silence)."
  },
  {
   "address": 65115,
   "type": "line",
   "text": "Background music phrase A, 16 voice 1 frequency high bytes read backwards (index 15 first): $19 _ $21 _ $21 _ $1F $1C $1F _ $21 _ $19 _ $19 _ (_ = rest). Relative pitches G C C B A B C G G: 'they all ran after the farmer's wife' from Three Blind Mice. The low frequency byte is always 0, so the pitches are only approximately in tune."
  },
  {
   "address": 65131,
   "type": "line",
   "text": "Background music phrase B, read backwards: $19 _ $15 _ $15 _ $13 _ $13 _ $11 $11 then four rests; the two $11 entries are replaced by $10C4 in music_pick_note. Played once after three passes of phrase A."
  },
  {
   "address": 65147,
   "type": "line",
   "text": "2x cheese sound on voice 3, one note per tick, read from the end: $7D $5F $41 $31 $2D $29 $25 $21 four times over, then the 0 at the start silences it (33 ticks)."
  },
  {
   "address": 65180,
   "type": "line",
   "text": "SPEED RUN intro tune, read backwards on voice 1, one note per 10 ticks: rising runs $1E-$28, $1E-$26 and $1E-$24, then silence."
  },
  {
   "address": 65196,
   "type": "line",
   "text": "Game-start fanfare, 47 voice 1 high bytes read backwards, one step per 6 ticks: E D C, E D C, G F F E, G F F E with rests between, i.e. 'Three blind mice, three blind mice, see how they run, see how they run'."
  },
  {
   "address": 65243,
   "type": "line",
   "text": "Red rats per round, minus one, indexed by round_index 0-14: 2 3 6 3 4 5 6 4 5 6 6 6 6 6 6, i.e. 3 4 7 4 5 6 7 5 6 7 7 7 7 7 7 red rats. The 7 in the third round belongs to a SPEED RUN, where the red rats start frozen."
  },
  {
   "address": 65258,
   "type": "line",
   "text": "Ticks between red rat moves, by round_index: 6 for rounds 1-7, 5 for rounds 8-15. With the player moving every 6 ticks, the red rats match the player's speed at first and are 20% faster from round 8."
  },
  {
   "address": 65273,
   "type": "line",
   "text": "Black cats per round, minus one: 7 (8 cats), except 15 (16 cats) at round_index 2, 6, 10 and 14, the SPEED RUN rounds."
  },
  {
   "address": 65288,
   "type": "line",
   "text": "$FF marks a SPEED RUN round: round_index 2, 6, 10, 14 (rounds 3, 7, 11 and 15 of each cycle). A SPEED RUN has the intro banner, 16 cats in fixed template positions, the red rats frozen at their spawn points until TIME runs out, no stars, a faster player (move every 4 ticks) and TIME draining twice as fast. Being caught ends it and moves on to the next round."
  },
  {
   "address": 65303,
   "type": "line",
   "text": "Parameter set (maze and cat template) per round_index 0-14: 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1. The $FF/$00 bytes after the fifteenth entry are unused filler, which continues to the CPU vectors at $FFFA."
  }
 ]
}