From CPCWiki - THE Amstrad CPC encyclopedia!
(Redirected from AY-3-8912)
Jump to: navigation, search

The Programmable Sound Generator (PSG) of the CPC is an AY-3-8912 chip. It is able to output three separate sound channels (named Channel A, B and C). Each channel can be used to output tones and/or white noise.

PSG Registers

The PSG has 16 read/writeable data registers, and a write-only index register. Both the index and data registers are accessed through PIO Port A, depending on the current setting of the BC1 and BDIR bits in PPI Port C. The four possible combinations are:

 0=inactive    2=write data
 1=read data   3=write index

The procedure to write data to a specific register is as follows: Write the register number to PPI Port A, set BC1/BDIR to Write Index - and back to Inactive. Now write the data to PIO Port A, set BC1/BDIR to Write Data - and back to Inactive.

00h - Channel A Tone Frequency Low (8bit)

01h - Channel A Tone Frequency High (4bit)

02h - Channel B Tone Frequency Low (8bit)

03h - Channel B Tone Frequency High (4bit)

04h - Channel C Tone Frequency Low (8bit)

05h - Channel C Tone Frequency High (4bit)

The tone (square wave) frequency in Hertz is calculated as follows:

 F = 1MHz / 16 / nn      ;with nn in range 1..4095 (nn=0 acts as nn=1)

Possible frequencies are in range from 62500Hz (nn=1) down to approx. 15.26Hz (nn=4095).

06h - Noise Frequency (5bit)

The noise frequency in Hertz is calculated as follows:

 F = 1MHz / 16 / nn      ;with nn in range 1..31 (nn=0 acts as nn=1)

Noise can be output on all 3 channels, but there is only one noise generator (so all channels share the same noise frequency). The noise generator consists of 17bit shift register, and a 1bit noise level (0=LOW or 1=HIGH). These are updated at the selected frequency as follows:

 noise_level = noise_level XOR shiftreg.bit0
 newbit = shiftreg.bit0 XOR shiftreg.bit3
 shiftreg = (shiftreg SHR 1) + (newbit SHL 16)

Note that level isn't set equal to bit0, instead, it toggles when bit0=1.

07h - Mixer Control Register

The control register enables or disables the sound channels. Each channel can output a Tone and/or Noise.

 Bit 0  Channel A Tone   (1=off, 0=on)
 Bit 1  Channel B Tone   (1=off, 0=on)
 Bit 2  Channel C Tone   (1=off, 0=on)
 Bit 3  Channel A Noise  (1=off, 0=on)
 Bit 4  Channel B Noise  (1=off, 0=on)
 Bit 5  Channel C Noise  (1=off, 0=on)
 Bit 6  Port A Direction (1=output, 0=input) (should be always 0 for CPC)
 Bit 7  Port B Direction (1=output, 0=input) (not used in CPC)

If both Tone and Noise are disabled on a channel, then a constant HIGH level is output (useful for digitized speech). If both Tone and Noise are enabled on the same channel, then the signals are ANDed (the signals aren't ADDed) (ie. HIGH is output only if both are HIGH).

08h - Channel A Volume (0-0Fh=volume, 10h=use envelope instead)

09h - Channel B Volume (0-0Fh=volume, 10h=use envelope instead)

0Ah - Channel C Volume (0-0Fh=volume, 10h=use envelope instead)

Defines the volume, 0=off, 15=max. If bit4=1, then the volume is taken from the envelope generator. The volume is non-linear. Below formula does comply with the PSG datasheet, and does more or less match the voltages measured on the CPCs speaker (the voltages on the CPCs stereo connector seem to be slightly different though).

 amplitude = max / sqrt(2)^(15-nn)
 eg. 15 --> max/1, 14 --> max/1.414, 13 --> max/2, etc.

The volume affects only HIGH levels. LOW levels are always NULL. Ie. sound output toggles between +VOL and NULL (not between +VOL and -VOL).

Digitized samples can be written to the volume registers (mind that volume is non-linear). When doing that, it's best to switch the channel to constant HIGH level (by disabling both Tone and Noise). Another method would be to set tone frequency to 000h or 001h (the resulting frequency is too high to be audible, so the HIGH/LOW levels sound like a constant HALF level).

0Bh - Volume Envelope Frequency Low (8bit)

0Ch - Volume Envelope Frequency High (8bit)

Envelope step frequency (tone or noise) calculated as follows:

 F = 1MHz / 16 / nn      ;with nn in range 1..65535 (nn=0 acts as nn=1)

Depending on the envelope shape, the volume is incremented from 0 to 15, or decremented from 15 to 0. In either case it takes 16 steps to complete, the completion time for 16 steps is therefore:

 T = nn*256 / 1MHz      ;with nn in range 1..65535 (256us .. 16.7 seconds)

0Dh - Volume Envelope Shape (4bit)

Writing to this register (re-)starts the envelope. Additionally, the written value specifies the envelope shape, the four bits have the following meaning:

 Bit 0  Hold        (1=stop envelope past first cycle)
 Bit 1  Alternate   (1=reverse direction at end of each cycle)
 Bit 2  Attack      (1=initial direction increase)
 Bit 3  Continue    (0=same as if Bit0=1 and Bit1=Bit2)

The possible combinations and resulting shapes are:

 Binary  Hex      Shape
 00XX    00h-03h  \_________  (same as 09h)
 01XX    04h-07h  /_________  (same as 0Fh)
 1000    08h      \\\\\\\\\\
 1001    09h      \_________  (volume remains quiet)
 1010    0Ah      \/\/\/\/\/
 1011    0Bh      \"""""""""  (volume remains high)
 1100    0Ch      //////////
 1101    0Dh      /"""""""""  (volume remains high)
 1110    0Eh      /\/\/\/\/\
 1111    0Fh      /_________  (volume remains quiet)

When using the volume envelope generator, the volume is always increased from 00h to 0Fh (or vice versa), it is not possible to specify a starting/ending point (like from 00h to 07h).

0Eh - External Dataregister Port A

This register receives data from the CPC keyboard (or joystick), for more information read the chapter about the CPC Keyboard Matrix. This register can be also used as output port by setting bit 6 of the PSG control register to 1 (that would allow to use the six data pins of the joystick connector to output data to external hardware).

0Fh - External Dataregister Port B

This register is not used in CPC computers. In detail, a AY-3-8910 sound chip would have external connectors for this register, so that it could be used as a further IO port, but the CPC's sound chip (AY-3-8912, in 28 pin package) doesn't have such connectors, even though the register still does exist internally. The Aleste 520EX (russian CPC clone) is a special case: does have a 8910 chip, with PSG Port B being used as 8bit printer port data.

Mono and Stereo Output

When using the CPC's external stereo jack, channel A is output to the right, channel C is output left, and channel B is output to both left and right, in that case channel B is output through a bigger resistor to prevent that this channel appears louder than the others.

Otherwise (when using the built-in speaker), all three channels are mixed at the same intensity. This signal appears to be also sent to the Tape output line also, so a connected Data Recorder could be used to record CPC music also.

Noise Generator

The noise generator uses a Linear-Feedback Shift Register algorithm.

According to the MAME developers, the Random Number Generator of the 8910 is a 17-bit shift register. The input to the shift register is bit0 XOR bit3. Bit0 is the output. This was verified on AY-3-8910 and YM2149 chips.

D/A converter table

These are the 16-bit values used in Arkos Tracker. They are more accurate than the datasheet you can find, as they were tested electronically by Grim and Zik directly from a real CPC:

0, 231, 695, 1158, 2084, 2779, 4168, 6716, 8105, 13200, 18294, 24315, 32189, 40757, 52799, 65535

For the record, these are Matthew (Gasman) Westcott measurements (normalised) on its ZX Spectrum:

0, 0.0105, 0.0154, 0.0216, 0.0314, 0.0461, 0.0635, 0.1061, 0.1319, 0.2163, 0.2973, 0.3908, 0.5129, 0.6371, 0.8186, 1

ay3 manual show different values: 2 steps down = half values down.

Thus, the theoretical formula is f(x) = 2 ^ ((x - 15) / 2) with x between 0 and 15.

This is the volume table used by BSC: PSG DAC volume table.jpg

ETO once started testing the output levels (to be fair, with a multimeter only) and it was very close to the theoretical value based on the data sheet and how the CPC mixes the channels.

See Discussion on the forum

Block Diagram

  • PSG Block Diagram.png


The PSG is driven by an external clock at 1MHz provided by the Gate Array. The AY chip has an internal clock divider by 8 which means that it works internally at 125KHz, outputting 125,000 samples per second for each channel.

The BC2 and A8 pins are always equal to 1 as they are connected to +5V. The /A9 pin is non-existent on the AY-3-8912 model.