MusicBox3 is a music player program that uses the SOUND command to drive a three-channel synthesizer, playing one of five selectable compositions stored entirely as DATA statements. Each composition’s note data is encoded as eight values per event — three channel frequency/volume pairs (AF, AC, BF, BC, CF, CC), a BEEP pitch value (F), and a tempo divisor (V) — allowing simultaneous chord voices alongside a melody line. A special sentinel value of 99 for F triggers a PAUSE instead of BEEP, enabling sustained chords without a melodic note. The program uses ON ERR to detect end-of-data as a loop termination signal, resetting cleanly with ON ERR RESET after playback, and supports adjustable tempo, looping, and continuous playback modes. Compositions are indexed by offsetting RESTORE targets to line numbers of the form N*1000+1000, mapping selections 1–5 to DATA blocks starting at lines 2000, 3000, 4000, 5000, and 6000.
Program Structure
The program is divided into a control flow section (lines 10–320) and a series of DATA blocks (lines 2000–6000) that contain the musical compositions. The main flow is:
- Title screen with scrolling banner (lines 10–40)
- Menu listing compositions (lines 50–70)
- User selection and setup (lines 80–90)
- Playback loop using SOUND and BEEP (lines 100–170)
- End-of-data handling via ON ERR (lines 180–310)
- Post-playback options (lines 190–310)
Composition Indexing via RESTORE
Each composition’s DATA begins at a line number of the form N*1000+1000. Selecting composition 1 RESTOREs to line 2000, composition 2 to line 3000, and so on. The first two items in each block are the title string N$ and a rate scalar R. This scheme means lines 50–60 can enumerate all compositions in a simple FOR I=1 TO 5 loop, each time doing RESTORE I*1000+1000: READ N$.
Line 6000 contains a blank title and rate of 1, functioning as a placeholder for a fifth slot with no actual notes beyond what appears in other DATA lines.
Note Data Format
Each event record consists of eight values read at line 130:
| Variable | Meaning |
|---|---|
AF | Channel A frequency (SOUND register 0) |
AC | Channel A volume/control (SOUND register 1) |
BF | Channel B frequency (SOUND register 2) |
BC | Channel B volume/control (SOUND register 3) |
CF | Channel C frequency (SOUND register 4) |
CC | Channel C volume/control (SOUND register 5) |
F | BEEP pitch (semitones) or sentinel 99 for pause |
V | Duration divisor (note value: 4 = quarter, 8 = eighth, etc.) |
When AF is negative (−1), the SOUND call at line 140 is skipped via the IF AF<0 THEN GO TO 150 branch, allowing note events with no chord update — only a BEEP or pause for that event.
Dual Output: SOUND and BEEP
Lines 140–170 handle output. If F equals 99, line 160 executes a PAUSE T/V*60 (a rest), then loops back to read the next event. Otherwise, line 170 calls BEEP T/V, F for a melodic note of the appropriate duration, while the three SOUND channels sustain a chord independently. The duration T is computed as R*TT where R is the composition’s rate scalar and TT is the user-adjustable tempo value (default 10), so T/V gives the actual note duration in seconds.
ON ERR as End-of-Data Detection
Rather than using a dedicated end-of-data sentinel in the READ loop, the program uses ON ERR GO TO 180 at line 130 to trap the “Out of DATA” error that occurs when all note records have been consumed. Line 180 then immediately cancels the error trap with ON ERR RESET before proceeding. This is a common BASIC idiom for DATA exhaustion detection.
Continuous Play Mode
Line 180 checks if Z$="2" (continuous play). If so, it re-issues a RESTORE to N*1000+1010 — skipping the title/rate header at the x000 line — and jumps back to line 130 to replay the note data from the beginning without re-displaying the menu. This offset of +10 past the composition base accounts for the header DATA line.
Post-Playback Options
After playback ends normally, the program offers four options via a PAUSE 0 / INKEY$ idiom:
- 1 — Play again from the start
- 2 — Play continuously (loops automatically)
- 3 — Change tempo (prompts for a new
TTvalue, then replays) - 0 — Return to composition selection
Initial SOUND Setup
Line 90 initializes the sound chip with SOUND 7,56;8,15;9,15;10,15. Register 7 value 56 (binary 00111000) configures the noise/tone mixer; registers 8–10 set the volume envelopes for all three channels to maximum (15), preparing the chip for subsequent note events.
Anomalies and Notable Details
- Line 4010 contains
1-1,0,0,0,0,0,17,16which evaluates to0,0,0,0,0,0,17,16— a typo where a leading-1sentinel was written as1-1. This silences the SOUND call sinceAF=0is not negative, so it would issue a SOUND command with all-zero registers rather than skipping it. This is likely an unintentional data entry error. - The title banner loop at line 10 prints 13 rows (A=0 TO 12) of alternating INK 1 and INK 3 “MUSIC BOX 3” text, creating a simple color-striped title display.
- Line 110 centers the composition title using
AT 10,(31-LEN N$)/2, a standard centering formula for a 32-column display. - The tempo prompt at lines 260–300 correctly notes that the default is 10 and that smaller values produce faster playback, consistent with how
TTis used as a multiplier inT=R*TT.
Content
Source Code
10 BORDER 4:PAPER 6:CLS :FOR A=0 TO 12
20 PRINT TAB 3; INK 1;"MUSIC BOX 3"; TAB 18; INK 3;"MUSIC BOX 3":NEXT A
30 PRINT AT 15,0; PAPER 5;''"THIS IS YOUR MUSIC BOX 3. PRESS ""ENTER"" TO SEE THE CONTENTS. "
40 PAUSE 0
50 CLS :PRINT PAPER 5;"********* BOX CONTENTS *********":PRINT ''
60 FOR I=1 TO 5:RESTORE I*1000+1000:READ N$:PRINT I; TAB 4;N$:NEXT I
70 PRINT PAPER 5; AT 20,0;"ENTER THE NUMBER OF THE COMPOSI-TION THAT YOU WANT TO PLAY "
80 INPUT N:CLS :LET TT=10:LET Z$=""
90 RESTORE N*1000+1000:READ N$,R:LET T=R*TT:SOUND 7,56;8,15;9,15;10,15
100 CLS :PRINT PAPER 5;"********* NOW PLAYING **********"; AT 21,0;"********* NOW PLAYING **********"
110 PRINT AT 10,(31- LEN N$)/2;N$
120 PRINT PAPER 3; INK 7; AT 20,0;"TO STOP, PRESS ""SHIFT"" + ""BREAK"""
130 READ AF,AC,BF,BC,CF,CC,F,V:ON ERR GO TO 180:IF AF<0 THEN GO TO 150
140 SOUND 0,AF;1,AC;2,BF;3,BC;4,CF;5,CC
150 IF F <>99 THEN GO TO 170
160 PAUSE T/V*60:GO TO 130
170 BEEP T/V,F:GO TO 130
180 ON ERR RESET :IF Z$="2" THEN RESTORE N*1000+1010:GO TO 130
190 SOUND 7,63:CLS :PAPER 7:PRINT AT 7,0;"PRESS ""1"" TO PLAY AGAIN. "
200 PRINT "PRESS ""2"" TO PLAY CONTINUOUSLY. "
210 PRINT ;"PRESS ""3"" TO PLAY DIFFERENTLY. "
220 PRINT ;"PRESS ""0"" TO PLAY ANOTHER "
230 PRINT "COMPOSITION.":PAPER 6
240 PAUSE 0:LET Z$= INKEY$:IF Z$="1" OR Z$="2" THEN GO TO 90
250 IF Z$="0" THEN GO TO 50
260 CLS :PRINT AT 6,0;"INPUT A NUMBER FOR THE DESIRED"
270 PRINT "TEMPO. THE PROGRAMMED TEMPO IS"
280 PRINT "10. A SMALLER NUMBER WILL MAKE"
290 PRINT "THE TEMPO FASTER; A LARGER"
300 PRINT "NUMBER WILL MAKE IT SLOWER."
310 INPUT TT:GO TO 90
320 SAVE "BOX 3" LINE 10
2000 DATA "\{20}\{0}THE SHEPHERDESS",.1
2010 DATA 0,0,0,0,0,0,14,8,221,0,23,1,23,1,19,4,209,0,209,0,209,0,21,8,186,0,186,0,186,0,23,4,209,0,209,0,209,0,21,8,221,0,23,1,23,1,19,2.67,-1,0,0,0,0,0,19,4,-1,0,0,0,0,0,14,8,209,0,23,1,23,1,16,4,0,0,0,0,0,0,16,8
2020 DATA 221,0,23,1,23,1,14,8,-1,0,0,0,0,0,14,8,0,0,0,0,0,0,12,8,234,0,23,1,23,1,16,4,0,0,0,0,0,0,16,8,221,0,23,1,21,1,14,4,0,0,0,0,0,0,14,8,221,0,221,0,221,0,19,4,186,0,186,0,186,0,21,8,139,0,139,0,139,0,23,4
2030 DATA 186,0,186,0,186,0,21,8,221,0,221,0,221,0,19,2.67,-1,0,23,1,116,1,19,4,0,0,0,0,0,0,26,8,221,0,23,1,116,1,23,4,0,0,0,0,0,0,19,8,209,0,39,1,116,1,21,4,0,0,0,0,0,0,14,8,186,0,221,0,221,0,19,4,0,0,0,0,0,0,19,8
2040 DATA -1,0,23,1,186,0,19,4,-1,0,0,0,0,0,26,8,221,0,23,1,116,1,23,4,0,0,0,0,0,0,19,8,209,0,39,1,116,1,21,4,0,0,0,0,0,0,14,8,186,0,221,0,221,0,19,2,0,0,0,0,0,0,99,8
2050 DATA 0,0,0,0,0,0,14,8,221,0,23,1,23,1,19,4,209,0,209,0,209,0,21,8,186,0,186,0,186,0,23,4,209,0,209,0,209,0,21,8,221,0,23,1,23,1,19,2.67,-1,0,0,0,0,0,19,4,-1,0,0,0,0,0,14,8,209,0,23,1,23,1,16,4,0,0,0,0,0,0,16,8
2060 DATA 221,0,23,1,23,1,14,8,-1,0,0,0,0,0,14,8,0,0,0,0,0,0,12,8,234,0,23,1,23,1,16,4,0,0,0,0,0,0,16,8,221,0,23,1,21,1,14,4,0,0,0,0,0,0,14,8,221,0,221,0,221,0,19,4,186,0,186,0,186,0,21,8,139,0,139,0,139,0,23,4
2070 DATA 186,0,186,0,186,0,21,8,221,0,221,0,221,0,19,2.67,-1,0,23,1,116,1,19,4,0,0,0,0,0,0,26,8,221,0,23,1,116,1,23,4,0,0,0,0,0,0,19,8,209,0,39,1,116,1,21,4,0,0,0,0,0,0,14,8,186,0,221,0,221,0,19,4,0,0,0,0,0,0,19,8
2080 DATA -1,0,23,1,186,0,19,4,-1,0,0,0,0,0,26,8,221,0,23,1,116,1,23,4,0,0,0,0,0,0,19,8,209,0,39,1,116,1,21,4,0,0,0,0,0,0,14,8,186,0,221,0,221,0,19,2,0,0,0,0,0,0,99,8
3000 DATA "PRELUDE BY CHOPIN",.2
3010 DATA 0,0,0,0,0,0,4,4,47,5,47,5,47,5,13,5.33,-1,0,0,0,0,0,14,16,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,2,0,0,0,0,0,0,18,4,209,0,226,3,226,3,15,5.22,-1,0,0,0,0,0,16,16,197,0,75,1,241,1,21,4
3020 DATA 197,1,75,1,241,1,21,4,197,0,75,1,241,1,21,2,0,0,0,0,0,0,13,4,138,1,47,5,47,5,10,5.33,-1,0,0,0,0,0,11,16,39,1,186,1,151,2,14,4,39,1,186,1,151,2,14,4,39,1,186,1,151,2,14,2,116,1,0,0,0,0,8,4,116,1,196,7,196,7,8,5.33
3030 DATA -1,0,0,0,0,0,9,16,138,1,241,1,151,2,13,4,138,1,241,1,151,2,13,4,138,1,241,1,151,2,13,2,0,0,0,0,0,0,4,4,47,5,47,5,47,5,13,5.33,-1,0,0,0,0,0,14,16,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,2
3040 DATA 0,0,0,0,0,0,18,4,209,0,226,3,226,3,15,5.33,-1,0,0,0,0,0,16,16,124,0,75,1,241,1,25,4,124,0,75,1,241,1,25,4,117,0,138,1,79,2,25,2,248,0,0,0,0,0,13,4,234,0,235,6,235,6,13,5.33,-1,0,0,0,0,0,14,16,221,0,116,1,79,2,18,4
3050 DATA 248,0,186,1,79,2,18,4,7,1,186,1,151,2,18,2,116,1,0,0,0,0,8,4,116,1,196,7,196,7,11,5.33,-1,0,0,0,0,0,9,16,197,0,241,1,151,2,21,4,197,0,75,1,241,1,21,4,197,0,75,1,241,1,21,2,0,0,0,0,0,0,99,4,0,0,0,0,0,0,4,4
3060 DATA 47,5,47,5,47,5,13,5.33,-1,0,0,0,0,0,14,16,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,2,0,0,0,0,0,0,18,4,209,0,226,3,226,3,15,5.33,-1,0,0,0,0,0,16,16,197,0,75,1,241,1,21,4,197,0,75,1,241,1,21,4
3070 DATA 197,0,75,1,241,1,21,2,0,0,0,0,0,0,13,4,138,1,47,5,47,5,10,5.33,-1,0,0,0,0,0,11,16,39,1,186,1,151,2,14,4,39,1,186,1,151,2,14,4,39,1,186,1,151,2,14,2,116,1,0,0,0,0,8,4,116,1,196,7,196,7,8,5.33,-1,0,0,0,0,0,9,16
3080 DATA 138,1,241,1,151,2,13,4,138,1,241,1,151,2,13,4,138,1,241,1,151,2,13,2,0,0,0,0,0,0,4,4,47,5,47,5,47,5,13,5.33,-1,0,0,0,0,0,14,16,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,4,7,1,116,1,151,2,11,2,0,0,0,0,0,0,18,4
3090 DATA 209,0,226,3,226,3,15,5.33,-1,0,0,0,0,0,16,16,124,0,75,1,241,1,25,4,124,0,75,1,241,1,25,4,117,0,138,1,79,2,25,2,248,0,0,0,0,0,13,4,234,0,235,6,235,6,13,5.33,-1,0,0,0,0,0,14,16,221,0,116,1,79,2,18,4,248,0,186,1,79,2,18,4
3100 DATA 7,1,186,1,151,2,18,2,116,1,0,0,0,0,8,4,116,1,196,7,196,7,11,5.33,-1,0,0,0,0,0,9,16,197,0,241,1,151,2,21,4,197,0,75,1,241,1,21,2,0,0,0,0,0,0,99,4
4000 DATA "SOMEWHERE IN THE GARDEN",.3
4010 DATA 186,0,248,0,209,5,17,8,-1,0,0,0,209,5,17,8,197,0,23,1,241,1,16,16,-1,0,0,0,0,0,19,16,1-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,248,0,57,1,232,2,14,8,-1,0,0,0,0,0,14,8,248,0,57,1,232,2,14,16,-1,0,0,0,0,0,16,16
4020 DATA -1,0,0,0,0,0,17,16,-1,0,0,0,0,0,19,16,156,0,232,2,232,2,21,8,186,0,248,0,248,0,17,8,197,0,23,1,241,1,16,16,-1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,248,0,57,1,232,2,14,8,-1,0,0,0,0,0,14,16
4030 DATA -1,0,0,0,0,0,16,16,-1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,-1,0,0,0,0,0,14,16,248,0,241,1,226,3,12,8,248,0,248,0,248,0,12,16,-1,0,0,0,0,0,16,16,7,1,75,1,75,1,11,16,-1,0,0,0,0,0,14,16
4040 DATA -1,0,0,0,0,0,12,16,-1,0,0,0,0,0,11,16,241,1,241,1,241,1,9,8,-1,0,0,0,0,0,4,8,241,1,226,3,226,3,9,16,-1,0,0,0,0,0,11,16,-1,0,0,0,0,0,12,16,-1,0,0,0,0,0,14,16,241,1,241,1,241,1,16,8,248,0,248,0,248,0,12,8
4050 DATA 7,1,75,1,75,1,11,16,-1,0,0,0,0,0,14,16,-1,0,0,0,0,0,12,16,-1,0,0,0,0,0,11,16,241,1,226,3,226,3,9,4,165,0,209,0,248,0,21,16,-1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,186,0,248,0,209,5,17,8
4060 DATA -1,0,0,0,209,5,17,8,197,0,23,1,241,1,16,16,-1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,248,0,57,1,232,2,14,8,-1,0,0,0,0,0,14,8,248,0,57,1,232,2,14,16,-1,0,0,0,0,0,16,16,-1,0,0,0,0,0,17,16
4070 DATA -1,0,0,0,0,0,19,16,156,0,232,2,232,2,21,8,186,0,248,0,248,0,17,8,197,0,23,1,241,1,16,16,-1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,248,0,57,1,232,2,14,8,-1,0,0,0,0,0,14,16,-1,0,0,0,0,0,16,16
4080 DATA -1,0,0,0,0,0,19,16,-1,0,0,0,0,0,17,16,-1,0,0,0,0,0,16,16,-1,0,0,0,0,0,14,16,248,0,241,1,226,3,12,8,248,0,248,0,248,0,12,16,-1,0,0,0,0,0,16,16,7,1,75,1,75,1,11,16,-1,0,0,0,0,0,14,16,-1,0,0,0,0,0,12,16
4090 DATA -1,0,0,0,0,0,11,16,241,1,241,1,241,1,9,8,-1,0,0,0,0,0,4,8,241,1,226,3,226,3,9,16,-1,0,0,0,0,0,11,16,-1,0,0,0,0,0,12,16,-1,0,0,0,0,0,14,16,241,1,241,1,241,1,16,8,248,0,248,0,248,0,12,8,7,1,75,1,75,1,11,16
4100 DATA -1,0,0,0,0,0,14,16,-1,0,0,0,0,0,12,16,-1,0,0,0,0,0,11,16,241,1,241,1,241,1,9,8,165,0,221,0,221,0,20,16,165,0,209,0,248,0,21,4
6000 DATA "",1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
