Music Play

This file is part of Byte Power November 1986 . Download the collection to get this file.
Developer(s): Eric Boisvert
Date: 1986
Type: Program
Platform(s): TS 2068

MUSIC PLAY is a TS2068 program that drives the AY-3-8912 sound chip using raw register writes via the SOUND keyword to play a sequence of musical notes stored as binary data loaded into memory at address 60000. Each note is encoded as three bytes: a fine-tuning value, a coarse-tuning value, and a pause/duration byte, with the sentinel value 255 marking the end of the sequence and 254 indicating a silent pause. The program uses a metallic timbre by configuring envelope generator registers 8, 9, 12, and 13 alongside the mixer register 7. A companion binary file “MUSIC DEMO” of 1594 bytes is saved and loaded separately at address 60000 (6e4 in scientific notation), and a self-list protection check at line 15 uses PEEK 23681 to detect whether a proper entry point was used.


Program Structure

The program is split into two functional segments. Lines 10–160 form the playback engine, and lines 9000–9030 handle loading the companion data file before jumping back to the start. Line 9999 is a standalone save/verify utility and is never reached during normal execution.

  1. Initialisation (lines 20–30): Sets tempo (default 5) and start (default 60000).
  2. Main loop (lines 35–100): Reads three bytes from the data block, interprets them, plays or pauses, waits, and loops.
  3. Termination (lines 150–160): Reached when the sentinel byte 255 is encountered; executes STOP.
  4. Data loader (lines 9000–9030): Loads the binary “MUSIC DEMO” file to address 60000 and restarts.
  5. Save utility (line 9999): Saves both the BASIC program (auto-starting at line 9000) and the 1594-byte data block, then verifies both.

Data Format

Each note record occupies exactly three consecutive bytes starting at start:

OffsetVariableMeaning
+0fineAY fine pitch / control byte (254 = rest, 255 = end)
+1coarseAY coarse pitch
+2pauseDuration unit (multiplied by tempo for PAUSE, by 5 for envelope period)

The pointer start is advanced by 3 on every iteration at line 40, providing a simple sequential traversal with no array overhead.

AY Sound Chip Usage

Line 70 issues a single chained SOUND statement writing seven AY-3-8912 registers in one call:

  • 0, fine — Channel A fine pitch (low 8 bits)
  • 1, coarse — Channel A coarse pitch (high 4 bits)
  • 2, fine+1 — Channel B fine pitch (slight detuning for a chorus/metallic effect)
  • 3, coarse — Channel B coarse pitch
  • 8, 16 — Channel A amplitude: envelope-controlled mode
  • 9, 16 — Channel B amplitude: envelope-controlled mode
  • 7, 60 — Mixer: channels A and B tone enabled, noise off (binary 00111100)
  • 13, 0 — Envelope shape: hold-decay
  • 12, pause*5 — Envelope period coarse (duration scales with note length)

Detuning Channel B by one fine-pitch unit (fine+1) relative to Channel A produces the characteristic metallic beating timbre referenced in the comment citing August and October magazine issues.

Control Flow and Sentinel Values

Rather than storing note counts or using a separate length variable, the loop relies on two magic byte values embedded in the data stream itself. fine=254 at line 50 branches past the SOUND call (to line 80) to produce a rest of the specified duration. fine=255 at line 60 exits the loop entirely. This is an economical, data-driven termination scheme.

Entry-Point Protection

Line 15 reads system variable address 23681 (PEEK 23681). If this value is zero the program executes CLS : LIST 9999: STOP, exposing the save/verify line rather than running the player. This acts as a simple guard ensuring the program is entered via the data-loading path at line 9000 (where the LOAD would have set up prerequisites) rather than run cold from line 10.

Notable BASIC Idioms

  • LOAD "MUSIC DEMO"CODE 6e4 — The target address 60000 is written in scientific notation (6e4), a common TS2068 memory optimisation that saves tokenised bytes compared to the full integer literal.
  • SAVE "MUSIC PLAY" LINE 9000 — The program auto-runs at line 9000, ensuring the data file is always loaded before playback begins.
  • The tempo variable at line 20 provides a single point of adjustment for overall playback speed without touching the data; increasing it slows all notes proportionally.

Content

Appears On

Tape-based magazine.

Related Products

Related Articles

This program is a very basic music writer using the A,B,C… method for inputing the notes, once loaded a menu...

Related Content

Image Gallery

Music Play

Source Code

10 REM                                                             MUSIC PLAY                      written by Eric Boisvert        ©1986 BYTE POWER              
   15 IF PEEK 23681=0 THEN CLS : LIST 9999: STOP 
   20 LET tempo=5: REM tempo
   30 LET start=60000: REM start of data to play
   35 REM LOOP TO READ AND PLAY
   40 LET fine=PEEK start: LET coarse=PEEK (start+1): LET pause=PEEK (start+2): LET start=start+3
   50 IF fine=254 THEN GO TO 80: REM if pause (254)
   60 IF fine=255 THEN GO TO 150: REM if end (255)
   65 REM SET UP FOR METALLIC      SOUND and ENVELOPE GENERATIOR   (see AUGUST & OCTOBER issues)
   70 SOUND 0,fine;1,coarse;2,fine+1;3,coarse;8,16;9,16;7,60;13,0;12,pause*5
   80 REM wait for note to finish
   90 PAUSE tempo*pause
  100 GO TO 35
  150 REM END
  160 STOP 
 9000 REM LOAD DATA FILE 
 9010 REM NOTES MAY BE ANY WHERE
 9020 LOAD "MUSIC DEMO"CODE 6e4
 9030 GO TO 10
 9999 SAVE "MUSIC PLAY" LINE 9000: SAVE "MUSIC DEMO"CODE 6e4,1594: VERIFY "": VERIFY ""CODE

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top