The Spectrum 48K relied upon the humble BEEP command in BASIC and a small piezoelectric buzzer to produce sound. This was pitiful, and was upgraded in the 128K series of computers with the addition of a dedicated AY-3-8912 chip.


The beeper is controlled by rapidly toggling bit 4 of port &FE. This usually involves locking the processor up for the duration if an accurate note is required (such as the BEEP command in BASIC), though with a bit of ingenuity and clever programming sound effects could be deployed without holding up game play and the one channel beeper could be extended to play two or three channels of music.

This example was created by Tim Follin and originally published as a hex listing in Your Sinclair #20, page 55 (Star Tip #2, at the bottom of that page). Being an avid reader of the magazine and fascinated with the odd example of multi-channel music on the beeper, I decided to type it in.

I had the good fortune to work with Tim for a few years starting at Software Creations. Upon meeting him, I famously said “Are you THE Tim Follin?”, and produced that listing on a sheet of paper…

I still have that listing tucked away in a folder somewhere.

Anyway, download and unzip this TAP file into your favourite emulator, and run with the command “RANDOMIZE USR 40000”. The code is reproduced here with kind permission from the man himself.


The AY-3-8912 provided 3 channels. This is controlled by two ports:

&FFFD: Select register (OUT) &FFFD: Read from selected register (IN) &BFFD: Write to selected register (OUT)

The AY chip has 15 registers, namely:

&00: Channel 1 fine pitch
&01: Channel 1 coarse pitch
&02: Channel 2 fine pitch
&03: Channel 2 coarse pitch
&04: Channel 3 fine pitch
&05: Channel 3 coarse pitch
&06: Noise pitch (5 bits)
&07: Mixer
&08: Channel 1 volume (4 bits)
&09: Channel 2 volume (4 bits)
&0A: Channel 3 volume (4 bits)
&0B: Envelope fine duration
&0C: Envelope coarse duration
&0D: Envelope shape (4 bits)
&0E: I/O port

The mixer register consists of the following bits to enable tone and / or noise for each channel. These are set to 0 to enable or 1 to disable:

Each channels pitch registers form a 12 bit value; the top nibble of the coarse pitch is ignored. All other registers are 8 bit, unless specified.

The following BASIC code outputs note A on channel 1:

10 LET AYS=65533
20 LET AYW=49149
30 OUT AYS,0
40 OUT AYW,242
50 OUT AYS,1
60 OUT AYW,7
70 OUT AYS,8
80 OUT AYW,15
90 OUT AYS,7
100 OUT AYW,BIN 11111110

This example sets the note value in lines 30 to 60, the volume in lines 70 and 80 and finally enables channel 1 in lines 90 and 100.

The I/O port is exposed on the AUX and RS232/MIDI sockets.