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.
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.
The Mixer is better treated as a BINary value, since each bit is a "flag" with a function to enable/disable:
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
Note that, unlike many other places, here 0 is enable and 1 is disable. I.e.:
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
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
...is 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.
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.
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 REPEAT UNTIL INKEY$ ="q" PROC psgReg(7, 255) : ; silence everything STOP DEFPROC psgReg(register, value) OUT 65533, register : OUT 49149,value ENDPROC
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.
https://en.wikipedia.org/wiki/General_I ... _AY-3-8910
http://www.breakintoprogram.co.uk/compu ... trum/sound
Manual chapter 23, pages 272-273; look for "PSG Registers"
https://www.facebook.com/retrobeachmang ... 4838925707
Thanks to Dave Clarke and Remy Sharp on the ZX Spectrum Next Facebook group: