Generating sound through OUT commands to AY

This is where most of us started. Classic Spectrum basic.

Moderator: Programming Moderators

User avatar
Posts: 21
Joined: Tue May 30, 2017 12:54 am

Generating sound through OUT commands to AY

Postby Protocultor » Thu Aug 13, 2020 11:45 am


There's a lot of info on the matter, but I wanted to present this in a newbie-friendly manner, since I'm a newbie myself and learning how to do it was kinda confusing and time-consuming. So I hope the following can help someone else.
Of course, if there's something wrong in here, corrections are useful and welcome.

Creating sound

The Spectrum Next has 3 AY programmable sound generators (PSG), each one with 3 channels. Control of these depend on two ports:

65533 (%$FFFD): PSG Control and Register Select
49149 (%$BFFD): PSG Data

Its control method is equivalent to that of the Next Registers, as explained in Chapter 23, page 265 of the Next manual. You'll need two consecutive OUT commands: one for the Select port (65533) to select a specific register (in practice, a feature of the PSG), and immediately after, another OUT to the Data port (49149) to modify the value of that register.

The exception to this rule is the selection of the currently used PSG; it just needs a single OUT to 65533: 255 (default), 254 or 253. Following OUT commands to 65533 with values not being these will target the PSG selected last.

A single PSG provides 15 registers; as mentioned, the following OUT must target 49149 with the new value.

Code: Select all

Reg	Use				Values
0	Channel A fine pitch		0-255
1	Channel A coarse pitch		0-15
2	Channel B fine pitch		0-255
3	Channel B coarse pitch		0-15
4	Channel C fine pitch		0-255
5	Channel C coarse pitch		0-15
6	Noise pitch			0-31
7	Mixer				See below
8	Channel A volume		0-15
9	Channel B volume		0-15
10	Channel C volume		0-15
11	Envelope fine duration		0-255
12	Envelope coarse duration	0-255
13	Envelope shape			0-15
14	I/O port
The Mixer is better treated as a BINary value, since each bit is a "flag" with a function to enable/disable:

Code: Select all

Bit	Use
D7	Unused (better left disabled)
D6	I/O
D5	Channel C Noise
D4	Channel B Noise
D3	Channel A Noise
D2	Channel C Tone
D1	Channel B Tone
D0	Channel A Tone
Note that, unlike many other places, here 0 is enable and 1 is disable. I.e.:
OUT 65533,7: OUT 49149, % BIN 11110100
... enables noise through channel A and tone through A and B.

Reading current values from a register

To do this, you can IN either 65533 or 49149, after selecting the wanted register first.
It means this:
OUT 65533,7: PRINT IN 65533 the same as this:
OUT 65533,7: PRINT IN 49149
...and both will return the current mixer settings (in decimal though)
The latter method is exclusive to +3 and Next; only the former could be used in earlier 128k Spectrums.

Example program

Code: Select all

#program stereo
#autoline 10,10
OUT 65533,254: ; use second AY chip
LET %i=0
PROC psgReg(8, 15) : ; A at full volume
PROC psgReg(10, 15): ; C at full volume
PROC psgReg(7, % BIN 11111010) : ; enable A & C
REPEAT : WHILE %i < 256
PROC psgReg(0, %i) : ; playing thru A
PROC psgReg(4, %255-i) : ; ... and C
LET %i=%i+1
PROC psgReg(7, 255) : ; silence everything
DEFPROC psgReg(register, value)
OUT 65533, register : OUT 49149,value
For the best experience, you should set "Stereo Mode" to "ABC"; it's the default, so if you haven't changed any startup options, you're fine.
Try using headphones, or another way to appreciate left and right channels on their own, and execute the program.
"psgReg" is a procedure to throw both needed OUTs consecutively, similar to the REG command for Next Registers.
Knowing that, try to understand what it does and how the effect was achieved.
Play around: try different speeds (3.5 to 28 MHz), and BREAK in the middle of the execution and hear what happens; don't worry, you can RUN it again and quit with Q.

Interesting reads: ... _AY-3-8910

References: ... trum/sound
Manual chapter 23, pages 272-273; look for "PSG Registers" ... 4838925707

Thanks to Dave Clarke and Remy Sharp on the ZX Spectrum Next Facebook group:

Who is online

Users browsing this forum: No registered users and 3 guests