Colm Cox delves into the inner secrets of the ST - beginning with
This is, hopefully, the first of a short series of
articles which aim to cover some of the more interesting features of
the Atari ST range of computers. In each article I aim to give
examples in ST Basic, C and 68000 assembly language – which I hope
will make the examples of some use to everyone.
This article covers the subject of sound. It would be
of benefit to have a short description of the YM-2149 sound chip
used in the ST so I'll start from there. To save space we'll call
the chip the PSG from now on.
The PSG has 3 independently programmable tone
generators i.e. 3 channels. A noise channel can be mixed with each
of the tone channels. The noise channel's pitch is under program
control and the tone channel's volume is also under control of a
program or 8 hardware volume envelopes.
The PSG has 14 registers which control the tone and
noise channels. A description of the registers is given below:
REG 0 and 1: Pitch control of channel 1. This
is a 12 bit value with the low 8 bits in REG 0, the high 4 bits in
the low 4 bits of REG 1. The lower the overall value the higher the
REG 2 and 3: Ditto for channel 2.
REG 4 and 5: Ditto for channel 3.
REG 6: Pitch control of noise channel. This is
a 5 bit value, and the lower the value the lower the pitch of noise.
REG 7: Mixer control. This register controls the overall
Output. Each sound channel can be tone only, noise only or tone and
noise. This register controls the combinations. Table 1 gives a
description of the use of each bit.
REG 8: The low 4 bits control volume of
channel 1 but if bit 4 is set then the volume is controlled by a
REG 9: Ditto for channel 2.
REG 10: Ditto for channel 3.
REG 11 and 12: The hardware envelope can last a certain
amount of time, called the sustain period. This register defines
REG 13: This register defines the shape of the envelope to be
used. The envelope in use is global to all channels, but what are
the shapes of the hardware envelope? If you look in the ST Basic
Source Book, under the command 'WAVE' a list of the envelope shapes
is given. What – it isn't there? The early sourcebooks were sent out
missing some vital diagrams! For those of us with an early manual,
myself included, Figure 1 shows the envelope shapes along with the
number to place in REG 13.
So now you know about the registers, how do you
access them? It is not possible to access the registers directly but
two locations, $FF8800 and $FF8802 are the answer.
$FF8800 WRITE – Register select, store the number of
the register you wish to access here.
$FF8800 READ – Read data, after storing the register number here,
reading this location will yield the value stored in that register.
$FF8802 WRITE – Store data, after storing the register number in
$FF8800 you can write to that register by storing the required value
$FF8802 READ – Always returns $FF
Note: The above registers are 8 bit registers.
NOW FOR THE PROGRAMS
Listing 1 is an example of using the above method to
program the PSG from ST Basic. For the BASIC programmer there is no
need to go to these lengths as ST Basic includes the necessary
commands, however the Basic Sourcebook
does not give the best description of the commands so the following
is a description relating the commands to the explanation of the PSG
SOUND CHANNEL, VOLUME, NOTE, OCTAVE, WAIT — Play the
note NOTE, in octave OCTAVE on channel CHANNEL at volume VOLUME and
wait for WAIT 50ths of a second before returning control to BASIC.
The only bad point of this command is that the large tone range of
the PSG is missed out by the fact that SOUND used musical notes
WAVE ENABLE, ENVELOPE, SHAPE, PERIOD, WAIT — ENABLE
controls the tone and noise output. Its value is stored in REG 7.
ENVELOPE enables/disables envelope control of volume on the low 3
bits of channels 1 to 3, a 1 meaning enable envelope control. This
parameter is related to REG 8 — REG 10. SHAPE is the shape of the
hardware envelope to be employed, and is stored in REG 13. PERIOD is
the period of the hardware envelope and is stored in REG 11 and 12.
WAIT has the same effect as in the SOUND command.
The only real advantage of accessing the PSG's
registers from BASIC is that you can alter the pitch of the noise
channel. A subroutine, along with a program which shows how to use
it, is given in Listing 2 — called NOISE.PITCH. NOISE.PITCH expects
the new pitch to be in a variable called N.P
DOING IT IN ASSEMBLY OR C
For the Assembly and C programmers, the hardware
registers are one way of producing exciting sound effects and music
with the ST. This section onwards will deal mainly with programming
in C and Assembly Language.
Direct access of the hardware registers is not the only way of using
the PSG. Atari thoughtfully provided 2 routines in the XBIOS (eXtended
Basic Input/Output System), they are: GIACCESS and DOSOUND.
This routine allows easy access of individual PSG
registers. The calling mechanism from Assembly Language is:
MOVE.W #REGISTER_NUMBER, -(SP)
MOVE.W #DATA_TO_WRITE, -(SP)
When writing, REGISTER_NUMBER has the high bit set,
when reading REGISTER_NUMBER's high bit is cleared. In the case of
read, DATA_TO_WRITE must still be pushed onto the stack. When
reading, the value returned is in D0.
This routine is called 'The Sound Processor', and is
a very useful routine. It requires a buffer containing a list of
'sound commands' which are processed by this routine. Calling
mechanism from Assembly is:
MOVE.L #BUFFER,-(SP) MOVE.W #32,-(SP)
Each byte in the buffer is either a command or data.
Each command requires some data.
$00 – $OF store a value in PSG register. These
commands store the next value in the PSG register specified by the
command, for example $00,$FF,$01,$EE stores $FF in REG 0 and $EE in
$80 stores the next value in a temporary register.
$81 – the first value specifies into which register
of the PSG the temporary register will be stored. The second value
is a 2's complement value. This value is added to the contents on
the register specified above. The last value is the end value – the
addition of the second value to the contents of the register will
continue until the value in the register reaches this value.
$82 – $FF – if the next value = 0 then control is
returned to the main program, otherwise sound processing is halted
for the time specified by the next value in 50ths of a second.
Note: It is important to end buffer with a command
such as: $82,$00 – which will return control to your program,
otherwise the sound processor will continue to process the RAM
contents, with some odd effects!
Use of each bit in Register 7
|Bit 0 —
||0 means channel 1 tone on
||1 means channel 1 tone off
|Bit 1 —
||0 means channel 2 tone on
||1 means channel 2 tone off
|Bit 2 —
||0 means channel 3 tone on
1 means channel 3 tone off
|Bit 3 —
||0 means channel 1 noise on
||1 means channel 1 noise off
|Bit 4 —
||0 means channel 2 noise on
||1 means channel 2 noise off
|Bit 5 —
||0 means channel 3 noise on
||1 means channel 3 noise off
THE ASSEMBLY AND C LISTINGS
Listings 3 and 4 are the required Assembly Language
interface between C and Assembly Language. Listing 3 is required for
HABA C, the C I use, which is in some respects a 'nonstandard' C.
Listing 4 is for 'standard' C - the Digital Research C, among
others. Either of these listings are required to run Listing 6.
The code is designed to allow it to be used in your
own programs. First of all type in and assemble the code specific to
your C, then whenever you wish to use one of these routines just
type, as the first line of your program:
extern short giaccess(),dosound();
and, at link time make sure you link in the listing
for your C.
That's about it for sound, the rest is up to you!
Listing 5 is for the Assembly Language programmers among us. The
amount of code does not justify the end result, but in general the
speed of Assembly Language is more than worth the extra effort.
Listing 6 is in C and shows just how fast C can be.
Some of the functions in this program may be of some use in your
programs. Try changing some of the parameters and try adding your
own effect routines - it's very easy!
In the next article I'll be taking the first of two
looks at graphics. Don't miss it!
If you have any questions on the article you may
write to me, Colm Cox, 10, Graigue Court, Poppintree, Ballymun,
DUBLIN 11, Ireland. Please enclose a S.A.E if you want a reply.