{
 "schema": 1,
 "platform": "c64",
 "game": "the-fourth-protocol",
 "part": "title",
 "build": "Bantam Software's US disk release, 1985 (C64 Preservation Project G64, marked good); five parts: the resident disk operating system and episode loader, the title and episode menu, and the three episodes",
 "source": "regenerator2000 live",
 "regions": {
  "exclude": [
   [
    256,
    511,
    "stack"
   ],
   [
    53248,
    57343,
    "I/O and colour RAM"
   ],
   [
    0,
    16383,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    16896,
    19455,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    20480,
    24575,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    32768,
    49151,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    53248,
    65535,
    "Resident: the disk operating system and the episode loader"
   ]
  ],
  "extra": [],
  "edges": [
   0,
   256,
   512,
   1024,
   2048,
   4096,
   16384,
   32768,
   40960,
   49152,
   53248,
   57344
  ],
  "elsewhere": [
   [
    0,
    16383,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    16896,
    19455,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    20480,
    24575,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    32768,
    49151,
    "Resident: the disk operating system and the episode loader"
   ],
   [
    53248,
    65535,
    "Resident: the disk operating system and the episode loader"
   ]
  ]
 },
 "blocks": [
  {
   "start": 16384,
   "end": 16390,
   "type": "Code"
  },
  {
   "start": 16391,
   "end": 16392,
   "type": "Address"
  },
  {
   "start": 16393,
   "end": 16399,
   "type": "Code"
  },
  {
   "start": 16400,
   "end": 16401,
   "type": "Address"
  },
  {
   "start": 16402,
   "end": 16408,
   "type": "Code"
  },
  {
   "start": 16409,
   "end": 16410,
   "type": "Address"
  },
  {
   "start": 16411,
   "end": 16534,
   "type": "Code"
  },
  {
   "start": 16535,
   "end": 16542,
   "type": "Byte"
  },
  {
   "start": 16543,
   "end": 16545,
   "type": "Code"
  },
  {
   "start": 16546,
   "end": 16632,
   "type": "PETSCII Text"
  },
  {
   "start": 16633,
   "end": 16637,
   "type": "Code"
  },
  {
   "start": 16638,
   "end": 16640,
   "type": "Byte"
  },
  {
   "start": 16641,
   "end": 16666,
   "type": "Code"
  },
  {
   "start": 16667,
   "end": 16669,
   "type": "Byte"
  },
  {
   "start": 16670,
   "end": 16694,
   "type": "PETSCII Text"
  },
  {
   "start": 16695,
   "end": 16846,
   "type": "Code"
  },
  {
   "start": 16847,
   "end": 16895,
   "type": "Byte"
  },
  {
   "start": 19456,
   "end": 20479,
   "type": "Byte"
  },
  {
   "start": 24576,
   "end": 32767,
   "type": "Byte"
  },
  {
   "start": 49152,
   "end": 52468,
   "type": "Byte"
  },
  {
   "start": 52469,
   "end": 53031,
   "type": "Code"
  },
  {
   "start": 53032,
   "end": 53247,
   "type": "Byte"
  }
 ],
 "symbols": [
  {
   "address": 16384,
   "name": "title_program",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 16389,
   "name": "j_4005",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 16494,
   "name": "b_406E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16503,
   "name": "j_4077",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 16508,
   "name": "b_407C",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16525,
   "name": "b_408D",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16543,
   "name": "episode_menu",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 16659,
   "name": "b_4113",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16667,
   "name": "episode_answer",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 16670,
   "name": "title_file_names",
   "type": "AbsoluteAddress",
   "kind": "user"
  },
  {
   "address": 16678,
   "name": "a_4126",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 16687,
   "name": "a_412F",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 16695,
   "name": "start_tune",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16703,
   "name": "title_irq",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 16727,
   "name": "raster_setup",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16759,
   "name": "stop_interrupts",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16785,
   "name": "wait_for_space",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16801,
   "name": "b_41A1",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16819,
   "name": "b_41B3",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 16830,
   "name": "copy_pages",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 16832,
   "name": "b_41C0",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 19456,
   "name": "title_colours",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 24576,
   "name": "title_bitmap",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 25536,
   "name": "title_rows_3",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 26496,
   "name": "title_rows_6",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 27456,
   "name": "title_rows_9",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 28416,
   "name": "title_rows_12",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 29376,
   "name": "title_rows_15",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 30336,
   "name": "title_rows_18",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 31296,
   "name": "title_rows_21",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32256,
   "name": "title_rows_24",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 32576,
   "name": "title_bitmap_tail",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 49152,
   "name": "music_unused_start",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 50057,
   "name": "tune_stream",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 51081,
   "name": "tune_middle",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52105,
   "name": "tune_last_part",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52464,
   "name": "tune_count",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52465,
   "name": "tune_waves",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52466,
   "name": "a_CCF2",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 52467,
   "name": "a_CCF3",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 52468,
   "name": "tune_step_length",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52469,
   "name": "tune_play",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52480,
   "name": "tune_next_command",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 52486,
   "name": "b_CD06",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 52491,
   "name": "tune_dispatch",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52492,
   "name": "a_CD0C",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 52494,
   "name": "cmd_voice1",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52503,
   "name": "cmd_voice2",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52512,
   "name": "cmd_voice3",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52521,
   "name": "cmd_voices12",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52536,
   "name": "cmd_voices123",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52557,
   "name": "cmd_count",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52563,
   "name": "cmd_wait",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 52571,
   "name": "cmd_envelopes",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52610,
   "name": "cmd_loop",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52621,
   "name": "cmd_pulse",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52660,
   "name": "cmd_stop",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52664,
   "name": "b_CDB8",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 52683,
   "name": "cmd_step_length",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52692,
   "name": "cmd_waveforms",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52713,
   "name": "cmd_filter",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52734,
   "name": "gate_voice1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52744,
   "name": "gate_voice2",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52754,
   "name": "gate_voice3",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52764,
   "name": "tune_byte",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52770,
   "name": "b_CE22",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 52773,
   "name": "freq_voice1",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52786,
   "name": "freq_voice2",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52818,
   "name": "r_CE52",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 52819,
   "name": "freq_voice3",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52851,
   "name": "r_CE73",
   "type": "Return",
   "kind": "auto"
  },
  {
   "address": 52852,
   "name": "tune_init",
   "type": "Subroutine",
   "kind": "user"
  },
  {
   "address": 52862,
   "name": "b_CE7E",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 52886,
   "name": "unused_irq_install",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52898,
   "name": "warble2_up",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 52920,
   "name": "warble2_down",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52942,
   "name": "warble3_up",
   "type": "UserDefined",
   "kind": "user"
  },
  {
   "address": 52964,
   "name": "warble3_down",
   "type": "Branch",
   "kind": "user"
  },
  {
   "address": 52986,
   "name": "tune_effects",
   "type": "Jump",
   "kind": "user"
  },
  {
   "address": 52993,
   "name": "a_CF01",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 53001,
   "name": "a_CF09",
   "type": "AbsoluteAddress",
   "kind": "auto"
  },
  {
   "address": 53002,
   "name": "j_CF0A",
   "type": "Jump",
   "kind": "auto"
  },
  {
   "address": 53029,
   "name": "b_CF25",
   "type": "Branch",
   "kind": "auto"
  },
  {
   "address": 53032,
   "name": "music_unused_end",
   "type": "UserDefined",
   "kind": "user"
  }
 ],
 "comments": [
  {
   "address": 16384,
   "type": "line",
   "text": "The title program, loaded and called at $4000 by the episode loader's run_title. Loads the picture's bitmap (XXXTITLE, to $6000), its colours (XXXCOLMAP, to $4C00) and the tune (XXXMUSIC, to $C000) with the OS's load_file, the name's length in X and its address in the two bytes after each call; waits five seconds; shows the picture and plays the tune until SPACE is pressed; then asks for an episode and returns its number, 0-2, in A."
  },
  {
   "address": 16391,
   "type": "line",
   "text": "load_file's argument: the name XXXTITLE (title_file_names)."
  },
  {
   "address": 16393,
   "type": "line",
   "text": "Loads XXXCOLMAP, nine characters, to $4C00."
  },
  {
   "address": 16400,
   "type": "line",
   "text": "The name XXXCOLMAP."
  },
  {
   "address": 16402,
   "type": "line",
   "text": "Loads XXXMUSIC, eight characters, to $C000."
  },
  {
   "address": 16409,
   "type": "line",
   "text": "The name XXXMUSIC."
  },
  {
   "address": 16411,
   "type": "line",
   "text": "Waits up to five seconds, or until SPACE (wait_for_space with A = 5)."
  },
  {
   "address": 16416,
   "type": "line",
   "text": "A black border, and the video chip switched to bank 1 ($4000-$7FFF) through CIA 2's port A: with $D018 at $38 it now shows the picture where it was loaded, colours at $4C00 and bitmap at $6000, while the copy below is made."
  },
  {
   "address": 16440,
   "type": "line",
   "text": "Copies the bitmap from $6000-$7FFF to the OS's bitmap at $2000 (32 pages), then the colours from $4C00-$4FFF to screen memory at $0C00 (4 pages), with copy_pages."
  },
  {
   "address": 16482,
   "type": "line",
   "text": "Puts the video bank back to bank 0, which now holds the same picture, and turns the display on (OS function $0D, screen_on)."
  },
  {
   "address": 16491,
   "type": "line",
   "text": "Starts the tune (start_tune), then waits for SPACE: wait_for_space returns with the carry clear after 20 seconds and is simply called again."
  },
  {
   "address": 16501,
   "type": "line",
   "text": "SPACE: the interrupts off (stop_interrupts), which stops the tune, and the sound chip's 25 registers set to zero."
  },
  {
   "address": 16514,
   "type": "line",
   "text": "Clears $3E00-$3EFF, the left 32 cells of the bitmap's bottom row, where the picture says PRESS <SPACE> TO CONTINUE."
  },
  {
   "address": 16530,
   "type": "line",
   "text": "Opens a window that keeps what it covers (OS function $11) for the episode menu."
  },
  {
   "address": 16535,
   "type": "line",
   "text": "open_window_saved's eight arguments: x 10, y 13, width 20, height 8 (cells, inside the frame), pattern $FF and $00 (solid) in colour $10 (white), and a spare byte."
  },
  {
   "address": 16543,
   "type": "line",
   "text": "Prints the menu in the window (the OS's print-inline-string call, os_print_string): THE EPISODES, 1) NATO DOCUMENTS, 2) THE BOMB, 3) THE SAS ASSAULT, SELECT NUMBER:. Code 13 ends each line."
  },
  {
   "address": 16546,
   "type": "line",
   "text": "The menu's text, zero-terminated: four spaces and THE EPISODES, a blank line, the three episodes, two blank lines and SELECT NUMBER:."
  },
  {
   "address": 16633,
   "type": "line",
   "text": "Reads the answer (OS function $3F, input_line) into episode_answer: a buffer of two bytes, so one character and RETURN."
  },
  {
   "address": 16638,
   "type": "line",
   "text": "input_line's three arguments: the buffer's address, episode_answer, and its length, 2."
  },
  {
   "address": 16641,
   "type": "line",
   "text": "The typed character less \"1\": 0, 1 or 2 is accepted. Closes the menu's window (OS function $12, close_window_here), which puts the picture back under it, and returns the episode in A."
  },
  {
   "address": 16659,
   "type": "line",
   "text": "Anything else: control code 12 (os_print_char) clears the window, and the menu is printed again."
  },
  {
   "address": 16667,
   "type": "line",
   "text": "input_line's buffer for the episode typed: the character and its RETURN, and a spare byte."
  },
  {
   "address": 16670,
   "type": "line",
   "text": "The three file names, with no terminators: XXXTITLE (8), XXXCOLMAP (9), XXXMUSIC (8)."
  },
  {
   "address": 16678,
   "type": "line",
   "text": "The name XXXCOLMAP, nine characters."
  },
  {
   "address": 16687,
   "type": "line",
   "text": "The name XXXMUSIC, eight characters."
  },
  {
   "address": 16695,
   "type": "line",
   "text": "Starts the tune: sets the raster interrupt up (raster_setup), resets the tune player (tune_init) and enables interrupts."
  },
  {
   "address": 16703,
   "type": "line",
   "text": "The title's interrupt handler, at $FFFE while the tune plays: once a frame, at raster line 252, calls tune_play, acknowledges the raster interrupt and sets the line again."
  },
  {
   "address": 16727,
   "type": "line",
   "text": "Turns every interrupt off (stop_interrupts), sets the raster compare to line 252 (bit 8 of $D011 cleared), enables the raster interrupt and points the interrupt vector at $FFFE to title_irq."
  },
  {
   "address": 16759,
   "type": "line",
   "text": "Masks interrupts, turns off both CIAs' interrupts ($7F to $DC0D and $DD0D) and the video chip's, and clears whatever was pending."
  },
  {
   "address": 16785,
   "type": "line",
   "text": "Waits until SPACE is pressed or A seconds have passed, timed by CIA 1's time-of-day clock. Sets the clock to zero (hours first, which stops it, tenths last, which starts it again), then tests SPACE (OS function $40, key_held, with X = $74: row 7, column 4) until the clock's seconds reach A. Returns the carry clear on time-out, or the carry set once SPACE has been pressed and let go. The seconds count in binary-coded decimal, so A = $1E, which the title waits with, times out at 20 seconds."
  },
  {
   "address": 16830,
   "type": "line",
   "text": "Copies X pages, 256 bytes each, from the address in $80/$81 to the address in $82/$83."
  },
  {
   "address": 16847,
   "type": "line",
   "text": "The rest of the file, 49 bytes that nothing reads."
  },
  {
   "address": 19456,
   "type": "line",
   "text": "XXXCOLMAP: the title picture's colours, one byte for each of the 1,000 character cells (the high four bits are the set pixels' colour, the low four the clear pixels'), copied to screen memory at $0C00. The last 24 bytes are past the screen; $4FF8-$4FFF land on the sprite pointers, which no sprite on the title uses."
  },
  {
   "address": 24576,
   "type": "line",
   "text": "XXXTITLE: the title picture, a hi-res bitmap of 320 by 200 pixels, 8 bytes to a character cell and 40 cells, 320 bytes, to a row, copied to the OS's bitmap at $2000. Rows 0-2 hold FREDERICK, in white, across cells 13-26."
  },
  {
   "address": 25536,
   "type": "line",
   "text": "The title picture's rows 3-5: FORSYTH, in white."
  },
  {
   "address": 26496,
   "type": "line",
   "text": "Rows 6-8: THE FOURTH, in yellow."
  },
  {
   "address": 27456,
   "type": "line",
   "text": "Rows 9-11: PROTOCOL, in yellow."
  },
  {
   "address": 28416,
   "type": "line",
   "text": "Rows 12-14: an empty row, then the top of the emblem, a skull in a ring, in grey (cells 16-23)."
  },
  {
   "address": 29376,
   "type": "line",
   "text": "Rows 15-17: the emblem's middle, the skull's eyes and nose."
  },
  {
   "address": 30336,
   "type": "line",
   "text": "Rows 18-20: the emblem's lower half."
  },
  {
   "address": 31296,
   "type": "line",
   "text": "Rows 21-23: one cell of the emblem's rim (row 21, cell 20), then two empty rows."
  },
  {
   "address": 32256,
   "type": "line",
   "text": "Row 24, the last: PRESS <SPACE> TO CONTINUE in red, cells 7-31; title_program rubs out the first 256 bytes of this row before it opens the menu."
  },
  {
   "address": 32576,
   "type": "line",
   "text": "The 192 bytes after the picture's 8,000, to the end of the file; the copy takes them to $3F40-$3FFF, which the video chip does not show."
  },
  {
   "address": 49152,
   "type": "line",
   "text": "The first 905 bytes of XXXMUSIC, which nothing reads: a pattern of $7F and $80 bytes repeating every 128 bytes, with a few others, as memory held it when the file was saved. The tune itself starts at $C389."
  },
  {
   "address": 50057,
   "type": "line",
   "text": "The title tune, by David Dunn (the manual's credits), \"the haunting melody\" of the hint book: a stream of commands that tune_play reads one byte at a time from $B7/$B8. Each command byte is the low byte of its routine's address in page $CD (tune_dispatch); its arguments follow it. $00 does nothing; $0E, $17 and $20 start a note on voice 1, 2 or 3 (two bytes of frequency, high byte first), $29 on voices 1 and 2 and $38 on all three (four or six bytes); $53 ends a step; $5B sets the three voices' envelopes (six bytes), $8D their pulse widths (six bytes), $D4 their waveforms (three bytes) and $E9 the volume and filter (three bytes); $CB sets the length of a step in frames; $82 goes back to the start. The opening sets voices 1 and 3 to pulse waves and voice 2 to a triangle, voice 3 through a low-pass and band-pass filter with full resonance, and steps of 17 frames."
  },
  {
   "address": 50088,
   "type": "line",
   "text": "The tune proper: a bass note on voice 1 ($02CC, about 42 Hz) under a figure on voice 2 that moves every step."
  },
  {
   "address": 51081,
   "type": "line",
   "text": "The tune's stream goes on: 182 steps from here to $CB89, with six changes of the voices' waveforms, seven of their envelopes, three of their pulse widths and five of the filter."
  },
  {
   "address": 52105,
   "type": "line",
   "text": "The stream's last 358 bytes: 69 steps, with four changes of waveform, five of envelope and two of the filter, then the loop at $CCEF."
  },
  {
   "address": 52463,
   "type": "line",
   "text": "The last command, $82: back to the start of the stream, so the tune repeats until the title stops it. It runs 438 steps of 17 frames, 7,446 frames: about 2 minutes 29 seconds at the 50 frames a second of a PAL machine."
  },
  {
   "address": 52464,
   "type": "line",
   "text": "Counted up by command $4D, which this tune does not use; nothing reads it."
  },
  {
   "address": 52465,
   "type": "line",
   "text": "The three voices' waveform (control register) values, set by command $D4: written to $D404, $D40B and $D412 with the gate bit when a note starts, and less 1, the gate off, three frames before the end of each step."
  },
  {
   "address": 52466,
   "type": "line",
   "text": "Voice 2's waveform value: $11, a triangle."
  },
  {
   "address": 52467,
   "type": "line",
   "text": "Voice 3's waveform value: $41, a pulse."
  },
  {
   "address": 52468,
   "type": "line",
   "text": "The frames in a step, set by command $CB: $11, 17, for the whole tune."
  },
  {
   "address": 52469,
   "type": "line",
   "text": "The tune player, called once a frame by title_irq. While the step's frame count in $45 is not zero, counts it down and goes on to the warbles (tune_effects). When it reaches zero, reads commands from the stream until one ends the step."
  },
  {
   "address": 52480,
   "type": "line",
   "text": "Moves the stream pointer $B7/$B8 on by one and reads the next command byte."
  },
  {
   "address": 52488,
   "type": "line",
   "text": "Writes the command byte into the operand of the JMP below, so the JMP goes to $CD00 plus the command: the command's own routine."
  },
  {
   "address": 52491,
   "type": "line",
   "text": "JMP $CDxx, its low byte the command just read."
  },
  {
   "address": 52492,
   "type": "line",
   "text": "The JMP's low byte, which tune_next_command overwrites with each command."
  },
  {
   "address": 52494,
   "type": "line",
   "text": "Command $0E: voice 1's frequency from the next two bytes (freq_voice1), and its note started (gate_voice1)."
  },
  {
   "address": 52503,
   "type": "line",
   "text": "Command $17: voice 2's frequency (freq_voice2), and its note started."
  },
  {
   "address": 52512,
   "type": "line",
   "text": "Command $20: voice 3's frequency (freq_voice3), and its note started."
  },
  {
   "address": 52521,
   "type": "line",
   "text": "Command $29: frequencies for voices 1 and 2, then both notes started."
  },
  {
   "address": 52536,
   "type": "line",
   "text": "Command $38: frequencies for all three voices, then the three notes started."
  },
  {
   "address": 52557,
   "type": "line",
   "text": "Command $4D: adds one to tune_count."
  },
  {
   "address": 52563,
   "type": "line",
   "text": "Command $53: ends the step: the frame count in $45 set to tune_step_length, and back to tune_play, which counts the first frame off."
  },
  {
   "address": 52571,
   "type": "line",
   "text": "Command $5B: six bytes, the attack/decay of voices 1, 2 and 3, then their sustain/release."
  },
  {
   "address": 52610,
   "type": "line",
   "text": "Command $82: the stream pointer back to its start, kept in $B9/$BA."
  },
  {
   "address": 52621,
   "type": "line",
   "text": "Command $8D: six bytes, the pulse width of voices 1, 2 and 3, each low byte then high."
  },
  {
   "address": 52660,
   "type": "line",
   "text": "Command $B4, which this tune does not use: silences the sound chip and returns from tune_play with A = $FF; the next step reads on from the byte after it."
  },
  {
   "address": 52673,
   "type": "line",
   "text": "Unused: stores A at $0314, the KERNAL's interrupt vector, with $EA as its high byte, enables interrupts and stops at a BRK; nothing jumps here. With unused_irq_install it looks like the hooks for running the tune under the KERNAL's interrupt."
  },
  {
   "address": 52683,
   "type": "line",
   "text": "Command $CB: one byte, the frames in a step (tune_step_length)."
  },
  {
   "address": 52692,
   "type": "line",
   "text": "Command $D4: three bytes, the voices' waveforms (tune_waves)."
  },
  {
   "address": 52713,
   "type": "line",
   "text": "Command $E9: three bytes, written to $D418 (filter mode and volume), $D417 (resonance and which voices are filtered) and $D416 (the cut-off frequency's high byte)."
  },
  {
   "address": 52734,
   "type": "line",
   "text": "Starts a note on voice 1: zero to its control register, then its waveform with the gate bit, so the envelope starts again."
  },
  {
   "address": 52744,
   "type": "line",
   "text": "Starts a note on voice 2."
  },
  {
   "address": 52754,
   "type": "line",
   "text": "Starts a note on voice 3."
  },
  {
   "address": 52764,
   "type": "line",
   "text": "Moves the stream pointer on by one and returns the byte there in A."
  },
  {
   "address": 52773,
   "type": "line",
   "text": "Voice 1's frequency from the stream, high byte then low."
  },
  {
   "address": 52786,
   "type": "line",
   "text": "Voice 2's frequency from the stream, high byte then low: written to the chip and kept in $71/$72 and in $A3/$A4, which then has $30 added, for the warble."
  },
  {
   "address": 52819,
   "type": "line",
   "text": "Voice 3's frequency, kept in $BB/$BC and in $B2/$B3 with $40 added."
  },
  {
   "address": 52852,
   "type": "line",
   "text": "Resets the player: no step under way ($45), the warble counters $96 and $97 at zero, the sound chip's registers cleared, the stream pointer and its restart address at $C388 (the first command is read from $C389), and the volume at full."
  },
  {
   "address": 52886,
   "type": "line",
   "text": "Unused: points the KERNAL's interrupt vector at $0314 to tune_play, enables interrupts and stops at a BRK (unused_irq_install); nothing calls it."
  },
  {
   "address": 52898,
   "type": "line",
   "text": "Every fifth frame voice 2 switches between its note and the note plus $30. This one writes the higher frequency from $A3/$A4 and points the branch at $CF08 to warble2_down for the next switch."
  },
  {
   "address": 52920,
   "type": "line",
   "text": "Writes voice 2's own note back from $71/$72 and points the branch at $CF08 to warble2_up."
  },
  {
   "address": 52942,
   "type": "line",
   "text": "Every sixth frame voice 3 switches between its note and the note plus $40: writes the higher frequency from $B2/$B3 and points the branch at $CF00 to warble3_down."
  },
  {
   "address": 52964,
   "type": "line",
   "text": "Writes voice 3's own note back from $BB/$BC and points the branch at $CF00 to warble3_up."
  },
  {
   "address": 52986,
   "type": "line",
   "text": "Counts frames for the warbles, voice 3's in $97 and voice 2's in $96, and switches a voice when its count comes up."
  },
  {
   "address": 52992,
   "type": "line",
   "text": "BEQ to warble3_down or warble3_up: its operand is rewritten by them ($E2 or $CC)."
  },
  {
   "address": 52993,
   "type": "line",
   "text": "The branch's offset: $E2 goes to warble3_down, $CC to warble3_up."
  },
  {
   "address": 53000,
   "type": "line",
   "text": "BEQ to warble2_up or warble2_down: its operand is rewritten by them ($98 or $AE)."
  },
  {
   "address": 53001,
   "type": "line",
   "text": "The branch's offset: $98 goes to warble2_up, $AE to warble2_down."
  },
  {
   "address": 53002,
   "type": "line",
   "text": "Three frames before the step ends ($45 = 3), the gate bit off on all three voices, so each note goes into its release."
  },
  {
   "address": 53029,
   "type": "line",
   "text": "Returns with A = 0."
  },
  {
   "address": 53032,
   "type": "line",
   "text": "The last 216 bytes of XXXMUSIC, which nothing reads: $00 and $FF alternating, then the same $7F and $80 pattern as at the file's start."
  }
 ]
}