WACCI 137 Index - Home Page www.wacci.org.uk

01 - Thanx & Stuff 02 - Fair Comment 03 - New Generation 04 - Exploring the PSG
05 - Programmers' Patch 06 - CPC Changed My Life 07 - Cartography

img_137_04_01.gif - 4,975 bytes

Exploring the PSG

James Hoskisson explains the intricacies of the AY-3-8912 PSG - otherwise known as the CPC's sound chip

Since you should now have at least some understanding of the PPI, the next chip on the list is the PSG.

James Gets it Wrong Again!

You may remember that last time I said that nearly all of the chips in the CPC use the Intel I/O convention; the PSG is yet another exception to the rule! In case you hadn't guessed, PSG actually stands for Programmable Sound Generator, in that it is Programmable and it Generates Sound.
  The PSG was actually designed to be used with the CP1610 range of processors, which accounts for the strange I/O operation. This problem is negated within the CPC, since the PSG is attached to the PPI, which can generate any kind of signals.

Interfacing With the PSG

The PSG is actually quite easy to use once you figure out the slightly irregular addressing mode. If you have a decent grip on the commands associated with sound production in BASIC, then the PSG should be a doddle to use, since a lot of the functions of the PSG are equivalent to aspects of the BASIC sound commands.
  The PSG is designed to work in both input and output modes. The direction of the data flow is determined by the state of the Bus DIRection (BDIR) pin. If the BDIR pin is high, then the PSG will be in input mode, if it is low the PSG will output data. Things get a little trickier when the other control pins are taken into account, but that's basically how it works.
  There are two other pins involved in interfacing with the PSG. These are the two Bus Control pins, namely BC1 and BC2. These pins determine whether the PSG is receiving a register address, receiving write data, inactive, or outputting data. The four states are determined by checking the status of all three pins as follows:

BC1     BC2     BDIR    Function

0       0       0       Inactive
0       0       1       Latch Address
0       1       0       Inactive
0       1       1       Read from PSG
1       0       0       Latch Address
1       0       1       Inactive
1       1       0       Write to PSG
1       1       1       Latch Address

And now, to explain:

The way the PSG is wired up to the PPI makes using it a little counter intuitive. This is because the data on the PSG data lines must be present BEFORE any of the control signals change state. This means that the data to send has to be written to &F400, before the control signals are changed by OUTing to &F600. This may make more sense with an example:

LD BC,&F400 ;Put the data, for the register
OUT (C),C   ;to select, on the data bus.
LD BC,&F6C0 ;Tell the PSG that you want
OUT (C),C   ;to select register 0.
LD BC,&F600 ;Put the PSG in the inactive state.
LD BC,&F4FF ;Set up the data to write
OUT (C),C   ;to register 0.
LD BC,&F680 ;Tell the PSG that the data
OUT (C),C   ;is to be written to register 0.
LD BC,&F600 ;Return the PSG to the inactive state.

The example only writes 255 to register 0, but it is quite lengthy, due in part to the extra INACTIVE state selects. Without telling the PSG to ignore the data on the data bus, the new value, that is to be written to the register, would be used to select a register (which would probably be 7 in this case, since there isn't a register 255.) This could cause many problems because the new data would be written to the wrong register.

PSG Shortcuts

If you looked closely at the table you may have realised that some of the commands are repeated! If you looked even more closely you may have recognised that one of the BC signals is redundant, since all of the different modes of operation can be accessed with BC2 high. This is no coincidence. The chip was designed this way so that the decoding circuitry could be simplified, if it wasn't being used with a CP1610 processor. Amstrad took advantage of this in designing the CPC, and tied the BC2 pin to +5V, which meant only the BDIR and BC1 signals would have to be routed to the PPI.

The Useful Information

Right, now all the academic stuff is out of the way, let's get down to operating the chip.
  As you already know the PSG is solely attached to the PPI (except for the power, address, and clock lines, of course!) All of the data lines of the PSG are attached to port A of the PPI. The two controls lines, BDIR and BC1, are attached to the top two bits of port C. You should already know how to set up the PPI to input and output the data from the ports, so I won't bother explaining it again.
  As I already mentioned there are 15 registers in the PSG. These are:

Register        Function

   0            Channel A tone period (fine tune)
   1            Channel A tone period (coarse tune)
   2            Channel B tone period (fine tune)
   3            Channel B tone period (coarse tune)
   4            Channel C tone period (fine tune)
   5            Channel C tone period (coarse tune)
   6            Noise generator
   7            Mixer control
   8            Channel A volume/Hardware envelope enable
   9            Channel B volume/Hardware envelope enable
  10            Channel C volume/Hardware envelope enable
  11            Hardware envelope period (fine tune)
  12            Hardware envelope period (coarse tune)
  13            Hardware envelope shape
  14            I/O Port data (Used for reading the keyboard)

Tone Generators: Registers 0-5 control the pitch of the note. The value is exactly the same as for the BASIC SOUND command, so the values can be looked up in the CPC handbook.
  The lower register of each of the sound channels is 8 bits, with the upper register being 4 bits. The lower 4 bits (i.e. bits 0-3) of the most significant byte of the tone registers are used, with the upper 4 bits being ignored. This gives a range of 4096 possible tone values for each channel.

Noise Generator: This 5-bit register determines the amount of "noise" there is. The channel(s) that the noise is played on can be set using the mixer register, but the noise value is the same on each channel i.e. it is not possible to have two or three different noise values sounding simultaneously.
  The value written to this register is exactly the same as the "noise" parameter in the SOUND command. The noise value can be anything from 0 to 31, with the lower values giving more of a hissing sound, and the higher values a grating sound.

Mixer Register: This is a 7-bit register which controls the I/O port, which channels have noise, and which channels should be sounding. The functions are allocated as follows:

Bit 7:  Not used.
Bit 6:  I/O Port control.
Bit 5:  Channel C enable/disable noise.
Bit 4:  Channel B enable/disable noise.
Bit 3:  Channel A enable/disable noise.
Bit 2:  Channel C enable/disable tone.
Bit 1:  Channel B enable/disable tone.
Bit 0:  Channel A enable/disable tone.

Whether the I/O port operates in Input or Output mode is determined by bit 6. If it is 1 then the port is set to output. If it is 0 then the port operates as an input (as used for keyboard scanning).
  Bits 5-3 control which channels output the noise. If any of the bits are 1 then the noise is disabled for the channel. If they are 0 then the noise is enabled on the channel. Therefore, to disable noise output completely, all three of the bits would be set to 1.
  Bits 2-0 control which of the channels output the tones that are programmed in to registers 0-5. If the bits are 1 then the tone is disabled, if they are 0 then the tone is enabled. These bits are useful if three notes are to be played at once, because the tone values can be set up in registers 0-5 and then all the channels can be enabled simultaneously.
  One thing that isn't made clear in the PSG datasheet is that once a channel is enabled, the tone that plays will continue indefinitely, until the channel is disabled, or the tone is changed. This also applies to the noise output.

Channel Volume Control: As the name suggests these channels control the volume level for each of the channels, as well as whether hardware enveloping is to be used on the channel. Each channel has a dedicated volume register, so the volume of the different sounds can be controlled independently of one another.
  Each of the 5 bit registers are arranged as follows:

Bit 7:  } Not used
Bit 6:  }
Bit 5:  }
Bit 4:  Amplitude mode
        1: Enable hardware enveloping,
        0: Disable hardware enveloping.
        (Use amplitude specified in bits 3-0)
Bit 3:  } Amplitude (0-15)
Bit 2:  }
Bit 1:  }
Bit 0:  }

The Amplitude Mode bit determines whether the hardware envelope is to be used with the channel. If it is 1 then hardware enveloping is enabled. If it is 0 hardware enveloping is disabled.
  The lower 4 bits (i.e. bits 0-3) are used to set the volume value for the channel. The value is exactly the same as in the BASIC SOUND command. The volume ranges from 0 (inaudible) to 15 (loudest) and is arranged on a logarithmic scale, with the difference in volume increasing more between the larger values.

Hardware Envelope Length: One of the main concerns, if you are trying to reproduce a sound, is the length of the hardware envelope. Bearing that in mind, I should probably tell you what a hardware envelope is! The hardware envelope is just like the ENV command in BASIC, in that it allows the volume of the sound to alter throughout its production. This is especially useful when you are trying to copy instruments, such as a Piano, which has a sharp attack and a relatively short sustain.
  The length of the hardware envelope determines how long one cycle of the envelope will take. This in turn determines how long each step in the hardware envelope is, since the number of steps in each envelope is constant. Confused? It may be a little clearer after you've read about register 13.
  The two 8 bit registers, R11 and R12, control the length of the hardware envelope. The time that the hardware envelope will take to complete one cycle is calculated thus:

Cycle Frequency = (PSG clock/256)/register value
Cycle Period = (4*Register value)/15625
Register Value = (15625/4) * Cycle Period = 15625/(4*Cycle Frequency)

The bottom equation is the only one that you'll really need, but I thought I'd save you a little arithmetic! As you probably guessed, the register value has to be an integer number, but that shouldn't cause too much of a problem - who's going to notice the odd few ten thousandths of a second?
  I should also point out that the PSG clock frequency in the CPC is 1Mhz! You may need to know that to calculate the Cycle Frequency!

Hardware Envelope Shape: This is a 4-bit register that indicates to the PSG what kind of envelope will be used. Since it is a hardware envelope, you are only allowed to specify one at a time, unlike the BASIC ENV command. This means that more complex envelopes will have to be produced by altering the volume values 'manually' by means of registers 8-10.
  The pattern of the lower 4 bits of Register 13 determines the shape of the envelope. Unfortunately, there are only 10 different envelope shapes, so some combinations are obsolete. The whole selection looks something like this:

img_137_04_02.gif - 2,047 bytes

  The 'Envelope Shape' patterns determine the sequence with which the volume level changes. The peaks on the pattern show the greatest volume, and the troughs show the lowest. It might also be handy to know that each pattern is supposed to have sixteen states per cycle, so you should be able to calculate the length of each state pretty easily.
  To clear up any confusion, the patterns which appear to be repeating in the diagram will repeat ad infinitum, whereas those that flatten out don't repeat, once they have completed one cycle. I was a little unsure of this at first, so I thought it might be wise to clarify it for you.

I/O Port: The I/O port is dead simple to use, once the data direction has been selected from the mixer register. Register 14 acts as an intermediary stage between the data lines of the PSG and the I/O port lines. Whatever is written to register 14 will be latched on to the output lines and whatever is on the I/O lines will be relayed to register 14.
  In the CPC the I/O port of the PSG is connected up to the keyboard, so it is used to carry out keyboard scanning. The port can be used as an output, without damaging anything, which allows the Joystick Port to be used for other things apart from input devices. It is possible, for example, to make a parallel interface, which can be attached to the joystick port. More details on keyboard scanning and the I/O port can be found in the next issue.

The End - but Not Quite!

Well, that explains the PSG in all its glory - almost! The PSG is used for keyboard scanning, but the PPI is also, so I've decided to dedicate the next article to this, as well as the Centronics Port Latch. Judging by the size of this article it might be split into two. If this happens (which it already will have, if you're reading this in the second part of the article!) you'll have to wait until the issue after that.
  Okay, I'm going for a lie down! [And me too... no program I could find would read the supposedly RTF file James sent this as, so it's been reconstructed by hand, and all the tables, which didn't come through, rewritten with help from Kevin Thacker's excellent website. - Richard] Bye.

01 - Thanx & Stuff 02 - Fair Comment 03 - New Generation 04 - Exploring the PSG
05 - Programmers' Patch 06 - CPC Changed My Life 07 - Cartography

WACCI 137 Index - Home Page www.wacci.org.uk