This program drives the Programmable Sound Generator (PSG) chip via OUT instructions to play a short musical sequence of 18 notes. It uses the AY-3-8910/8912 chip’s register interface, writing to register address port 245 and data port 246, configuring mixer and volume registers before setting tone period values for two channels. Each note’s pitch is defined by two frequency-divider bytes (a, b) and a duration multiplier (c), with channel A and channel B sharing the same coarse period bytes. After each note the volume registers are zeroed to produce a clean articulation between notes.
Program Structure
The program is compact: a REM banner at line 0, a single FOR/NEXT loop spanning lines 10–30 that iterates 18 times (once per note), and a DATA block at line 40. Each iteration reads three values (a, b, c) from the data table, programs the PSG, pauses for the note duration, then silences the chip before advancing.
PSG Register Mapping
The AY-3-8910/8912 is addressed by writing the register number to port 245 (register select) and the value to port 246 (register write). The registers used are:
| Register | Function | Value written |
|---|---|---|
| 7 | Mixer control | 60 (binary 00111100 — channels A & B tone enabled) |
| 8 | Channel A volume | 15 (maximum, no envelope) |
| 9 | Channel B volume | 15 (maximum, no envelope) |
| 0 | Channel A tone, fine | a |
| 1 | Channel A tone, coarse | b |
| 2 | Channel B tone, fine | a+2 |
| 3 | Channel B tone, coarse | b |
Channel B is tuned slightly sharp relative to channel A by adding 2 to the fine-period byte (a+2), producing a gentle chorus/detune effect between the two voices playing simultaneously.
Note Duration
Duration is controlled by PAUSE 9*c. The PAUSE unit is 1/50 s (one TV frame), so the three c values in the data (1, 2, 4) map to 9, 18, and 36 frames — roughly 0.18 s, 0.36 s, and 0.72 s — giving a simple 1:2:4 rhythmic ratio.
Articulation / Note-Off
After each pause, registers 8 and 9 (channel A and B volume) are both set to 0 before NEXT z. This silences the chip between notes, giving crisp articulation rather than letting pitches blur together. The mixer register (7) is left at 60 throughout; only volume is toggled.
Data Table Layout
Each note occupies three consecutive DATA values: fine period (a), coarse period (b), and duration multiplier (c). With 18 notes × 3 values = 54 values, all packed onto a single line 40. Coarse period values 3–5 place the melody in the upper-mid audible range of the AY chip.
Notable Techniques and Observations
- The mixer byte 60 (0b00111100) enables tone on channels A and B while disabling noise on all channels and leaving channel C silent — a precise, minimal mixer setup.
- Using
a+2for the Channel B fine period is an arithmetic shortcut that avoids storing a separate pitch value for the harmony voice, saving DATA entries. - The
STOPat line 30 (afterNEXT z) cleanly halts the program; without it the interpreter would fall through to line 40 and trigger a Out of DATA error. - No
RESTOREis used, so the program can only play through the melody once per run without re-executing from line 10. - There is no envelope generator usage (registers 11–13); dynamics are binary (full volume or silent).
Content
Source Code
0 REM OUT MUSIC ©1986 BYTE POWER WRITTEN BY K. BOISVERT
10 FOR z=1 TO 18: READ a,b,c
20 OUT 245,7: OUT 246,60: OUT 245,8: OUT 246,15: OUT 245,9: OUT 246,15: OUT 245,0: OUT 246,a: OUT 245,1: OUT 246,b: OUT 245,2: OUT 246,a+2: OUT 245,3: OUT 246,b
30 PAUSE 9*c: OUT 245,8: OUT 246,0: OUT 245,9: OUT 246,0: NEXT z: STOP
40 DATA 92,4,2,209,5,2,92,4,2,209,5,2,92,4,1,158,4,1,47,5,1,158,4,1,92,4,4,226,3,2,209,5,2,226,3,2,209,5,2,226,3,1,209,5,1,47,5,1,209,5,1,92,4,4
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
