{
 "schema": 1,
 "platform": "spectrum",
 "game": "driller",
 "build": "",
 "source": "control file",
 "regions": {
  "exclude": [
   [
    0,
    16383,
    "ROM"
   ],
   [
    23296,
    23739,
    "the printer buffer and the ROM's system variables: the game reads FRAMES ($5C78) once, to start its frame counter, and keeps the ROM's IY for the tape routines, and has no data of its own here"
   ],
   [
    23740,
    27409,
    "the game's work buffers, written in play (the view buffer and the multiply routines at $5CBC, the matrix and vertices at $5E4C, the object buffer at $5F4D, the draw list at $6766, the face list at $6856); at the hand-over they still hold the BASIC loader"
   ],
   [
    65000,
    65535,
    "not the game's block: the loader the BASIC puts at $FE40, which loads the game and hands over, and the bytes below it; the game fills $FE00-$FF00 with its interrupt table, puts a jump at $FDFD and keeps its stack below $FFF8"
   ]
  ],
  "extra": [],
  "edges": [
   16384,
   32768,
   49152
  ]
 },
 "blocks": [
  {
   "start": 16384,
   "end": 23295,
   "type": "Byte"
  },
  {
   "start": 27410,
   "end": 28378,
   "type": "Code"
  },
  {
   "start": 28379,
   "end": 28387,
   "type": "Byte"
  },
  {
   "start": 28388,
   "end": 32945,
   "type": "Code"
  },
  {
   "start": 32946,
   "end": 32959,
   "type": "Byte"
  },
  {
   "start": 32960,
   "end": 33783,
   "type": "Code"
  },
  {
   "start": 33784,
   "end": 33787,
   "type": "Byte"
  },
  {
   "start": 33788,
   "end": 34298,
   "type": "Code"
  },
  {
   "start": 34299,
   "end": 34302,
   "type": "Byte"
  },
  {
   "start": 34303,
   "end": 34657,
   "type": "Code"
  },
  {
   "start": 34658,
   "end": 37133,
   "type": "Byte"
  },
  {
   "start": 37134,
   "end": 37358,
   "type": "Code"
  },
  {
   "start": 37359,
   "end": 37360,
   "type": "Byte"
  },
  {
   "start": 37361,
   "end": 37587,
   "type": "Code"
  },
  {
   "start": 37588,
   "end": 37590,
   "type": "Byte"
  },
  {
   "start": 37591,
   "end": 37891,
   "type": "Code"
  },
  {
   "start": 37892,
   "end": 37947,
   "type": "Byte"
  },
  {
   "start": 37948,
   "end": 38217,
   "type": "Code"
  },
  {
   "start": 38218,
   "end": 38259,
   "type": "Byte"
  },
  {
   "start": 38260,
   "end": 38303,
   "type": "Code"
  },
  {
   "start": 38304,
   "end": 38304,
   "type": "Code"
  },
  {
   "start": 38305,
   "end": 38312,
   "type": "Code"
  },
  {
   "start": 38313,
   "end": 38318,
   "type": "Code"
  },
  {
   "start": 38319,
   "end": 38353,
   "type": "Code"
  },
  {
   "start": 38354,
   "end": 38391,
   "type": "Code"
  },
  {
   "start": 38392,
   "end": 38401,
   "type": "Code"
  },
  {
   "start": 38402,
   "end": 38482,
   "type": "Code"
  },
  {
   "start": 38483,
   "end": 38514,
   "type": "Code"
  },
  {
   "start": 38515,
   "end": 38703,
   "type": "Code"
  },
  {
   "start": 38704,
   "end": 38713,
   "type": "Code"
  },
  {
   "start": 38714,
   "end": 38759,
   "type": "Code"
  },
  {
   "start": 38760,
   "end": 38819,
   "type": "Code"
  },
  {
   "start": 38820,
   "end": 38968,
   "type": "Code"
  },
  {
   "start": 38969,
   "end": 38976,
   "type": "Byte"
  },
  {
   "start": 38977,
   "end": 39305,
   "type": "Code"
  },
  {
   "start": 39306,
   "end": 39311,
   "type": "Byte"
  },
  {
   "start": 39312,
   "end": 40392,
   "type": "Code"
  },
  {
   "start": 40393,
   "end": 40398,
   "type": "Byte"
  },
  {
   "start": 40399,
   "end": 40754,
   "type": "Code"
  },
  {
   "start": 40755,
   "end": 40769,
   "type": "Byte"
  },
  {
   "start": 40770,
   "end": 42389,
   "type": "Code"
  },
  {
   "start": 42390,
   "end": 42390,
   "type": "Byte"
  },
  {
   "start": 42391,
   "end": 43794,
   "type": "Code"
  },
  {
   "start": 43795,
   "end": 43812,
   "type": "Byte"
  },
  {
   "start": 43813,
   "end": 43968,
   "type": "Code"
  },
  {
   "start": 43969,
   "end": 45394,
   "type": "Byte"
  },
  {
   "start": 45395,
   "end": 45854,
   "type": "Code"
  },
  {
   "start": 45855,
   "end": 45855,
   "type": "Byte"
  },
  {
   "start": 45856,
   "end": 46875,
   "type": "Code"
  },
  {
   "start": 46876,
   "end": 46890,
   "type": "Byte"
  },
  {
   "start": 46891,
   "end": 47440,
   "type": "Code"
  },
  {
   "start": 47441,
   "end": 47480,
   "type": "Byte"
  },
  {
   "start": 47481,
   "end": 47643,
   "type": "Code"
  },
  {
   "start": 47644,
   "end": 47645,
   "type": "Byte"
  },
  {
   "start": 47646,
   "end": 47777,
   "type": "Code"
  },
  {
   "start": 47778,
   "end": 47792,
   "type": "Byte"
  },
  {
   "start": 47793,
   "end": 48329,
   "type": "Code"
  },
  {
   "start": 48330,
   "end": 48330,
   "type": "Byte"
  },
  {
   "start": 48331,
   "end": 48883,
   "type": "Code"
  },
  {
   "start": 48884,
   "end": 48889,
   "type": "Byte"
  },
  {
   "start": 48890,
   "end": 49838,
   "type": "Code"
  },
  {
   "start": 49839,
   "end": 50139,
   "type": "Byte"
  },
  {
   "start": 50140,
   "end": 51249,
   "type": "Code"
  },
  {
   "start": 51250,
   "end": 51308,
   "type": "Byte"
  },
  {
   "start": 51309,
   "end": 51484,
   "type": "Code"
  },
  {
   "start": 51485,
   "end": 51653,
   "type": "Byte"
  },
  {
   "start": 51654,
   "end": 51877,
   "type": "Code"
  },
  {
   "start": 51878,
   "end": 52089,
   "type": "Byte"
  },
  {
   "start": 52090,
   "end": 52699,
   "type": "Code"
  },
  {
   "start": 52700,
   "end": 64999,
   "type": "Byte"
  }
 ],
 "symbols": [
  {
   "address": 16384,
   "name": "screen_top_a",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 17408,
   "name": "screen_top_b",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 18432,
   "name": "screen_middle_a",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 19456,
   "name": "screen_middle_b",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 20480,
   "name": "screen_bottom_a",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 21504,
   "name": "screen_bottom_b",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 22528,
   "name": "screen_colours",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 27410,
   "name": "draw_view",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 27516,
   "name": "draw_object_list",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 27731,
   "name": "bound_view_box",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28197,
   "name": "make_multipliers",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28379,
   "name": "identity_matrix",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28388,
   "name": "make_view_matrix",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28610,
   "name": "draw_cuboid",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28855,
   "name": "draw_pyramid",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 29739,
   "name": "draw_polygon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 29879,
   "name": "draw_rectangle",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30098,
   "name": "draw_sensor",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30334,
   "name": "sort_faces",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30723,
   "name": "draw_faces",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30870,
   "name": "mul_matrix",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30997,
   "name": "rotate_vertices",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 31070,
   "name": "mul_return",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 31134,
   "name": "clip_edge",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 31799,
   "name": "clip_classify",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 31901,
   "name": "project_vertices",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32070,
   "name": "transform_vertices",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32140,
   "name": "clip_polygon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32485,
   "name": "face_side",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32946,
   "name": "edge_masks",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32960,
   "name": "fill_face",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 33206,
   "name": "draw_face_list",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 33421,
   "name": "clip_face_list",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 33784,
   "name": "steep_dy",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 33788,
   "name": "prepare_polygon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34299,
   "name": "line_lengths",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34303,
   "name": "prepare_line",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34658,
   "name": "probe_position",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34664,
   "name": "probe_motion",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34682,
   "name": "vehicle",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34683,
   "name": "rig_states",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34701,
   "name": "rig_percent",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34719,
   "name": "gas_picked",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34720,
   "name": "gas_field",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34723,
   "name": "gas_amounts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34725,
   "name": "player_objects",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34860,
   "name": "rig_places",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34914,
   "name": "area_now",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34922,
   "name": "colours",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34930,
   "name": "score",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34933,
   "name": "energy_shield",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34939,
   "name": "script_flags",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34943,
   "name": "script_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34975,
   "name": "area_open",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34976,
   "name": "crosshair_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34979,
   "name": "clock",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34988,
   "name": "aim_mode",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 34991,
   "name": "probe_target",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35000,
   "name": "probe_spare",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35006,
   "name": "step_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35015,
   "name": "dial_needles",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35017,
   "name": "turn_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35024,
   "name": "view_setup",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35039,
   "name": "view_bounds",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35051,
   "name": "gas_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35087,
   "name": "game_state",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35113,
   "name": "script_offsets",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35129,
   "name": "opcode_lengths",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35169,
   "name": "face_lists",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35328,
   "name": "one_face",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35342,
   "name": "line_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35355,
   "name": "frame_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35366,
   "name": "sensor_list",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35428,
   "name": "pass_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35435,
   "name": "projected",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35457,
   "name": "buffer_ptrs",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35489,
   "name": "span_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35804,
   "name": "draw_ptrs",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35824,
   "name": "end_flags",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 35830,
   "name": "messages",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36026,
   "name": "end_messages",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36110,
   "name": "view_rows",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36320,
   "name": "dial_rows",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36416,
   "name": "panel_rows",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36472,
   "name": "sines",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36616,
   "name": "tape_texts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36796,
   "name": "key_state",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36808,
   "name": "dir_commands",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36844,
   "name": "other_commands",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36884,
   "name": "probe_picture",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 36969,
   "name": "jet_picture",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37054,
   "name": "move_keys_picture",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37094,
   "name": "aim_keys_picture",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37134,
   "name": "mul_16x8",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37241,
   "name": "mul_16x16",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37359,
   "name": "div_sign",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37361,
   "name": "div_24_16",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37516,
   "name": "mul_s8",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37588,
   "name": "div32_sign",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37591,
   "name": "div_32_16",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37776,
   "name": "write_number",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37828,
   "name": "print_text",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37892,
   "name": "key_rows",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37908,
   "name": "key_codes",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 37948,
   "name": "read_keys",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38218,
   "name": "sound_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38260,
   "name": "play_sound",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38304,
   "name": "sound_none",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38305,
   "name": "sound_1",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38313,
   "name": "sound_2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38319,
   "name": "sweep",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38354,
   "name": "sound_3",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38373,
   "name": "sound_4",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38392,
   "name": "sound_6",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38402,
   "name": "sound_7",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38428,
   "name": "sound_8",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38458,
   "name": "sound_9",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38483,
   "name": "sound_5",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38515,
   "name": "sound_11",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38550,
   "name": "sound_12",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38585,
   "name": "sound_13",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38628,
   "name": "sound_14",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38653,
   "name": "sound_15",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38685,
   "name": "sound_17",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38704,
   "name": "sound_19",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38714,
   "name": "sound_20",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38740,
   "name": "sound_21",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38760,
   "name": "tone",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38820,
   "name": "start",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38861,
   "name": "begin_game",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38919,
   "name": "main_loop",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38969,
   "name": "sensor_keep",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 38977,
   "name": "process_sensors",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39306,
   "name": "commands_got",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39312,
   "name": "take_commands",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39607,
   "name": "game_over",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39790,
   "name": "run_scripts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39927,
   "name": "copy_view",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 39990,
   "name": "new_game",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 40220,
   "name": "set_start",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 40393,
   "name": "climb_from",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 40399,
   "name": "step_to",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 40755,
   "name": "move_cells",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 40770,
   "name": "move_to",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 41593,
   "name": "move_command",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 42390,
   "name": "collide_id",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 42391,
   "name": "collide",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 42874,
   "name": "set_area_colours",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43011,
   "name": "draw_line",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43194,
   "name": "find_object",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43302,
   "name": "plot",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43356,
   "name": "aim_command",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43680,
   "name": "crosshair",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43795,
   "name": "dissolve_pattern",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43813,
   "name": "dissolve",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 43969,
   "name": "security_words",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 44669,
   "name": "security_words_2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 45387,
   "name": "pick_polygon",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 45395,
   "name": "pick_object",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 45855,
   "name": "script_opcode",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 45856,
   "name": "run_script",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 46876,
   "name": "number_text",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 46891,
   "name": "update_panel",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47420,
   "name": "panel_copy",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47441,
   "name": "dial_centre",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47443,
   "name": "dial_edge",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47481,
   "name": "needle",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47644,
   "name": "bar_ends",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47646,
   "name": "bar",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47778,
   "name": "line_keep",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47793,
   "name": "install_interrupt",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 47846,
   "name": "interrupt",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48294,
   "name": "invert",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48330,
   "name": "enter_cell_hit",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48331,
   "name": "enter_cell",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48500,
   "name": "init_game_data",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48664,
   "name": "load_area",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48884,
   "name": "rig_strike",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 48890,
   "name": "drill",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 49753,
   "name": "rig_redraw",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 49818,
   "name": "show_message",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 49839,
   "name": "info_texts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 50130,
   "name": "tape_vars",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 50140,
   "name": "info_screen",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51136,
   "name": "info_screen_end",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51220,
   "name": "checksum",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51250,
   "name": "tape_or_disc",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51253,
   "name": "filename_line",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51309,
   "name": "filename",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51485,
   "name": "options_texts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51654,
   "name": "control_options",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51878,
   "name": "security_texts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52090,
   "name": "security",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52480,
   "name": "wipe",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52510,
   "name": "clear_view",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52539,
   "name": "place_rig",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52700,
   "name": "font",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53054,
   "name": "data_header",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53064,
   "name": "fill_patterns",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53124,
   "name": "data_offsets",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53128,
   "name": "data_unread",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53135,
   "name": "view_window",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53137,
   "name": "data_unread_2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53147,
   "name": "panel_places",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53162,
   "name": "text_places",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53214,
   "name": "data_copyright",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53234,
   "name": "start_values",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53254,
   "name": "area_table",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53312,
   "name": "area_table_end",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53324,
   "name": "shared_scripts",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53426,
   "name": "area_1",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 53937,
   "name": "demonstration",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 54055,
   "name": "demonstration_room",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 54152,
   "name": "copyright_backwards",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 54193,
   "name": "area_2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 54593,
   "name": "area_3",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 55111,
   "name": "area_8",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 55701,
   "name": "area_14",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 56301,
   "name": "area_15",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 56685,
   "name": "area_16",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 57015,
   "name": "area_17",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 57371,
   "name": "area_18",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 57750,
   "name": "area_19",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58196,
   "name": "area_20",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58464,
   "name": "area_21",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58721,
   "name": "area_22",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 58968,
   "name": "area_23",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59090,
   "name": "area_31",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59278,
   "name": "area_5",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 59580,
   "name": "area_4",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60070,
   "name": "area_6",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60515,
   "name": "area_7",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 60991,
   "name": "area_9",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 61508,
   "name": "area_10",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 61978,
   "name": "area_11",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62334,
   "name": "area_12",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 62745,
   "name": "area_13",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 63117,
   "name": "area_27",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 63657,
   "name": "area_25",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 64032,
   "name": "area_32",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 64158,
   "name": "area_127",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 64402,
   "name": "area_28",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 64706,
   "name": "area_data_end",
   "type": "UserDefined",
   "kind": "user"
  }
 ],
 "comments": [
  {
   "address": 16384,
   "type": "line",
   "text": "The game's own screen, loaded from the tape over the loading picture just before the hand-over: the cockpit, with the title, DRILLER and INTRODUCING FREESCAPE, in the view window, and the console below. The game draws its view over the window and its own figures over the console's as play begins; the rest stays as loaded. The bitmap is in the machine's order, a third of the screen at a time: here the top third (character rows 0 to 7), the top four pixel lines of each row, with the clock (11:59:53 as loaded) and the top of the title."
  },
  {
   "address": 17408,
   "type": "line",
   "text": "The loaded screen's top third, the bottom four pixel lines of each of character rows 0 to 7: the cockpit's frame round the clock, and DRILLER in the view window."
  },
  {
   "address": 18432,
   "type": "line",
   "text": "The loaded screen's middle third (character rows 8 to 15), the top four pixel lines of each row: INTRODUCING and FREESCAPE in the view window, between the cockpit's sides."
  },
  {
   "address": 19456,
   "type": "line",
   "text": "The loaded screen's middle third, the bottom four pixel lines of each of character rows 8 to 15: the rest of FREESCAPE, the bottom of the view window and the top of the console."
  },
  {
   "address": 20480,
   "type": "line",
   "text": "The loaded screen's bottom third (character rows 16 to 23), the top four pixel lines of each row: the console, with the energy and shield, the dials, the position, the area's name (AMETHYST), the score, the vehicle, the keys' use and the message line (GAS BUILD UP)."
  },
  {
   "address": 21504,
   "type": "line",
   "text": "The loaded screen's bottom third, the bottom four pixel lines of each of character rows 16 to 23: the console's lower half, down to the message line."
  },
  {
   "address": 22528,
   "type": "line",
   "text": "The loaded screen's colours, an attribute for each of the 768 character cells, row by row. The five cells at $5A7A-$5A7E are the pass lamps (see $8BF3)."
  },
  {
   "address": 27410,
   "type": "line",
   "text": "Draws the 3D view into the view buffer: a new picture when bit 2 of $8920 asks for one, the last one again when bit 3 of $8921 does. On the tape the first two bytes are JR $6B12, a jump to itself: the game hangs on its first call here unless the security question was answered, which writes $DD and $E5 (PUSH IX) over them ($CBD8, $CCE8). A new picture bounds what can be seen (bound_view_box), builds the view matrix (make_view_matrix) and the multiply routines for it (make_multipliers), empties the sensor list, then puts every object of the area ($8864, $8863 of them) and the player's own objects at $87A5 ($890F of them) through draw_object_list, sorts what was queued (sort_faces) and draws it (draw_faces). It lights the pass lamps as it goes, at the screen address $8BF3 holds, in their lit colour ($8A65): the second (+1) at the start, the third (+2) after the objects and the fourth (+3) after the sort."
  },
  {
   "address": 27443,
   "type": "line",
   "text": "The sensor list starts empty: $8A24 counts it, $8A62 is where the next record goes."
  },
  {
   "address": 27499,
   "type": "line",
   "text": "No new picture: the last one again only when bit 3 of $8921 is set."
  },
  {
   "address": 27516,
   "type": "line",
   "text": "Draws A objects from the list at IX, each record as long as its byte +8 says. An object is skipped when its type (the low nibble of +0) is 0, when bit 6 (hidden) is set, or when it lies wholly outside the box bound_view_box made: on each axis its position (+1 to +3, in units of 64) must be no more than the first limit of the pair at $88E5 and its far side (position plus size, +4 to +6) no less than the second, each by the sign of the byte difference. A sensor (type 2) is neither culled nor tested for hidden here. A drawn object's two corners go to the object buffer ($8BDE) as six words, x0, x1, y0, y1, z0, z1, each scaled by 64 and taken from the player ($8762); bits 0 to 5 of $5E62 record, for each, whether it is on the far side of the player (the low corner above zero, the high corner below). Then the type picks the drawer: 1 a cuboid (draw_cuboid), 2 a sensor (draw_sensor), 3 a rectangle (draw_rectangle), 4 to 9 the pyramids and prisms (draw_pyramid), 10 and up the lines and flat polygons (draw_polygon), with the object's id (+7) in $8916 and its type in $5E61."
  },
  {
   "address": 27567,
   "type": "line",
   "text": "The corners: for x, y and z in turn, position x 64 less the player's, then plus size x 64, each a word."
  },
  {
   "address": 27714,
   "type": "line",
   "text": "On to the next record: +8 is its length."
  },
  {
   "address": 27731,
   "type": "line",
   "text": "Works out the part of the area's box that can be in view, so that draw_object_list can skip what lies outside it. The four corners of the view are the pitch ($876C) and the heading ($876D) each turned by $88D7 either way, in the game's 72 steps to the circle (5 degrees each); each corner falls in one of eight octants, numbered 1 to 8 here, and the octant decides which limits of the area's own box ($88DF-$88E4) bound the view on that side. They go to $88E5-$88EA, a pair for each axis, the upper limit first. An axis no corner bounded keeps $FF, and one of its pair is set from the player's position ($8762, $8764, $8766, x 4, the high byte): the upper one above it, or else the lower one at it."
  },
  {
   "address": 27847,
   "type": "line",
   "text": "The octant: the heading picks 1, 3, 5 or 7 by its quarter, the pitch adds 1, 5, 4 or nothing by its own, wrapping past 8."
  },
  {
   "address": 28106,
   "type": "line",
   "text": "The axes no corner bounded, from the player's position."
  },
  {
   "address": 28197,
   "type": "line",
   "text": "Writes a multiply routine for each of the nine entries of the view matrix ($5E55, signed bytes, $40 = 1.0) into the buffer that $8A97 points to, and its address into the table at $8A83, row by row. Each multiplies DE by the entry's magnitude with shifts and adds unrolled for its own bits: LD HL,0 / XOR A / LD C,0 or $FF (the entry's sign), then from the top set bit ADD HL,DE / ADC A,0 where a bit is set and ADD HL,HL / RLA between, ending JP $795E. An entry of 0 is JP $7981 alone. So the vertices are turned at a fixed cost for each entry, with no multiply loop. The buffer is the view buffer itself, cleared and drawn over once the vertices are turned."
  },
  {
   "address": 28379,
   "type": "line",
   "text": "A 3 x 3 identity matrix in the game's scale, $40 = 1.0, which make_view_matrix starts each rotation from."
  },
  {
   "address": 28388,
   "type": "line",
   "text": "Builds the view matrix at $5E55 from the player's angles, each a step of 5 degrees (0 to 71): the identity, then a rotation by the heading ($876D), the pitch ($876C) and the roll ($876E) in turn, each built at $5E4C from the sine and the cosine that the angle picks in the table at $8E78 (two bytes an angle, the sine first) and multiplied in by mul_matrix; an angle of 0 is skipped. Last comes a scaling, the diagonal $88D2-$88D4. Then it points the object buffer ($8BDE), the face list ($8BDC) and the draw list ($8BE0) at the buffers that $8A9B, $8A99 and $8A9D name, and clears the draw list's count ($8918) and the count of faces that fill the view ($8A6A)."
  },
  {
   "address": 28610,
   "type": "line",
   "text": "Draws a cuboid (object type 1). Its eight corners are made from the two in the object buffer into the vertex list at $5E63, three words each, and transform_vertices turns them through the view. If any can be in view ($5E5F), the faces the player can see are chosen: for each axis the side bits in $5E62 say whether the low face or the high face faces the player, and that face takes its colour from a nibble of the object's colour bytes (+9 to +11, the low nibble for the low face); a face the player cannot see, or of colour 0, gets 0, which the face drawers skip. The six colours go to the face list at $8961, six bytes apart, and the faces are drawn by draw_face_list, or by clip_face_list when $5E5E says some corner is outside a clip plane."
  },
  {
   "address": 28855,
   "type": "line",
   "text": "Draws a pyramid or a prism, object types 4 to 9: one face the full size of the object, and an opposite face whose extent across the object is set by four more bytes of its record, +12 to +15, each in units of 64 (to $5EDC-$5EE2 as words). Types 4 and 5 point along x, one way and the other, 6 and 7 along y, 8 and 9 along z: each fills the eight corners at $5E63 from the object buffer with the inner face's offsets added on its own axes. The face list follows the shape of that inner face: $8986 (five faces) when it shrinks to a point, $89A1 or $89BE (six) when it is a line one way or the other, $89DB (eight) when it is a rectangle; its vertex count goes to $8A7F. After transform_vertices, if any corner can be in view, the faces of the list take their colours from the object's nibbles in turn (+9 on, the low nibble first), and are drawn with only the faces whose corners go one way round ($5E60 = 1) by draw_face_list, or clip_face_list when $5E5E is set."
  },
  {
   "address": 28867,
   "type": "line",
   "text": "Which face list: +12 against +14, and +13 against +15."
  },
  {
   "address": 28929,
   "type": "line",
   "text": "The four offsets of the inner face, times 64, to $5EDC."
  },
  {
   "address": 29640,
   "type": "line",
   "text": "Turn the corners, then give each face of the list its colour."
  },
  {
   "address": 29739,
   "type": "line",
   "text": "Draws a line or a flat polygon, object types 10 to 14: 2 to 6 corners (the type less 8, to $8A7F), each three bytes from +10 of the record, in units of 64, taken from the player's position into the vertex list at $5E63. After transform_vertices, if any can be in view, the one face at $8A00 is set up with its corner count: a line takes the low nibble of +9 as its colour ($5E60 = 0), and a polygon takes colour 1 with the whole byte +9 in $8917, its two nibbles the colours of its two sides ($5E60 = 2, the side seen picked by which way round its corners go). Drawn by draw_face_list, or clip_face_list when $5E5E is set."
  },
  {
   "address": 29879,
   "type": "line",
   "text": "Draws a rectangle, object type 3: a cuboid with one size 0. Its four corners come from the object buffer into $5E63; the flat axis is x if the size +4 is 0, else y if +5 is, else z, and B records it as 1, 2 or 3. After transform_vertices, if any corner can be in view, the side of the flat axis the player is on ($5E62) picks the colour: the low nibble of +9 when the player is beyond the low corner, the high nibble otherwise; a side of colour 0 is not drawn. One face of four corners at $8A00, drawn by draw_face_list, or clip_face_list when $5E5E is set."
  },
  {
   "address": 30098,
   "type": "line",
   "text": "Handles a sensor (object type 2). Every sensor of the area gets a 6-byte record in the sensor list at ($8A62), which draw_view starts empty and counts in $8A24: its id (+7), the frames between its shots (+10), which the interrupt counts to, and a state at +3: 0 when it is hidden, when the player is on none of the sides it watches (the side bits $5E62 against its mask, +13) or when the player is out of its reach; 2 when it is in reach but not on the screen; and 1 when it is, with +4 and +5 then its point on the screen. Reach is |x| + |y| + |z| from the player to the sensor's corner, against the word +11. A sensor in reach is drawn as a line of two points at its corner, a dot ($8A09, colour the low nibble of +9), by draw_face_list."
  },
  {
   "address": 30334,
   "type": "line",
   "text": "Sorts the draw list for the painter's method: $8918 entries at ($8A9D), four bytes each, the last two pointing at the corners of the entry's object (x, y, z, each a low and a high word, from the player). Each pass compares every pair of neighbours. Axis by axis where their extents do not overlap, the side of the player each is on decides which is in front (two bits an axis in $5EE4); a pair is left as it is only when no axis says the first is nearer and at least one says it is farther, and is swapped otherwise. Passes repeat while any pass swapped ($5EE5), one fewer each time than there are entries."
  },
  {
   "address": 30723,
   "type": "line",
   "text": "Draws the sorted draw list ($8918 entries at ($8A9D)) into the view buffer, farthest first. Each entry points at an object's faces: its id, a count (bit 7 set when a face fills the whole view, the low seven bits the number of faces), then each face as a byte, its colour in the high nibble ($8917) and its corner count in the low ($8A7F), and its corners, two bytes each. A face of two corners is a line (prepare_line), any other a polygon (prepare_polygon); either is then filled into the buffer by fill_face. With $889F set the buffer ($8A95, 2,704 bytes) is cleared first; when $8A6A faces fill the view, drawing starts from the last of them and nothing is cleared."
  },
  {
   "address": 30870,
   "type": "line",
   "text": "Multiplies the rotation at $5E4C by the view matrix at $5E55, R x V, both 3 x 3 signed bytes with $40 = 1.0, into $5E55: each of the nine sums of three products (mul_s8) is a word at $5EEB, then divided by 64, rounding up on the top bit shifted out, and kept as a byte. The low bytes of the words are left shifted in place."
  },
  {
   "address": 30997,
   "type": "line",
   "text": "Turns the $8A7F vertices at $5E63 (three words each) through the view matrix into $5E9F (three words each, cleared first): each output coordinate is the sum of the three products of an input coordinate and a matrix entry, made by the routine make_multipliers wrote for that entry (the table at $8A83), whose result comes back through $795E. The input is made positive first and B remembers its sign. $5F01 and $5EFF follow the input and the output."
  },
  {
   "address": 31070,
   "type": "line",
   "text": "Where every generated multiply routine returns: A:H:L is |input| x |entry|; times 4 with the top two bytes kept it is the product divided by 64, truncated. The sign of the input (B) against the entry's (C) negates it, and it is added into the output word at ($5EFF). $7981 is where an entry of 0 jumps, adding nothing."
  },
  {
   "address": 31134,
   "type": "line",
   "text": "Moves the vertex before IX (IX-6, three words) along the edge from it to the vertex at IX until it lies on the clip plane $5EDB: 1 is x = -z, 2 is y = -z, 3 is x = z, 4 is y = z, and anything else the plane z = 0. The fraction of the edge is a ratio of differences, t1 / t2, and each coordinate moves by its own difference times t1 / t2 (mul_16x16 then div_32_16, rounded). On the planes x = +-z or y = +-z the coordinate on the plane is set from the new z."
  },
  {
   "address": 31799,
   "type": "line",
   "text": "Says which side of the clip plane $5EDB the vertex at IX is on: A = 0 inside, 1 outside, $FF on the plane. Planes 1 and 2 test x + z and y + z, 3 and 4 test z - x and z - y, anything else z itself; outside is a negative word (by its sign bit)."
  },
  {
   "address": 31901,
   "type": "line",
   "text": "Projects the $8A7F turned vertices at $5E9F onto the view, two bytes each at $8A6B: x' = cx + x x cx / z and y' = cy + y x cy / z, with cx and cy the view's half-width and half-height ($88D9, $88DA), by mul_16x8 and div_24_16. A coordinate outside the view's pyramid is clamped to 0 or to twice the half-size, and a vertex at z = 0 goes to the centre."
  },
  {
   "address": 32070,
   "type": "line",
   "text": "Turns the $8A7F vertices at $5E63 through the view (rotate_vertices), then tests them against the clip planes from $8A80 down to 1 (clip_classify). $5E5F is 0 if every vertex is outside some plane, so nothing of them can be seen, and 1 otherwise; $5E5E is 1 if some vertex was outside a plane tested, so the faces must be clipped."
  },
  {
   "address": 32140,
   "type": "line",
   "text": "Clips the polygon of $8A7F turned vertices at $5E9F against each clip plane from $8A80 down to 1, Sutherland and Hodgman's way: the vertices' sides of the plane go to $5F40, and each edge that crosses it adds its crossing point (clip_edge) to the output at $5F03, each vertex inside adding itself, a point the same as the last one added left out ($5F3F counts them). A polygon of more than two corners closes on its first vertex, copied after its last. What is left goes back to $5E9F and $8A7F; fewer than two corners leave $8A7F = 0, and so does a polygon with no vertex inside a plane."
  },
  {
   "address": 32485,
   "type": "line",
   "text": "Says which way round the three screen points at HL go, by the side of the line through the first two that the third is on: A = 0 or 1, and 1 when they are in a line. Points in a vertical or a horizontal line are decided by comparisons; otherwise the line's slope is worked out x 2048 (div_24_16), with x and y of all three swapped first when the line is steep (and swapped back after), and the third point's height against the line's at its x gives the side."
  },
  {
   "address": 32946,
   "type": "line",
   "text": "Masks of the left 1 to 7 pixels of a byte, then of single pixels 1 to 7, for fill_face's partial bytes."
  },
  {
   "address": 32960,
   "type": "line",
   "text": "Fills a face from the span table ($8A9F, three bytes a row: 0, 1 or 2 ends set, and their x) into the view buffer, from row $8919 down to row $891B, in the pattern of colour $8917: four bytes a colour from ($891D), one for each row modulo 4. Rows are stored bottom up, ($88DD) bytes each, from ($8A95). A row with one end set is a single pixel; x counts from 1, so a span starting at 0 loses that pixel. Each row's ends are cleared as it is filled."
  },
  {
   "address": 33206,
   "type": "line",
   "text": "Puts the faces of an object, at IY, into the face list at ($8BDC), when every corner is inside the clip planes: the corners are projected (project_vertices), and each face of the list (a colour byte and a corner count, then the corners' numbers) gets a byte, its colour x 16 plus its count, then its corners' screen points. A face of colour 0 is skipped. With $5E60 = 1 only faces whose corners go one way round (face_side) are kept; with 2 the side seen picks the colour from the nibbles of $8917. When any face was kept the object goes into the draw list ($8BE0: where its faces are, and where its corners are in the object buffer), the face list and the object buffer (12 bytes) move on, and $8918 counts it."
  },
  {
   "address": 33421,
   "type": "line",
   "text": "Puts the faces of an object, at IY, into the face list when some corner is outside a clip plane: each face's corners are copied to $5E9F, clipped (clip_polygon), projected and kept or skipped as draw_face_list does. A face of four corners left at the four corners of the view fills it: it ends the object, $8A6A counts it and bit 7 of the object's face count marks it, so draw_faces can start there."
  },
  {
   "address": 33652,
   "type": "line",
   "text": "Does the face fill the whole view: its four points at (0, 0), (0, 2cy), (2cx, 2cy) and (2cx, 0) in any order?"
  },
  {
   "address": 33784,
   "type": "line",
   "text": "prepare_polygon's two lengths of the edge it is stepping along."
  },
  {
   "address": 33788,
   "type": "line",
   "text": "Turns the $8A7F screen corners at IX of a polygon into the span table at ($8A9F), three bytes a row: the corners are copied to $8A6B with the first again after the last, $8919 and $891B take the highest and the lowest row, and each edge in turn sets, on every row it crosses from its top end down, one end of the row's span (the first x a row gets, then a second if it differs). A level edge on the top or bottom row sets both ends at once. A steep edge steps a row at a time and moves x when its error passes; a shallow one steps x until its error passes and keeps the first x of each row. IX is left after the corners."
  },
  {
   "address": 34299,
   "type": "line",
   "text": "prepare_line's two lengths of the line it is stepping along."
  },
  {
   "address": 34303,
   "type": "line",
   "text": "Turns the line of two screen points at IX into the span table: every row from the top end to the bottom one gets the x the line is at (one end set), and a shallow line a span from where it enters a row to where it leaves; $8919 and $891B take its rows. IX is left after the points."
  },
  {
   "address": 34658,
   "type": "line",
   "text": "The probe's position: x ($8762), height ($8764) and z ($8766), each a word in fine units, 64 to a unit of the area's grid. Four times a coordinate, its high byte, is the grid unit it is in, which is how bound_view_box, drill and the cell tests read it."
  },
  {
   "address": 34664,
   "type": "line",
   "text": "How the probe moves. The step ($8768, a word) is the walking step ($876A) times the area's scale; $876B is the walking step's place in the table at $88BF. The three angles, in 72nds of a turn (5 degrees): the pitch ($876C), the heading ($876D) and the roll ($876E). The turn step ($876F) and its place in the table at $88CA ($8770). Then four limits in cells as the game's data sets them, the most the probe may stand up to ($8771), its standing height ($8772), and the most it may fall ($8773) and climb ($8774), and the same four times the area's scale ($8775 to $8778), which load_area works out from the scale itself ($8779)."
  },
  {
   "address": 34682,
   "type": "line",
   "text": "Which vehicle the player is in: 0 the probe, otherwise the jet, which flies. It starts as $CFFF says (0)."
  },
  {
   "address": 34683,
   "type": "line",
   "text": "The state of each of the 18 sectors that can be drilled, a byte each from sector 1: 0 no rig, 1 a rig that struck nothing, 2 a rig on less than half the gas, 3 a rig that made the sector safe. Collecting a rig sets it back to 0."
  },
  {
   "address": 34701,
   "type": "line",
   "text": "The share of the sector's gas that its rig struck, as the percentage drill works out (100 less the rig's distance from the field's centre times 100 over the field's size), a byte for each of the 18 sectors; 0 with no rig, or one that struck nothing."
  },
  {
   "address": 34719,
   "type": "line",
   "text": "Set once the first rig strikes gas, when the amounts of gas in the sectors are picked: $87A3 then points from 0 to 15 bytes into the table at $88EB, as the clock's frame count ($88A3) happened to be."
  },
  {
   "address": 34720,
   "type": "line",
   "text": "The gas field of the area the player is in, from its record: the centre, x ($87A0) and z ($87A1), in grid units, and the field's size ($87A2), which drill divides the rig's distance from the centre by. All three are 0 where there is no gas."
  },
  {
   "address": 34723,
   "type": "line",
   "text": "Where the sectors' amounts of gas start in the table at $88EB, a word: sector n's amount is the byte n - 1 on from it."
  },
  {
   "address": 34725,
   "type": "line",
   "text": "The player's own objects, which draw_view draws in every area after the area's own ($890F of them, 8), each in the area's object format with its length at +8. The first five are the drilling rig: $87A5, $87C0 and $87CE, which place_rig shows where the area's rig stands, and $87DE and $87EE, shown only when it struck gas. load_area hides the last three ($87FE, $880E, $881E) as each area loads."
  },
  {
   "address": 34860,
   "type": "line",
   "text": "Where the rig stands in each of the 18 sectors: x, height and z in grid units, three bytes a sector from sector 1, written when a rig is placed."
  },
  {
   "address": 34914,
   "type": "line",
   "text": "The area the player is in ($8862), its count of objects ($8863), and where its objects ($8864), its name ($8866) and its scripts ($8868) begin in the area data, from its record."
  },
  {
   "address": 34922,
   "type": "line",
   "text": "The colours in use: the border ($886A, also the bits the sound routines write to the beeper's port with it), the border colour that sound 2 flashes ($886B), and the view's paper and ink ($886C, $886D), which make its attribute as paper x 8 + ink, so a paper of 8 is bright. Then the area's own four ($886E-$8871), from its record; set_area_colours copies them over the first four, and a script's opcode $19 can change them."
  },
  {
   "address": 34930,
   "type": "line",
   "text": "The score, 24 bits, low byte first."
  },
  {
   "address": 34933,
   "type": "line",
   "text": "The energy ($8875) and the shield ($8878) of the vehicle in use, at most 63 each, and those of the other kept for it: the jet's energy and shield ($8876, $8879) and the probe's ($8877, $887A)."
  },
  {
   "address": 34939,
   "type": "line",
   "text": "The scripts' 32 flags, eight to a byte, which opcodes $0C, $0D, $1D and $0E set, clear, toggle and test. Bit 7 of $887E is also set while the player is in the jet, and bit 6 while the area can take a rig."
  },
  {
   "address": 34943,
   "type": "line",
   "text": "The scripts' 32 variables, a byte each from variable 1, which opcodes 9, $0A, $14 and $0B add one to, take one from, set and test. The game keeps three of them itself: the interrupt counts $889C and $889D on each minute (load_area sets $889D back to 0), and $889E counts the sectors made safe."
  },
  {
   "address": 34975,
   "type": "line",
   "text": "The first byte of the area's record. When it is not 0, draw_faces clears the view buffer before it draws, so that what no face covers is left empty; with 0 it does not, which is the case in one of the two Stores (area 19), the K1, K2 and K3 complexes, the Linker and the Ketar hangar."
  },
  {
   "address": 34976,
   "type": "line",
   "text": "The crosshair: its x and y in the view ($88A0, $88A1), whether it is on the screen ($88A2), and whether the player wants it shown ($88AD, which command $15 turns on and off)."
  },
  {
   "address": 34979,
   "type": "line",
   "text": "The clock. The interrupt counts 50 frames at $88A3, then takes a second from the time at $88A4-$88AB, eight ASCII characters, \"HH:MM:SS\", as the console prints them. It starts at four hours ($CFF2)."
  },
  {
   "address": 34988,
   "type": "line",
   "text": "What the direction keys do ($88AC): 0 move the probe, otherwise move the crosshair. Command $1E swaps them. $88AD says whether the crosshair is wanted (see $88A0), and $88AE is the minute the main program last saw at $889D, so that a pass runs each minute even with no key held."
  },
  {
   "address": 34991,
   "type": "line",
   "text": "Where a move is taking the probe: x, height and z as words in fine units ($88AF, $88B1, $88B3), and the grid cell it is in, x, height and z ($88B5-$88B7)."
  },
  {
   "address": 35000,
   "type": "line",
   "text": "Six bytes that no instruction found reads or writes, 0 in the image."
  },
  {
   "address": 35006,
   "type": "line",
   "text": "The walking steps that commands $11 and $12 choose from: the count (8) at $88BE, then the steps, 1, 2, 5, 10, 25, 50, 100 and 250, in fine units before the area's scale."
  },
  {
   "address": 35015,
   "type": "line",
   "text": "Where the two dials' needles were last drawn, so that drawing them again takes them off: the pitch's ($88C7) and the heading's ($88C8), $FF when none is drawn."
  },
  {
   "address": 35017,
   "type": "line",
   "text": "The turn steps that commands $0B and $0C choose from: the count (6) at $88C9, then the steps, 1, 2, 3, 6, 9 and 18, in 72nds of a turn (5 to 90 degrees)."
  },
  {
   "address": 35024,
   "type": "line",
   "text": "How far enter_cell keeps the probe from a wall ($88D0, in fine units, 10; check_sensors makes it 0 while it tests a sensor's line, keeping it at $9840); a byte not used; the scaling that ends the view matrix, x, y and z ($88D2-$88D4, $40 = 1.0); two bytes not used; the half-width of the view ($88D7, in 72nds of a turn), which bound_view_box turns the angles by; how far either side of its angle a dial's needle reaches ($88D8); the view's centre, x and y ($88D9, $88DA); and the view's size, rows ($88DB) and bytes a row ($88DD), each a word."
  },
  {
   "address": 35039,
   "type": "line",
   "text": "The area's box, a pair for each axis, the upper limit first ($88DF-$88E4), and the part of it that can be in view, as bound_view_box works it out each picture ($88E5-$88EA)."
  },
  {
   "address": 35051,
   "type": "line",
   "text": "The amounts of gas, 18 of them, twice over, so that any of 16 starting points ($87A3) gives each sector one: a sector's amount times the percentage its rig struck, times 10, is added to the score."
  },
  {
   "address": 35087,
   "type": "line",
   "text": "How many of the player's objects there are ($890F, 8); the area's colours to be set ($8910); the entrance the probe is put at ($8911); where the area records are ($8912) and their table of offsets ($8914); the object being drawn or looked for ($8916); the colour of the face being filled ($8917); the count of entries on the draw list ($8918), four bytes and one object each, with all its faces; the top and bottom rows of the face being filled ($8919, $891B); the colour patterns ($891D); what the game is doing ($891F: 1 play, 3 the demonstration); what draw_view and update_panel are to redraw, a bit each ($8920, $8921); the shared scripts ($8922); the demonstration's start ($8924), its repeat count ($8926) and its place ($8927)."
  },
  {
   "address": 35113,
   "type": "line",
   "text": "For each object type, 0 to 15, how long the fixed part of its record is: the object's script is what follows, up to the record's length (+8), and an object whose length equals it has none."
  },
  {
   "address": 35129,
   "type": "line",
   "text": "How long each of the script opcodes 0 to $21 is with its operands, a byte each; run_script steps over an opcode it does not run by this. Six bytes of 0 follow."
  },
  {
   "address": 35169,
   "type": "line",
   "text": "The faces of the shapes, as lists of corner numbers for the eight corners at $5E63: a byte for the colour, the corner count, then the corners. The cuboid's six faces at $8961, then the pyramids' and prisms': five faces at $8986 for one whose inner face is a point, six at $89A1 and $89BE for a line one way or the other, eight at $89DB for a rectangle."
  },
  {
   "address": 35328,
   "type": "line",
   "text": "The one face of a rectangle, a line or a flat polygon: its colour ($8A00), its corner count ($8A01) and its corners, 0 to 5, in order. $8A09 is a sensor's face, a line of two points both at its one corner, which draws a dot."
  },
  {
   "address": 35342,
   "type": "line",
   "text": "draw_line's work: the two ends, x and y, ($8A0E, $8A0F) to ($8A10, $8A11), and the differences, steps and counts of its loop ($8A12-$8A1A)."
  },
  {
   "address": 35355,
   "type": "line",
   "text": "The table of screen rows that draw_line and plot work through ($8A1B, a word: the view's at $8D0E, or a dial's while needle draws); the frame counter the interrupt counts ($8A1D); whether the probe ran into something ($8A1E); the sound queued for after the view is shown ($8A1F); $8A20, which new_game sets and no instruction found reads; the beam state, which the interrupt and the main program share ($8A21); the ROM's IY, kept for the tape routines ($8A22); the count of sensors in view ($8A24), and of those in the interrupt's copy of the list ($8A25), which check_sensors sets as it hands the list over."
  },
  {
   "address": 35366,
   "type": "line",
   "text": "The sensors of the area and of the player's objects, six bytes each, room for five, as draw_sensor lists them, those hidden, not watching or out of reach among them with state 0: from here the main program writes, and at $8A44 the interrupt keeps its own copy, whose third byte of each it counts for the beam. $8A62 is where the next record goes."
  },
  {
   "address": 35428,
   "type": "line",
   "text": "Whether anything moved in this pass ($8A64); the two attributes of the pass lamps ($8A65 lit, $8A66 dark); the energy and shield last drawn on the bars ($8A67, $8A68); the object walked into or shot ($8A69); and the count of faces that fill the view ($8A6A)."
  },
  {
   "address": 35435,
   "type": "line",
   "text": "The corners of the face being drawn, projected onto the view, x and y a byte each, with the first again after the last; then the count of corners ($8A7F) and of clip planes ($8A80)."
  },
  {
   "address": 35457,
   "type": "line",
   "text": "Where things are: the font ($8A81); the nine multiply routines for the view matrix, a word each ($8A83-$8A94); the view buffer ($8A95); the buffer the multiply routines are written into ($8A97); the face list ($8A99), the object buffer ($8A9B), the draw list ($8A9D) and the span table ($8A9F)."
  },
  {
   "address": 35489,
   "type": "line",
   "text": "The span table that a face is filled from, three bytes for each of the view's 105 rows: how many ends of a span are set on the row (0, 1 or 2), and their x."
  },
  {
   "address": 35804,
   "type": "line",
   "text": "Where the face list ($8BDC), the object buffer ($8BDE) and the draw list ($8BE0) have reached, and the object being drawn ($8BE2). Then the tables of screen rows for the view ($8BE4), the two dials ($8BE6, $8BE8), the vehicle's picture ($8BEA), the height's letter ($8BEC) and the keys' picture ($8BEE)."
  },
  {
   "address": 35824,
   "type": "line",
   "text": "Whether the next view dissolves in ($8BF0); whether the scripts being run were started by a shot ($8BF1); how the game stands ($8BF2: 0 on, 1 not yet begun or the shield gone, 2 the time, 3 the energy, 4 a fall, 5 every sector safe, 6 abandoned); and where the pass lamps are on the screen ($8BF3, $5A7A from $CFA4): five attribute cells of the console, put dark at the start of each pass and lit as each stage of it ends. The byte after, from $CFA6, no instruction found reads."
  },
  {
   "address": 35830,
   "type": "line",
   "text": "The message line's texts, 14 characters each: SECTOR CLEARED, GAS BUILD UP, AREA NEUTRAL, RIG POSITIONED, POS UNSUITABLE, the gas in cubic feet and the percentage struck, whose digits drill writes, ENERGY TOO LOW, NOT IN PROBE, NO GAS FOUND, RIG COLLECTED, PROCESSING, ALREADY PLACED and NO RIG PLACED."
  },
  {
   "address": 36026,
   "type": "line",
   "text": "The game over's texts, 14 characters each, one for each way it ends, by $8BF2: OUT OF TIME (2), SHIELD OUT (1), ENERGY OUT (3), NASTY FALL (4), TERMINATED (6) and TASK COMPLETED (5)."
  },
  {
   "address": 36110,
   "type": "line",
   "text": "The screen address of each of the view's 105 rows, the bottom row first, from column 3: draw_view's copy and the crosshair work through the view by this table."
  },
  {
   "address": 36320,
   "type": "line",
   "text": "The screen rows of the console's two dials, 24 rows each: the heading's ($8DE0) and the pitch's ($8E10)."
  },
  {
   "address": 36416,
   "type": "line",
   "text": "The screen rows of the console's small pictures: the vehicle's, 14 rows ($8E40); the height's letter, one ($8E5C); the keys' use, 13 rows ($8E5E)."
  },
  {
   "address": 36472,
   "type": "line",
   "text": "The sine and the cosine of each of the 72 angles, two signed bytes an angle, the sine first, $40 = 1.0, which make_view_matrix and the movement use."
  },
  {
   "address": 36616,
   "type": "line",
   "text": "The tape messages, 20 characters each: blank, PRESS PLAY & RECORD, INVALID FILE, LOADING ERROR, LOADING FILE, THEN ANY KEY, SAVING FILE, FOUND : and SEARCHING."
  },
  {
   "address": 36796,
   "type": "line",
   "text": "What read_keys found: the count of keys held ($8FBC) and their codes ($8FBD-$8FC1); the frame counter it waits on ($8FC2, which the interrupt counts down); the delay and the rate of a held key's repeat ($8FC3, $8FC4); and the controls chosen ($8FC5: 0 keyboard, 1 Sinclair, 2 Kempston, 3 cursor). Then the counts of the two command tables that follow ($8FC6, $8FC7)."
  },
  {
   "address": 36808,
   "type": "line",
   "text": "The direction keys, three bytes each: the key's code, its command when the keys move the probe, and its command when they move the crosshair. Forward (3) or up ($1A) on 7, O and the stick's up ($91); back (4) or down ($19) on 6, K and down ($92); turn left (5) or left ($18) on 5, Q and left ($93); turn right (6) or right ($17) on 8, W and right ($94)."
  },
  {
   "address": 36844,
   "type": "line",
   "text": "The other keys, two bytes each, the key's code and its command: 0 and the stick's fire fire ($16), B the crosshair ($15), Y $5E, T $5B, SPACE swaps the keys ($1E), A and Z the turn step ($0B, $0C), S and X the walking step ($11, $12), U turns round ($0D), R and F up and down (1, 2), P and L look up and down (7, 8), N and M roll (9, $0A), D drills ($28), C collects ($2A) and I the information screen ($29). The count at $8FC7 is 24, four more than there are: the search runs on into the picture after, whose bytes match no key."
  },
  {
   "address": 36884,
   "type": "line",
   "text": "The probe's picture for the console, 14 rows of 6 bytes after the count of bytes a row."
  },
  {
   "address": 36969,
   "type": "line",
   "text": "The jet's picture for the console, 14 rows of 6 bytes after the count of bytes a row."
  },
  {
   "address": 37054,
   "type": "line",
   "text": "The picture of the keys' use while they move the probe, 13 rows of 3 bytes after the count of bytes a row."
  },
  {
   "address": 37094,
   "type": "line",
   "text": "The picture of the keys' use while they move the crosshair, 13 rows of 3 bytes after the count of bytes a row."
  },
  {
   "address": 37134,
   "type": "line",
   "text": "Multiplies HL by A, both signed, into A:H:L, a signed 24-bit product: the magnitudes by shift and add from the top set bit of A, then the sign. A or HL of 0 gives 0 at once. BC and DE are kept."
  },
  {
   "address": 37241,
   "type": "line",
   "text": "Multiplies HL by DE, both signed, into DE:HL, a signed 32-bit product: the magnitudes by shift and add, the multiplier's bits taken from its top set one, then the sign. HL of 0 clears DE, DE of 0 clears HL. AF and BC are kept."
  },
  {
   "address": 37359,
   "type": "line",
   "text": "The sign of div_24_16's quotient (1 or $FF), and the count of bits left to divide."
  },
  {
   "address": 37361,
   "type": "line",
   "text": "Divides A:H:L by DE, both signed, into A:H:L, the quotient truncated towards zero, with DE the remainder of the two magnitudes. The dividend is shifted up to its top set bit, then divided a bit at a time by restoring subtraction for the bits that are left ($91F0). A dividend of 0 gives 0 and DE = 0."
  },
  {
   "address": 37516,
   "type": "line",
   "text": "Multiplies H by L, both signed bytes, into HL. Either of 0 gives 0 at once. AF, BC and DE are kept."
  },
  {
   "address": 37588,
   "type": "line",
   "text": "The sign of div_32_16's quotient (1 or $FF), and its running remainder, a word."
  },
  {
   "address": 37591,
   "type": "line",
   "text": "Divides DE:HL by BC, both signed, into DE:HL, with BC the remainder of the magnitudes (also at $92D5). The quotient of the magnitudes is rounded up when the remainder less half the divisor is not negative, then given its sign. Half the divisor is taken rounded down, so a remainder of a third rounds up when the divisor is 3: 1 / 3 gives 1, 4 / 3 gives 2. A dividend of 0 gives 0 and BC = 0. AF is kept."
  },
  {
   "address": 37722,
   "type": "line",
   "text": "The rounding: the remainder against half the divisor, the quotient one more when it is not less. The last bit of the quotient went in just before ($9352-$9358)."
  },
  {
   "address": 37776,
   "type": "line",
   "text": "Writes the number DE:HL in decimal as A ASCII digits ending at IX + A - 1, leading zeros kept: each digit is the remainder of a division by 10 (div_32_16), whose rounding of the quotient is undone when the remainder is 5 or more. Every register is kept."
  },
  {
   "address": 37828,
   "type": "line",
   "text": "Prints the text at IX on the screen. HL points at a record: the screen address (a word) and the number of characters. Each character is six bytes of the font that $8A81 points to, from character $20 on, written to six pixel rows of a cell, one under the other ($100 apart). Every register is kept."
  },
  {
   "address": 37892,
   "type": "line",
   "text": "The keyboard as read_keys last scanned it: one byte for each of the eight half-rows, the keys held as set bits, each bit cleared as read_keys turns its key into a code, so that once it returns they hold only keys past the fifth, usually none. Then the repeat flag ($940C), the count of keys held last time ($940D) and those keys' codes ($940E-$9412)."
  },
  {
   "address": 37908,
   "type": "line",
   "text": "The code of each key, five to a half-row, from the half-row of CAPS SHIFT to that of SPACE: $7F for CAPS SHIFT, $0D for ENTER, $1B for SYMBOL SHIFT and the ASCII capital or digit for the rest."
  },
  {
   "address": 37948,
   "type": "line",
   "text": "Reads the keys held. Up to five codes go to $8FBD on, their count to $8FBC; with the Kempston joystick chosen ($8FC5 = 2) its fire, up, down, left and right add $95, $91, $92, $93 and $94. No key gives A = 0 with the carry clear. A new set of keys gives the first code in A with the carry set. The same keys held as last time are given again only once the frame counter at $8FC2 has run down: first from the delay at $8FC3, then from the repeat at $8FC4; until then this loops, scanning again."
  },
  {
   "address": 38218,
   "type": "line",
   "text": "The address of each sound effect, 1 to 21."
  },
  {
   "address": 38260,
   "type": "line",
   "text": "Plays sound effect A (1-21) on the beeper, its address from sound_table written into the CALL at $958F. The interrupts are off while it plays, and on again after it unless A is 2, the effect the interrupt plays itself. Every register is kept."
  },
  {
   "address": 38304,
   "type": "line",
   "text": "Effects 16 and 18: nothing."
  },
  {
   "address": 38305,
   "type": "line",
   "text": "Effect 1: 96 pulses of sweep in the border colour."
  },
  {
   "address": 38313,
   "type": "line",
   "text": "Effect 2: 24 pulses of sweep in the colour at $886B. The interrupt plays it when a sensor fires."
  },
  {
   "address": 38319,
   "type": "line",
   "text": "DE pulses with the border colour in A: a wait of C turns, the speaker raised for C and then 256 turns of a DJNZ, then lowered. C starts at 1 and goes up by 9 each pulse."
  },
  {
   "address": 38354,
   "type": "line",
   "text": "Effect 3: two notes."
  },
  {
   "address": 38373,
   "type": "line",
   "text": "Effect 4: two notes."
  },
  {
   "address": 38392,
   "type": "line",
   "text": "Effect 6: one note of 42 cycles."
  },
  {
   "address": 38402,
   "type": "line",
   "text": "Effect 7: two cycles at each pitch, each lower than the last, from tone's shortest half-period by $14 to $C00."
  },
  {
   "address": 38428,
   "type": "line",
   "text": "Effect 8: $800 pulses, each high for 24 turns of a DJNZ and low for E turns, E falling."
  },
  {
   "address": 38458,
   "type": "line",
   "text": "Effect 9: 256 pulses, high and low for E turns each, E falling from 256."
  },
  {
   "address": 38483,
   "type": "line",
   "text": "Effects 5 and 10: eight runs of six notes of seven cycles, each run falling from tone's shortest half-period by $32."
  },
  {
   "address": 38515,
   "type": "line",
   "text": "Effect 11: $600 pulses, each high for C and then 256 turns, C going up by one a pulse. The wait before each is meant to be C turns: after the first it is D OR E, the count left."
  },
  {
   "address": 38550,
   "type": "line",
   "text": "Effect 12: 256 pulses, each a wait of C turns, then high for C and then E turns, C going up and E down."
  },
  {
   "address": 38585,
   "type": "line",
   "text": "Effect 13: $E8 edges, each wait computed from the last by a little arithmetic on H, then the speaker left low in the border colour."
  },
  {
   "address": 38628,
   "type": "line",
   "text": "Effect 14: 255 pulses, high and low for E turns each, E rising from 1."
  },
  {
   "address": 38653,
   "type": "line",
   "text": "Effect 15: $300 pulses, high for E turns and low for C, E falling and C rising."
  },
  {
   "address": 38685,
   "type": "line",
   "text": "Effect 17: two notes."
  },
  {
   "address": 38704,
   "type": "line",
   "text": "Effect 19: one note of five cycles."
  },
  {
   "address": 38714,
   "type": "line",
   "text": "Effect 20: two cycles at each pitch (tone plays DE + 1, and DE is 1), from tone's shortest half-period by $14 to $1900."
  },
  {
   "address": 38740,
   "type": "line",
   "text": "Effect 21: two cycles at each pitch, from $300 down by 10."
  },
  {
   "address": 38760,
   "type": "line",
   "text": "Plays DE + 1 cycles of a square wave on the beeper. Each half is a wait of H turns of 63 of a loop, plus L / 4 + 1 turns, plus L mod 4 NOPs (the jump into the NOPs at $977E is set by IX); the high half is one turn longer. The wait before the first edge is shorter. The first edge raises the speaker, with the border colour from $886A and MIC set."
  },
  {
   "address": 38820,
   "type": "line",
   "text": "The main program, where the loader hands over. Sets the stack at $FFF8, the game as played ($891F = 1) on the keyboard ($8FC5 = 0), keeps the ROM's IY at $8A22 for the tape routines, sets up a new game (new_game), starts the frame interrupt, waits three seconds and asks the security question."
  },
  {
   "address": 38861,
   "type": "line",
   "text": "Each game: the view and the console drawn whole ($8920 = $FFFD), the clock, the control options (but in the demonstration, $891F = 3), the sensors and the view shown; then, but in the demonstration, 40 frames and the crosshair shown (aim_command $15). The game is on from here ($8BF2 = 0)."
  },
  {
   "address": 38919,
   "type": "line",
   "text": "The main loop, a pass for each command: the view drawn, the sensors checked and the view shown when anything moved ($8920 bit 2 or $8921 bit 3), the console; then the commands (take_commands) and the scripts (run_scripts), until a pass asks for a new game ($8920 bit 1)."
  },
  {
   "address": 38969,
   "type": "line",
   "text": "What check_sensors keeps while it tests a line from the probe to a sensor in reach but off the screen: the probe's x, height and z ($9839, $983B, $983D, words), the vehicle ($983F) and the wall margin ($9840), each put back after."
  },
  {
   "address": 38977,
   "type": "line",
   "text": "Checks each sensor in the list at $8A26 ($8A24 of them, six bytes each: the object, the frames between shots, the count, the state draw_sensor gave it, its place on the screen) for a line to the probe. One on the screen (1) keeps firing only if pick_object, with the crosshair put at its place on the screen, finds it there; one in reach but off the screen (2) only if move_to, from the probe to the sensor with the step's margin ($88D0) off and as if flying, gets all the way, so that a wall between them stops it. Then it waits until the interrupt has no beam on the screen ($8A21 bit 0) with bit 2 set to keep the interrupt off the list, hands the list to the interrupt's copy at $8A44 with each sensor's count kept from the copy, a count of 0 or 1 put back to 2, and shows the new view: the area's colours if asked for ($8910), dissolved in when $8BF0 is set or else copied, and the crosshair over it if it is shown ($88A2). Every register is kept."
  },
  {
   "address": 39306,
   "type": "line",
   "text": "The commands of this pass, one for each key read_keys found, up to five ($998A-$998E), and how many of them have been carried out ($998F), which take_commands clears at the start of each pass."
  },
  {
   "address": 39312,
   "type": "line",
   "text": "A pass's commands. In the demonstration ($891F = 3) one command comes from the recording at ($8927): a byte with bit 7 set gives the next one that many times, and 0 ends the demonstration; a key ends it too. In play it waits for keys, or for a minute of the clock ($889D moved on), which asks for the scripts; then each key held (up to five) becomes a command by the tables at $8FC8 (three bytes a key: the key, its command, and its command while the keys move the crosshair; $8FC6 of them) and after them (two bytes a key; $8FC7 of them), $7F for none, and they are carried out in turn: 1-$14 by move_command, $15-$1E by aim_command, $28 and $2A by drill and $29 by info_screen, each of these two ending the pass."
  },
  {
   "address": 39607,
   "type": "line",
   "text": "The game over, when the interrupt or a script has set $8BF2: once no beam is on the screen, the reason on the message line (1 the shield, 2 the time, 3 the energy, 4 a fall, 5 every sector made safe, 6 the game abandoned), sound $14 but for 5, and the view of area $7F with the number of safe sectors in its name, held 13 times 75 frames. A key in the last twelve of them goes straight to a new game; otherwise the demonstration follows ($891F = 3)."
  },
  {
   "address": 39790,
   "type": "line",
   "text": "After a pass that moved anything ($8A64): the script of the object the probe walked into or shot ($8A69), found at the offset that the object's type gives in the table at $8929, or sound $13 for an object with none when $8A1E asks for it; then the game's shared scripts at ($8922) and the area's at ($8868), each list a count and then each script's length and bytes."
  },
  {
   "address": 39927,
   "type": "line",
   "text": "Copies the view buffer at ($8A95) to the screen, a row of ($88DD) bytes at a time to the screen rows the table at ($8A1B) lists, from the top row down (the buffer holds the top row first), all but the bottom one; then plays the sound queued in $8A1F. Every register is kept."
  },
  {
   "address": 39990,
   "type": "line",
   "text": "Sets up a new game: the probe's height, step and turn angle from the game's data ($CFFC, $D000, $D001), the game not yet on ($8BF2 = 1) with the view to be dissolved in, the score, the variables, the flags, the rigs and the sensors cleared, the energy and shield of the probe and the jet ($CF44-$CF47), init_game_data, the first area ($CF41) at its entrance ($CF42), and every object of every area shown and whole again but those that start hidden (bit 7 of the type byte). Every register is kept."
  },
  {
   "address": 40220,
   "type": "line",
   "text": "Loads area $8862 and puts the probe at its entrance $8911: the entrance's cell (x, height, z, each 64 fine units to a cell with half a cell added, the height above the floor by the probe's own when walking) and its pitch, heading and roll. With no such entrance the probe keeps its place, but comes in at the opposite edge when it left by one: x first, else z, each only when it was on an edge (cell 0 or $7E). Every register is kept."
  },
  {
   "address": 40393,
   "type": "line",
   "text": "step_to's copy of the probe's cell height before a climb, and the byte where collide writes the number of an object it meets in the test above the probe in a climb ($9DCA), so that the test leaves $8A69 alone."
  },
  {
   "address": 40399,
   "type": "line",
   "text": "Takes the probe into the next cell in the directions of A: bits 1 and 0 along x (0 back, 1 on), 3 and 2 in height, 5 and 4 along z. Flying, a blocked cell stops it (A = 1, $8A1E set). Walking, a blocked cell is climbed when a free one is no more than $8778 cells higher and the probe's height ($8776) of cells above that is free too; the height is then raised and sound 4 queued in $8A1F; otherwise A = 1. Once in, the probe falls to the first cell with something under it, sound 3 queued, and a fall of more than $8777 cells ends the game (code 4 in $8BF2). A = 2 after a climb or a fall, else 0 (or B when it neither climbed nor moved in height)."
  },
  {
   "address": 40755,
   "type": "line",
   "text": "move_to's working: the target's cell on each axis ($9F33-$9F35), the crossing point ($9F36-$9F3B) and the move's length on each axis ($9F3C-$9F41)."
  },
  {
   "address": 40770,
   "type": "line",
   "text": "Moves the probe from its position towards the target at $88AF, $88B1 and $88B3, a cell at a time. Of the cell boundaries the line crosses, the x one is taken first, then z, then the height, whichever is met first along the line; the other coordinates at the crossing are worked out from the line's slope (mul_16x16 and div_32_16). The area's walls and a blocked step_to stop the move at the crossing (one unit short of it with $88D0 set). With $88D0 set the probe's position becomes the target, or the place it stopped, enter_cell checks the cells it is in, and A = 1 if it moved, else 0. HL, DE and BC are kept."
  },
  {
   "address": 41304,
   "type": "line",
   "text": "The area's walls ($88DF-$88E4), then the step."
  },
  {
   "address": 41432,
   "type": "line",
   "text": "Stopped: the target becomes the crossing, one short of the boundary when $88D0 is set."
  },
  {
   "address": 41504,
   "type": "line",
   "text": "With $88D0 set, the probe moves there and its cells are checked."
  },
  {
   "address": 41593,
   "type": "line",
   "text": "Carries out movement commands 1-$14. 1 and 2, up and down: flying, by $8768; walking, the probe stands up or crouches by $8779 cells, up to $8771 and down to 1 (the level at $8772). 3 and 4, forward and back, by $8768 along the heading ($876D) and, flying, the pitch ($876C), through the table of sines and cosines at $8E78. 5-$0A turn left and right, look up and down and roll by the turn step ($876F), in $48ths of a turn. $0D turns round. $0B and $0C set the turn step from the table at $88CA, $11 and $12 the walking step from the table at $88BF ($8768 = step x $8779), each with a pause of 7 frames. The bits of BC go into $8920 and $8921, which tell draw_view what to redraw; $8A64 is set after a move or a turn."
  },
  {
   "address": 42351,
   "type": "line",
   "text": "Seven frames' pause."
  },
  {
   "address": 42390,
   "type": "line",
   "text": "The number of the last object collide met that does not stop it at once."
  },
  {
   "address": 42391,
   "type": "line",
   "text": "Tests the probe's cell ($88B5-$88B7) against the area's objects, the list at ($8864) first and then the shared list at $87A5, moving in the directions of A as step_to's. For each axis it moves along, the cell meets an object when the face it moves towards is the object's near face and, on the other two axes, the cell is inside the object or on a face it is moving across. Hidden objects are passed over. An object of type 3 or of $0A up gives its number at IX and A = 1 at once; another's number is kept, and given at IX with A = 1 if no object stops it. No object met gives A = 0."
  },
  {
   "address": 42439,
   "type": "line",
   "text": "One list: B objects from IY."
  },
  {
   "address": 42574,
   "type": "line",
   "text": "The height. The x test here takes A as it is, whichever of the two values it holds, where the other tests take D."
  },
  {
   "address": 42702,
   "type": "line",
   "text": "Along z."
  },
  {
   "address": 42874,
   "type": "line",
   "text": "Makes the area's colours current ($886E-$8871 to $886A-$886D), resets every sensor's count to 2, paints the view window's attributes with the paper and ink at $886C and $886D, and sets the border."
  },
  {
   "address": 43011,
   "type": "line",
   "text": "Draws a line from ($8A0E, $8A0F) to ($8A10, $8A11) by Bresenham's method, each point flipped by plot. The longer of the two lengths ($8A12) steps every point and the shorter ($8A14) adds to a running error that starts at half the longer; the shorter axis steps when the error reaches the longer. The steps along x and y are at $8A16-$8A19. Every register is kept."
  },
  {
   "address": 43194,
   "type": "line",
   "text": "Finds object $8916 of area A, or with A = 0 of the area the probe is in (the shared list at $87A5 first, then the area's own at ($8864)). The areas are found through the table of offsets at ($8914), $CF3E of them, from ($8912); an area's objects start $19 bytes into it. Gives IX at the object and A = 0, or A = 1 when there is none."
  },
  {
   "address": 43302,
   "type": "line",
   "text": "Flips the pixel at x = C - 1 on row B of the screen rows listed at ($8A1B). Every register is kept."
  },
  {
   "address": 43356,
   "type": "line",
   "text": "Carries out commands $15-$1E. $1E swaps what the keys do ($88AC: turn the probe, or move the crosshair), redraws the key panel and plays sound $13: going to the crosshair it shows the crosshair, going back it takes it off and shows it again only if the player wants it ($88AD). $15 shows or hides the crosshair ($88AD) while the keys turn the probe, and does nothing while they move the crosshair. Each pauses 9 frames when it acts. While the crosshair is shown ($88A2), $17-$1A move it a pixel within the view, and $16 fires the laser: four lines from the view's edges to the crosshair, sound 1, the lines rubbed out, then pick_object finds what was hit."
  },
  {
   "address": 43583,
   "type": "line",
   "text": "A short pause after a move of the crosshair, 1000 turns of a loop."
  },
  {
   "address": 43680,
   "type": "line",
   "text": "Flips the crosshair at ($88A0, $88A1): two pixels on each side of the centre with a pixel's gap, fewer where the view's edge comes first. BC and AF are kept."
  },
  {
   "address": 43795,
   "type": "line",
   "text": "dissolve's pointer to the row of the pattern for this pass, and the pattern: four rows of four offsets."
  },
  {
   "address": 43813,
   "type": "line",
   "text": "The view copied to the screen as copy_view does, but in four passes, each copying every fourth byte of every row from an offset that steps through dissolve_pattern row by row, so that the new view dissolves in. Then plays the sound queued in $8A1F. Every register is kept."
  },
  {
   "address": 43969,
   "type": "line",
   "text": "The security question's words, 128 records, of which the frame counter picks one: the word's length, the page + $40, the line, the word's place on the line + $20, then its letters, each stored as its code doubled less $80 (bit 6 of no account, so the case is lost). The pages run from 5 to 32 of the manual. These are records 0 to 61, pages 5 to 13; the first is page 5, line 1, word 11, SINGLE."
  },
  {
   "address": 44669,
   "type": "line",
   "text": "The security question's words, records 62 to 127, pages 13 to 32; the last is page 32, line 11, word 3, SHOOTING."
  },
  {
   "address": 45387,
   "type": "line",
   "text": "pick_object's working: the polygon being tested, the number of crossings found and the crossings ($B14E-$B152)."
  },
  {
   "address": 45395,
   "type": "line",
   "text": "Finds the object under the crosshair and puts its number in $8A69. The faces drawn are tested from the nearest (the end of the list at ($8A9D)) back. A face whose count has bit 7 set is taken at once. Otherwise each polygon whose corners lie on both sides of the crosshair in x and in y (or on its row or column) has its edges crossed with the crosshair's row: up to five crossings are kept at $B14E, each by div_24_16 and mul_16x8 from the edge's slope, and the polygon is hit when one is on the crosshair's column or they lie on both sides of it. A horizontal edge on the crosshair's row is a hit. Every register is kept."
  },
  {
   "address": 45855,
   "type": "line",
   "text": "The opcode run_script is running, bit 7 taken off."
  },
  {
   "address": 45856,
   "type": "line",
   "text": "Runs the script at IX, A bytes long. Each instruction is an opcode (bits 0-6) and its operands, as long as the opcode's entry in the table at $8939 says. An opcode with bit 7 set runs only when the script was started by a shot ($8BF1 set), one without only when it was not; the other kind is passed over. 1 adds to the score, 2 and $13 to the energy and the shield (at most 63; below 0 ends the game, $8BF2 = 3 or 1); 3-5 and $10 toggle, show, hide and destroy an object of this area, 6-8 and $11 one of another; $1E, $1F, $20 and $21 test whether an object is shown or hidden; 9, $0A, $14 and $0B add one to, take one from, set and test a variable at $887F; $0C, $0D, $1D and $0E set, clear, toggle and test a flag at $887B; $0F plays a sound and $1C leaves it for the view's copy when the view is to be redrawn; $12 goes to another area; $15 swaps the probe and the jet; $19 changes the area's colours; $1A redraws the view now; $1B pauses. A test that fails, or an opcode not listed, ends the script. Every register is kept."
  },
  {
   "address": 46876,
   "type": "line",
   "text": "Where write_number puts the digits that update_panel prints, up to 15 characters: the score, the step, the angle and the position are each written here first."
  },
  {
   "address": 46891,
   "type": "line",
   "text": "Redraws the parts of the console that the bits of $8920 and $8921 ask for: the score ($8921 bit 1) and the area's name (bit 6) while playing ($891F = 1); the message line (bit 5: the area cannot be drilled, a rig is in place, or the area is safe); the step (bit 0); the turn angle in degrees ($8920 bit 7); the position, each coordinate over the area's scale (bit 4); the heading's dial (bit 5, but not in areas 13 and 18) and the pitch's (bit 6), each needle drawn again where it was to take it off; the energy and shield bars ($8921 bits 2 and 4); the height, or J in the jet (bit 7); and the pictures of the keys' use ($8920 bit 0) and the vehicle (bit 3). Every register is kept."
  },
  {
   "address": 47420,
   "type": "line",
   "text": "Copies B rows of the picture at HL (a count of bytes a row, then the rows) to the screen addresses listed at IX."
  },
  {
   "address": 47441,
   "type": "line",
   "text": "The centre of a dial, x then y, from which needle draws its two lines."
  },
  {
   "address": 47443,
   "type": "line",
   "text": "A quarter-turn of a dial's edge, x and y a byte each for the 19 angles from 0 to 90 degrees, which needle turns into the right quarter."
  },
  {
   "address": 47481,
   "type": "line",
   "text": "Draws a dial's needle (by flipping pixels, so drawing it again takes it off) at angle A, in 72nds of a turn, on the panel whose screen rows IX lists: two lines from the dial's edge, $88D8 either side of the angle, to its centre ($B951, x then y), the edge's points read from the quarter-turn table at $B953 and turned into the right quarter. Every register is kept."
  },
  {
   "address": 47644,
   "type": "line",
   "text": "The bar's two lengths while bar moves it: where it is going ($BA1C, from H) and where it has got to ($BA1D, from L)."
  },
  {
   "address": 47646,
   "type": "line",
   "text": "Moves a bar of the console from length L to length H, a pixel at a time, six pixel rows deep. IX points at the bar's record: its screen address, then the cell its right end is in. Every register is kept."
  },
  {
   "address": 47778,
   "type": "line",
   "text": "Where the interrupt keeps draw_line's 15 bytes of work ($8A0E-$8A1C) while it draws a sensor's beam with it, so that a line the main program was drawing goes on as it was."
  },
  {
   "address": 47793,
   "type": "line",
   "text": "Starts the frame interrupt in IM 2: the table at $FE00-$FF00 filled with $FD, so that the interrupt goes to $FDFD, where a jump to $BAE6 is put. Clears the beam state ($8A21) and the clock's frame count ($88A3), and starts the frame counter $8A1D from the ROM's FRAMES ($5C78). Every register is kept."
  },
  {
   "address": 47846,
   "type": "line",
   "text": "The frame interrupt. Counts $8A1D on and $8FC2 down. While the game is on ($8BF2 = 0) it counts 50 frames to a second at $88A3 and then the clock ($88A4-$88AB) down a second: a minute costs a unit of energy (none left ends the game, $8BF2 = 3), and the clock running out ends it ($8BF2 = 2). Then, unless the main program is changing the sensors' list ($8A21 bit 2) with no beam on the screen (bit 0), each sensor's count goes round its period: one on the screen (state 1) draws its beam (four lines from it to a strip down the view's middle, by flipping pixels) at 1 and takes it off at 0; the border flashes in the area's colours; and at 0 it hits, with sound 2 and a unit of shield (none left ends the game, $8BF2 = 1). Bit 1 of $8A21 holds the beams off."
  },
  {
   "address": 48294,
   "type": "line",
   "text": "Inverts the text line whose record HL points at (a screen address, then the number of characters): its eight pixel rows, from the one above the address. Every register is kept."
  },
  {
   "address": 48330,
   "type": "line",
   "text": "Where enter_cell puts the number of an object it meets when $8A69 already holds one."
  },
  {
   "address": 48331,
   "type": "line",
   "text": "Keeps the probe's target ($88AF, $88B1, $88B3) at least $88D0 fine units from the faces of its cell that have an object behind them. Each axis on which the target lies within that distance of the cell's low or high face sets the direction bits of a collide test; when something is met the target is moved out to that distance on each of those axes. The object met goes to $8A69, or to $BCCA when $8A69 already holds one. IX, HL, BC and AF are kept."
  },
  {
   "address": 48500,
   "type": "line",
   "text": "Sets up the pointers into the game's data: the areas at $CF3E and their table of offsets at $D006, the colour patterns at $CF48, the font at $CDDC, the recorded demonstration ($8924, $8927) and the shared scripts ($8922). Then the probe's limits, the key repeat's delay and rate, the pass lamps' lit and dark colours ($8A65, $8A66, from $D004), the lamps' screen address ($CFA4 to $8BF3), the clock's digits, and whether the game starts in the jet, with that vehicle's shield and fuel."
  },
  {
   "address": 48664,
   "type": "line",
   "text": "Makes area $8862 current: its record found through the table at ($8914); its number of objects ($8863) and their list ($8864), its script ($8868), its name ($8866), its colours ($886E-$8871) and the centre and size of its gas field ($87A0-$87A2). The probe's scale in this area ($8779) sets its step ($8768), the most it may fall ($8777) and climb ($8778), its height ($8776) and the most it can stand up to ($8775). Then the rig is placed and the area's colours are asked for ($8910)."
  },
  {
   "address": 48884,
   "type": "line",
   "text": "The last strike's percentage and the gas tapped, and a script of one instruction (opcode 1, add to the score) whose three bytes drill fills."
  },
  {
   "address": 48890,
   "type": "line",
   "text": "Commands $28 (drill) and $2A (collect the rig), taken only when the key is pressed alone. Each needs an area that can have a rig (below $13), the probe rather than the jet, and energy of 5 or more ($8875), which each costs. Drilling places the rig in front of the probe, by its heading, on the floor or on top of a block, clear of every other object and the area's walls, and rates the strike by the distance from the area's gas field: 100 - distance x 100 / the field's size, as a percentage. 50 or more makes the sector safe ($877B = 3), and 18 safe sectors win the game. The score goes up by the percentage times the gas the rig taps times 10, the gas from the table at ($87A3), which the first strike of a game picks by the interrupt's frame count; collecting a rig takes that score back. A refusal flashes its reason on the message line."
  },
  {
   "address": 49753,
   "type": "line",
   "text": "Places the rig and redraws the whole view, as if the probe had moved, under the message at $8C90 for 50 frames, with sound 5. Gives BC = $8920 as it was."
  },
  {
   "address": 49818,
   "type": "line",
   "text": "Flashes the message at IX on the message line ($CFAD), inverted, for 50 frames."
  },
  {
   "address": 49839,
   "type": "line",
   "text": "The information screen's text. A record for print_text: the screen address ($C2AF, which info_screen sets for each line) and 26 characters a line ($C2B1). Then the lines, each 26 characters: SECTOR:, RIG STATUS:, GAS FOUND: XX000 CFT, % TAPPED: XXX %, GAS TAPPED: XXXXX CFT, TOTAL SECTORS: 18, SAFE SECTORS: XX, L-LOAD S-SAVE 1-ABORT and ANY OTHER KEY-CONTINUE, whose X's info_screen writes the figures over. Last, the words it fills in: AREA, SECTOR, NOT REQUIRED, UNPOSITIONED, POSITIONED, NONE and ZERO."
  },
  {
   "address": 50130,
   "type": "line",
   "text": "info_screen's work for a save or a load: the key pressed, S or L ($C3D2); the name's length and where it is ($C3D3, $C3D4); and, for the save, the state's length ($C3D6), where the header is built after it ($C3D8) and the state's checksum ($C3DA), which the header carries."
  },
  {
   "address": 50140,
   "type": "line",
   "text": "The information screen, with its key pressed alone. Once no beam is on the screen, the game is held ($8BF2 = 6) and the view is cleared under ink 6, with the sector's name, whether it can be drilled, its rig's state and the gas (struck, in thousands of cubic feet, and the percentage of the field tapped; or the gas in hand), and the safe sectors. A key then: S or L, pressed alone, saves or loads the game under a name typed (filename) and redraws the view; 1 abandons the game ($8BF2 stays 6); any other dissolves the view back in. The save is the 333 bytes from $8762 and each object's type byte, with a header (a $1B, the name, the length, the game's number at $CF3F and the checksum) saved first, both through the ROM's SA-BYTES; the load takes headers through LD-BYTES until one matches (the name, or any with none typed), then the state, checked by its checksum, and asks the security question again. SPACE stops either."
  },
  {
   "address": 51136,
   "type": "line",
   "text": "info_screen's way out. After a save, or a load that failed: the border back, a second's wait (50 frames on $8FC2). A load that worked comes in after the security question ($C7BB). Either way the view and the console are drawn whole again, the view dissolving in ($C7D1). From the key pressed at the screen ($C7EB): 1 leaves the game held ($8BF2 stays 6), so it ends; any other key puts the area's colours back, dissolves the view in, puts back the crosshair if it was shown, and waits out 11 frames. Then the game is on again ($8BF2 = 0) with no beam on the screen ($8A21 = 0)."
  },
  {
   "address": 51220,
   "type": "line",
   "text": "The checksum of HL bytes at DE: the even bytes XORed into B, the odd ones into C, then both shifted two bits to the left as a pair (SLA B, RL C, RL B, RL C): B's top two bits go to C's bottom two, C's top bit to B's bottom one, and C's bit 6 is lost."
  },
  {
   "address": 51250,
   "type": "line",
   "text": "A text record and its text that no instruction found uses: a screen address of 0 and 17 characters, then TAPE OR DISC ?. The Spectrum game never asks it."
  },
  {
   "address": 51253,
   "type": "line",
   "text": "filename's line: its screen address ($C835, which filename sets to the view's 17th row) and 24 characters, then FILENAME : and the 12 characters of the name ($C855) that the keys type; the 12 spaces at $C861 clear the name first."
  },
  {
   "address": 51309,
   "type": "line",
   "text": "Clears the view and takes a file name of up to 12 characters on its 17th row (space to Z; CAPS SHIFT with 0 rubs out; ENTER ends it), the keys repeating after 35 frames and then every 5. Gives A = its length and HL = $C855, where it is."
  },
  {
   "address": 51485,
   "type": "line",
   "text": "The control options' screen: seven records for print_text, a screen address and a count each ($C91D-$C931), then their texts: CONTROL OPTIONS, 1: KEYBOARD, 2: SINCLAIR JOYSTICK, 3: KEMPSTON JOYSTICK, 4: CURSOR JOYSTICK, ENTER: BEGIN MISSION, and COPYRIGHT 1987 INCENTIVE."
  },
  {
   "address": 51654,
   "type": "line",
   "text": "The control options over the view, cleared under ink 6: the chosen one ($8FC5) inverted, 1-4 to choose (keyboard, Sinclair joystick, Kempston joystick, cursor joystick), ENTER to begin. The keys for the four directions are put in the key table at $8FC8: 9, 8, 6, 7 for the Sinclair joystick, the cursor keys 7, 6, 5, 8 otherwise. Every register and the flags are kept."
  },
  {
   "address": 51878,
   "type": "line",
   "text": "The security question's screen. The count of wrong answers ($CAA6, three of which reset the machine); a record for print_text, the screen address ($CAA7) and 26 characters a line; then the lines: DRILLER FEDERATION, SECURTIY INPUT STATION (so spelt), NAME : LESLEIGH SKERRIT, MISSION : CLASSIFIED, RE : FEDERATION BRIEFING, PAGE, LINE and ENTER WORD. The question writes the page, line and word's numbers into the lines at $CB38, $CB52 and $CB6C, and the word typed into $CB6F."
  },
  {
   "address": 52090,
   "type": "line",
   "text": "The security question: a page, line and word of the manual, picked by the frame counter ($8A1D, 0-127) from the table at $ABC1 (each record: the word's length, the page + $40, the line, the word + $20, then the letters, each stored as its code doubled less $80, bit 6 of no account), and the word typed (A to Z, at most ten letters; CAPS SHIFT with 0 rubs out). Asking spoils the view routine's first instruction ($6B12 = $DD); the right word mends it (PUSH IX) and returns. A wrong word asks again, from the counter as it then stands; the third wipes memory and resets the machine."
  },
  {
   "address": 52480,
   "type": "line",
   "text": "Three wrong answers: memory from $5CBC to $CD09 and from $CD1E to $FFFE cleared, and a jump to $0000."
  },
  {
   "address": 52510,
   "type": "line",
   "text": "Clears the rows of the view's buffer but the top one."
  },
  {
   "address": 52539,
   "type": "line",
   "text": "Puts the five objects of the rig in the shared list ($87A5, $87C0, $87CE, $87DE and $87EE) where the area's rig stands ($882C, three bytes an area) and shows them, the last two only when it struck gas; hides them all in an area with no rig or none to drill ($13 up). Bit 6 of $887E says whether the area can have a rig. Every register is kept."
  },
  {
   "address": 52700,
   "type": "line",
   "text": "The game's font: 59 characters, from space ($20) to Z, six bytes each, the six pixel rows of a cell from the top. $8A81 points here, and print_text draws every text on the screen with it."
  },
  {
   "address": 53054,
   "type": "line",
   "text": "The game's data begins here, and the offsets in the table at $D006 and at $CF84 count from here. The count of areas (29); the game's number, which a saved position's header carries and a load checks ($CF3F, $2D84); the first area (1) and the entrance the probe comes in at ($CF42, $13); a byte no instruction found reads ($CF43); and the energy and shield the jet starts with ($CF44, $CF45: 29 and 34) and the probe ($CF46, $CF47: 48 and 50)."
  },
  {
   "address": 53064,
   "type": "line",
   "text": "The fill patterns of the 15 colours a face can have, four bytes each, one for each pixel row modulo 4, colour 1 first: 1 is empty, 2 solid, and the rest are dithers and stripes of the view's ink on its paper."
  },
  {
   "address": 53124,
   "type": "line",
   "text": "Where the demonstration ($CF84, $0373: $D2B1) and the shared scripts ($CF86, $010E: $D04C) are, each from $CF3E."
  },
  {
   "address": 53128,
   "type": "line",
   "text": "Seven bytes no instruction found reads: $68, $34, $9B, 0, 0, 0 and $2B. The first two are the view's centre, as at $88D9."
  },
  {
   "address": 53135,
   "type": "line",
   "text": "The screen address of the view window's top left corner ($4043: character row 2, column 3), from which set_area_colours works out where to paint the window's attributes."
  },
  {
   "address": 53137,
   "type": "line",
   "text": "Ten bytes no instruction found reads."
  },
  {
   "address": 53147,
   "type": "line",
   "text": "Where the console's pictures are, a screen address and a count of rows each: the heading's dial ($CF9B: $5047, 24 rows), the pitch's ($CF9E: $5055, 24), the vehicle ($CFA1: $500D, 14), the pass lamps ($CFA4: $5A7A, which init_game_data copies to $8BF3 with the byte after), and the keys' use ($CFA7: $5007, 13). update_panel reads the vehicle's count ($CFA3) and the keys' ($CFA9); the rows themselves come from the tables at $8DE0-$8E77."
  },
  {
   "address": 53162,
   "type": "line",
   "text": "Where the console's texts go, a screen address and a count of characters each: the score ($CFAA, 7), the message line ($CFAD, 14), the step ($CFB0, 3), the turn angle ($CFB3, 2), the position, x, y and z ($CFB6, $CFB9, $CFBC, 4 each), the area's name ($CFBF, 12), two no instruction found uses ($CFC2: $4000, 32; $CFC5: $517C, 1), the clock ($CFC8, 8), the height, or J in the jet ($CFCB, 1), the energy's and the shield's bars ($CFCE, $CFD1), one more unused ($CFD4: $40A4, 11), and the two tape message lines ($CFD7, $CFDA, 20 each). A 0 follows."
  },
  {
   "address": 53214,
   "type": "line",
   "text": "C 1987, then 0, 0, $40 and 0, then INCENTIVE and a 0: text no instruction found reads."
  },
  {
   "address": 53234,
   "type": "line",
   "text": "The game's starting values: the clock, 04:00:00, as the console prints it ($CFF2); the most the probe may fall ($CFFA, 2) and climb ($CFFB, 2), its standing height ($CFFC, 2) and the most it can stand up to ($CFFD, 4), all in cells; a byte no instruction found reads ($CFFE); the vehicle it starts in ($CFFF, 0: the probe); the walking step's place in the table at $88BF ($D000, 7) and the turn step's in the table at $88CA ($D001, 2); the delay and the rate of a held key's repeat in play ($D002, $D003, both 0, so a held key repeats at once); and the pass lamps' two attributes ($D004, $D005)."
  },
  {
   "address": 53254,
   "type": "line",
   "text": "Where each of the 29 areas' records is, a word each from $CF3E, in the order load_area searches them for the area's number."
  },
  {
   "address": 53312,
   "type": "line",
   "text": "Twelve bytes of 0 after the table, which nothing reads."
  },
  {
   "address": 53324,
   "type": "line",
   "text": "The shared scripts, which run_scripts runs after every pass that moved anything, in every area: the count (5), then each script's length and its bytes."
  },
  {
   "address": 53426,
   "type": "line",
   "text": "Area 1, AMETHYST: the record load_area reads. Its first byte is $10; then the count of objects (32), the area's number, where its scripts are (+$01FE, $D2B0), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 100, z 100, of size 30. Its name follows, 12 characters, then its objects from $D0CB, 13 cuboids, 9 rectangles, 2 pyramids and prisms, 2 lines and flat polygons and 6 objects of type 0, never drawn, 9 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 53937,
   "type": "line",
   "text": "The demonstration, a recording of commands that take_commands plays back one a pass: a byte with bit 7 set gives the next command that many times, any other is a command once, and 0 ends it. It begins with $7F, which no key gives and which does nothing. Then the probe walks and turns, drills, backs off and walks on, looks up, takes the crosshair down and across the view in a staircase, firing as it goes, looks down again, and walks off."
  },
  {
   "address": 54055,
   "type": "line",
   "text": "97 bytes of 0 after the demonstration, room for a longer one, which nothing reads."
  },
  {
   "address": 54152,
   "type": "line",
   "text": "INCENTIVE SOFTWARE LTD COPYRIGHT 1987, written backwards, then three bytes of 0. No instruction reads it."
  },
  {
   "address": 54193,
   "type": "line",
   "text": "Area 2, LAPIS LAZULI: the record load_area reads. Its first byte is $10; then the count of objects (25), the area's number, where its scripts are (+$018F, $D540), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 64, z 64, of size 127. Its name follows, 12 characters, then its objects from $D3CA, 11 cuboids, 6 rectangles, 5 pyramids and prisms and 3 objects of type 0, never drawn, 3 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 54593,
   "type": "line",
   "text": "Area 3, EMERALD: the record load_area reads. Its first byte is $10; then the count of objects (35), the area's number, where its scripts are (+$0205, $D746), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 64, z 64, of size 11. Its name follows, 12 characters, then its objects from $D55A, 13 cuboids, 8 rectangles, 6 pyramids and prisms, 3 sensors and 5 objects of type 0, never drawn, 7 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 55111,
   "type": "line",
   "text": "Area 8, TOPAZ: the record load_area reads. Its first byte is $10; then the count of objects (36), the area's number, where its scripts are (+$024D, $D994), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 47, z 15, of size 127. Its name follows, 12 characters, then its objects from $D760, 16 cuboids, 7 rectangles, 5 pyramids and prisms, 4 sensors and 4 objects of type 0, never drawn, 13 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 55701,
   "type": "line",
   "text": "Area 14, OBSIDIAN: the record load_area reads. Its first byte is $10; then the count of objects (36), the area's number, where its scripts are (+$0240, $DBD5), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink magenta), and its gas field, centred at x 104, z 104, of size 127. Its name follows, 12 characters, then its objects from $D9AE, 14 cuboids, 9 rectangles, 7 pyramids and prisms, 2 sensors, 1 line or flat polygon and 3 objects of type 0, never drawn, 9 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 56301,
   "type": "line",
   "text": "Area 15, BASALT: the record load_area reads. Its first byte is $01; then the count of objects (23), the area's number, where its scripts are (+$017F, $DD6C), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink magenta), and its gas field, centred at x 20, z 35, of size 24. Its name follows, 12 characters, then its objects from $DC06, 9 cuboids, 6 rectangles, 5 pyramids and prisms, 1 line or flat polygon and 2 objects of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 56685,
   "type": "line",
   "text": "Area 16, OCHRE: the record load_area reads. Its first byte is $01; then the count of objects (19), the area's number, where its scripts are (+$0149, $DEB6), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink magenta), and its gas field, centred at x 22, z 105, of size 45. Its name follows, 12 characters, then its objects from $DD86, 8 cuboids, 4 rectangles, 3 sensors, 3 lines and flat polygons and 1 object of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 57015,
   "type": "line",
   "text": "Area 17, GRAPHITE: the record load_area reads. Its first byte is $01; then the count of objects (23), the area's number, where its scripts are (+$0163, $E01A), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink magenta), and its gas field, centred at x 20, z 99, of size 24. Its name follows, 12 characters, then its objects from $DED0, 11 cuboids, 10 rectangles, 1 pyramid or prism and 1 object of type 0, never drawn, 5 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 57371,
   "type": "line",
   "text": "Area 18, TRACHYTE: the record load_area reads. Its first byte is $10; then the count of objects (17), the area's number, where its scripts are (+$012B, $E146), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink red), and its gas field, centred at x 64, z 108, of size 6. Its name follows, 12 characters, then its objects from $E034, 10 cuboids, 1 rectangle, 4 pyramids and prisms, 1 line or flat polygon and 1 object of type 0, never drawn, 3 of them hidden at the start, each as long as its byte +8 says. Last, its 2 scripts: a count, then each script's length and its bytes."
  },
  {
   "address": 57750,
   "type": "line",
   "text": "Area 19, STORES: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (22), the area's number, where its scripts are (+$01BD, $E353), its scale (4: the probe's step and heights here are 4 times the game's), its colours (border black, sound 2's flash white, the view's paper black (bright) and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E1AF, 6 cuboids, 1 rectangle, 12 pyramids and prisms, 2 lines and flat polygons and 1 object of type 0, never drawn, 3 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 58196,
   "type": "line",
   "text": "Area 20, STORES: the record load_area reads. Its first byte is $83; then the count of objects (16), the area's number, where its scripts are (+$010A, $E45E), its scale (4: the probe's step and heights here are 4 times the game's), its colours (border black, sound 2's flash blue, the view's paper black (bright) and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E36D, 7 cuboids, 1 rectangle, 5 pyramids and prisms, 1 sensor and 2 objects of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 58464,
   "type": "line",
   "text": "Area 21, K2-COMPLEX: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (16), the area's number, where its scripts are (+$0100, $E560), its scale (2: the probe's step and heights here are 2 times the game's), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink magenta), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E479, 9 cuboids, 2 rectangles, 3 pyramids and prisms and 2 objects of type 0, never drawn, 3 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 58721,
   "type": "line",
   "text": "Area 22, K1-COMPLEX: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (14), the area's number, where its scripts are (+$00CD, $E62E), its scale (2: the probe's step and heights here are 2 times the game's), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink magenta), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E57A, 11 cuboids, 2 rectangles and 1 object of type 0, never drawn, 1 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 58968,
   "type": "line",
   "text": "Area 23, LINKER: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (8), the area's number, where its scripts are (+$0079, $E6D1), its scale (4: the probe's step and heights here are 4 times the game's), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink green), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E671, 6 cuboids and 2 objects of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 59090,
   "type": "line",
   "text": "Area 31, UNKNOWN AREA: the record load_area reads. Its first byte is $83; then the count of objects (13), the area's number, where its scripts are (+$00BB, $E78D), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink blue), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $E6EB, 11 cuboids, 1 rectangle and 1 object of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 59278,
   "type": "line",
   "text": "Area 5, RUBY: the record load_area reads. Its first byte is $10; then the count of objects (20), the area's number, where its scripts are (+$012D, $E8BB), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 64, z 40, of size 48. Its name follows, 12 characters, then its objects from $E7A7, 7 cuboids, 5 rectangles, 2 pyramids and prisms, 1 sensor and 5 objects of type 0, never drawn, 8 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 59580,
   "type": "line",
   "text": "Area 4, MALACHITE: the record load_area reads. Its first byte is $01; then the count of objects (31), the area's number, where its scripts are (+$01E9, $EAA5), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 93, z 84, of size 24. Its name follows, 12 characters, then its objects from $E8D5, 14 cuboids, 7 rectangles, 5 pyramids and prisms, 2 sensors and 3 objects of type 0, never drawn, 3 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 60070,
   "type": "line",
   "text": "Area 6, AQUAMARINE: the record load_area reads. Its first byte is $10; then the count of objects (27), the area's number, where its scripts are (+$01BC, $EC62), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 80, z 39, of size 10. Its name follows, 12 characters, then its objects from $EABF, 7 cuboids, 8 rectangles, 4 pyramids and prisms, 4 lines and flat polygons and 4 objects of type 0, never drawn, 8 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 60515,
   "type": "line",
   "text": "Area 7, BERYL: the record load_area reads. Its first byte is $10; then the count of objects (32), the area's number, where its scripts are (+$01D2, $EE35), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 112, z 70, of size 48. Its name follows, 12 characters, then its objects from $EC7C, 11 cuboids, 9 rectangles, 2 pyramids and prisms, 1 sensor, 3 lines and flat polygons and 6 objects of type 0, never drawn, 10 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 60991,
   "type": "line",
   "text": "Area 9, NICCOLITE: the record load_area reads. Its first byte is $10; then the count of objects (30), the area's number, where its scripts are (+$0204, $F043), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and its gas field, centred at x 8, z 32, of size 2. Its name follows, 12 characters, then its objects from $EE58, 9 cuboids, 9 rectangles, 5 pyramids and prisms, 3 sensors and 4 lines and flat polygons, 5 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 61508,
   "type": "line",
   "text": "Area 10, ALABASTER: the record load_area reads. Its first byte is $10; then the count of objects (32), the area's number, where its scripts are (+$01D5, $F219), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and its gas field, centred at x 64, z 64, of size 20. Its name follows, 12 characters, then its objects from $F05D, 19 cuboids, 12 rectangles and 1 object of type 0, never drawn, 10 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 61978,
   "type": "line",
   "text": "Area 11, OPAL: the record load_area reads. Its first byte is $01; then the count of objects (25), the area's number, where its scripts are (+$0163, $F37D), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and its gas field, centred at x 121, z 121, of size 6. Its name follows, 12 characters, then its objects from $F233, 6 cuboids, 16 rectangles, 2 lines and flat polygons and 1 object of type 0, never drawn, 6 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 62334,
   "type": "line",
   "text": "Area 12, QUARTZ: the record load_area reads. Its first byte is $04; then the count of objects (28), the area's number, where its scripts are (+$019A, $F518), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and its gas field, centred at x 37, z 28, of size 32. Its name follows, 12 characters, then its objects from $F397, 12 cuboids, 12 rectangles, 1 pyramid or prism, 1 sensor, 1 line or flat polygon and 1 object of type 0, never drawn, 8 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 62745,
   "type": "line",
   "text": "Area 13, DIAMOND: the record load_area reads. Its first byte is $10; then the count of objects (20), the area's number, where its scripts are (+$0173, $F68C), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink white), and its gas field, centred at x 64, z 48, of size 32. Its name follows, 12 characters, then its objects from $F532, 8 cuboids, 2 rectangles, 6 pyramids and prisms, 2 sensors, 1 line or flat polygon and 1 object of type 0, never drawn, 1 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 63117,
   "type": "line",
   "text": "Area 27, KETAR HANGAR: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (33), the area's number, where its scripts are (+$01EB, $F878), its scale (4: the probe's step and heights here are 4 times the game's), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $F6A6, 5 cuboids, 10 rectangles, 15 pyramids and prisms and 3 objects of type 0, never drawn, 13 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 63657,
   "type": "line",
   "text": "Area 25, K3-COMPLEX: the record load_area reads. Its first byte is $00, so the view is not cleared before each picture; then the count of objects (17), the area's number, where its scripts are (+$0146, $F9EF), its scale (4: the probe's step and heights here are 4 times the game's), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $F8C2, 6 cuboids, 4 rectangles, 6 lines and flat polygons and 1 object of type 0, never drawn, 7 of them hidden at the start, each as long as its byte +8 says. Last, its 4 scripts: a count, then each script's length and its bytes."
  },
  {
   "address": 64032,
   "type": "line",
   "text": "Area 32, MITRAL: the record load_area reads. Its first byte is $02; then the count of objects (7), the area's number, where its scripts are (+$007A, $FA9A), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink red), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $FA39, 2 cuboids, 1 pyramid or prism, 1 sensor, 1 line or flat polygon and 2 objects of type 0, never drawn, 2 of them hidden at the start, each as long as its byte +8 says. Last, its script: a count, then each script's length and its bytes."
  },
  {
   "address": 64158,
   "type": "line",
   "text": "Area 127, \"0 CLEARED\", whose digit the game over replaces with the count of safe sectors: the record load_area reads. Its first byte is $30; then the count of objects (15), the area's number, where its scripts are (+$00F3, $FB91), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black (bright) and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $FAB7, 9 cuboids, 1 pyramid or prism, 4 lines and flat polygons and 1 object of type 0, never drawn, 1 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 64402,
   "type": "line",
   "text": "Area 28, K4-COMPLEX: the record load_area reads. Its first byte is $83; then the count of objects (17), the area's number, where its scripts are (+$012F, $FCC1), its scale (1), its colours (border black, sound 2's flash yellow, the view's paper black and ink yellow), and three bytes of 0 where a sector has its gas field: it is not a sector, and no rig can be placed in it. Its name follows, 12 characters, then its objects from $FBAB, 7 cuboids, 1 rectangle, 4 pyramids and prisms, 4 sensors and 1 object of type 0, never drawn, 1 of them hidden at the start, each as long as its byte +8 says. Last, the count of its own scripts, 0: it has none."
  },
  {
   "address": 64706,
   "type": "line",
   "text": "294 bytes of 0 after the last area's record, to the end of the game's block on the tape at $FDE7. No instruction reads them."
  }
 ]
}