STFA v 2.02


Author: Seb/The Removers
This document is available here.


  1. Introduction
  2. Programming STFA
    1. XBIOS emulation
    2. STFA direct access

Introduction

STFA (Sound Treiber Für ATARI) is a sound driver for all ATARI computers and compatible. The point is to provide sound rendering through the standard Falcon XBIOS interface. Any application taking advantage of STFA capabilities will be able to play sound on every Atari computer from STF to Hades 60 without any effort. Many sound formats and many frequencies are supported: for example, signed or unsigned PCM sounds and Little Endian (Intel format) or Big Endian (Motorola format) 16 bit sounds may be directly rendered without preliminary conversion (the task is done in real time)! There are so many frequencies available (more than 500!) that applications should use the appropriate STFA call to set the nearest frequency to a given value.


Programming STFA

To test if STFA is installed, you should look for the cookie STFA in the Cookie Jar. The value of the cookie (read only) is a pointer to a structure named STFA_control.

Note that STFA can create a Cookie Jar if none is found (e.g. on STF computers) and makes it bigger if needed. So you can be sure that there will always be a cookie STFA when STFA is present.

Note also that STFA uses the XBRA protocol to perform every system call hook.


XBIOS emulation

There are two ways of XBIOS emulation depending on the availability of DMA sound on your system.

In both cases, the following XBIOS functions are emulated:
Locksnd()
LONG Locksnd(VOID);
Unlocksnd()
LONG Unlocksnd(VOID);
Soundcmd()
LONG Soundcmd(WORD mode,WORD data);
Setbuffer()
LONG Setbuffer(WORD reg,LONG begaddr,LONG endaddr);
Setmode()
LONG Setmode(WORD mode);
Setinterrupt()
LONG Setinterrupt(WORD mode,WORD cause);
Buffoper()
LONG Buffoper(WORD mode);
Devconnect()
LONG Devconnect(WORD source,WORD dest,WORD clk,WORD prescale,WORD protocol);
Sndstatus()
LONG Sndstatus(WORD reset);
Buffptr()
LONG Buffptr(SBUFFPTR *sptr);

Of course, it is a limited emulation. Indeed, sound recording and matrix settings are not supported.


If your system has DMA sound capability (i.e. STE/TT):
If your system has no DMA sound capability:

Locksnd()

LONG Locksnd(VOID)
Locksnd() prevents other applications from simultaneously attempting to use the sound system.
Opcode 128 (0x80)
Availability Available if the '_SND' cookie has bit #2 set.
Binding
        move.w  #$80,-(sp)
        trap    #14
        addq.l  #2,sp
Return Value Locksnd() returns 1 if the sound system was successfully locked or SNDLOCKED (-129) if the sound system was already locked.
Comments This call should be used prior to any usage of the 16-bit DMA sound system.
See Also Unlocksnd()


Unlocksnd()

LONG Unlocksnd(VOID)
Unlocksnd() unlocks the sound system so that other applications may utilize it.
Opcode129 (0x81)
Availability All TOS versions.
Binding
        move.w  #$81,-(sp)
        trap    #14
        addq.l  #2,sp
Return Value Unlocksnd() returns a 0 if the sound system was successfully unlocked or SNDNOTLOCK (-128) if the sound system wasn't locked prior to the call.
See Also Locksnd()


Soundcmd()

LONG Soundcmd(mode, data)

WORD mode, data;
Soundcmd() sets various configuration parameters in the sound system.
Opcode 130 (0x82)
Availability Available only when bit #2 of '_SND' cookie is set.
Parameters mode specifies how data is interpreted as follows:
Name
mode
Meaning
LTATTEN
0
Set the left attenuation (increasing attentuation is the same as decreasing volume). data is a bit mask as follows: XXXX XXXX LLLL XXXX'L' specifies a valid value between 0 and 15 used to set the attenuation of the left channel in -1.5db increments. The bits represented by 'X' are reserved and should be 0.
RATTEN
1
Set the right attentuation. data is a bit mask as follows: XXXX XXXX RRRR XXXX'R' specifies a valid value between 0 and 15 used to set the attenuation of the right channel in -1.5db increments. The bits represented by 'X' are reserved and should be 0
LTGAIN
2
Set the left channel gain (boost the input to the ADC). data is a bit mask as follows: XXXX XXXX LLLL XXXX'L' specifies a valid value between 0 and 15 used to set the gain of the left channel in 1.5db increments. The bits represented by 'X' are reserved and should be 0.
RTGAIN
3
Set the right channel gain (boost the input to the ADC). data is a bit mask as follows: XXXX XXXX RRRR XXXX'R' specifies a valid value between 0 and 15 used to set the gain of the right channel in 1.5Db increments. The bits represented by 'X' are reserved and should be 0.
ADDERIN
4
Set the 16 bit ADDER to receive its input from the source(s) specified in data. data is a bit mask where each bit indicates a possible souce. Bit 0 represents the ADC (ADDR_ADC). Bit 1 represents the connection matrix (ADDR_MATRIX). Setting either or both of these bits determines the source of the ADDER.
ADCINPUT
5
Set the inputs of the left and right channels of the ADC. data is a bit mask with bit 0 being the right channel: LEFT_MIC (0x00) or LEFT_PSG (0x02) and bit 1 being the left channel: RIGHT_MIC (0x00) or RIGHT_PSG (0x01).Setting a bit causes that channel to receive its input from the Yamaha PSG. Clearing a bit causes that channel to receive its input from the microphone.
SETPRESCALE
6
This mode is only valid when Devconnect() is used to set the prescaler to TT030 compatibility mode. In that case, data represents the TT030 compatible prescale value as follows: Name Value Meaning

CCLK_6K 0 Divide by 1280 (6.25 kHz)

CCLK_12K 1 Divide by 640 (12.5 kHz)

CCLK_25K 2 Divide by 320 (25 kHz)

CCLK_50K 3 Divide by 160 (50 kHz)

Setting data to SND_INQUIRE (-1) with any command will cause that command's current value to be returned and the parameter unchanged.
Binding
        move.w  data,-(sp)
        move.w  mode,-(sp)
        move.w  #$82,-(sp)
        trap    #14
        addq.l  #6,sp
Return Value Soundcmd() returns the prior value of the specified command if data is SND_INQUIRE (-1).Using the SETPRESCALE mode to set a frequency of 6.25 MHz (CCLK_6K) will cause the sound system to mute on a Falcon030 as it does not support this sample rate.
Caveats On current systems, a bug exists that causes a mode value of LTGAIN to set the gain for both channels.
See Also Devconnect()


Setbuffer()

LONG Setbuffer(mode, begaddr, endaddr)

WORD mode;

VOIDP begaddr;

VOIDP endaddr;
Setbuffer() sets the starting and ending addresses of the internal play and record buffers.
Opcode131 (0x83)
Availability Available when bit #2 of the '_SND' cookie is set.
Parameters mode specifies which registers are to be set. A mode value of PLAY (0) sets the play registers, a value of RECORD (1) sets the record registers. begaddr specifies the starting location of the buffer. endaddr specifies the first invalid location for sound data past begaddr.
Binding
        pea     endaddr
        pea     begaddr
        move.w  mode,-(sp)
        move.w  #$83,-(sp)
        trap    #14
        lea     12(sp),sp
Return Value Setbuffer() returns a 0 if successful or non-zero otherwise.
See Also Buffoper()


Setmode()

LONG Setmode(mode)

WORD mode;
Setmode() sets the mode of operation for the play and record registers.
Opcode132 (0x84)
Availability Available if bit #2 of the '_SND' cookie is set.
Parameters mode defines the playback and record mode as follows:
Name
mode
Meaning
MODE_STEREO8
0
8-bit Stereo Mode
MODE_STEREO16
1
16-bit Stereo Mode
MODE_MONO
2
8-bit Mono Mode
Binding
        move.w  mode,-(sp)
        move.w  #$84,sp
        trap    #14
        addq.l  #4,sp
Return Value Setmode() returns 0 if the operation was successful or non-zero otherwise.
Caveats Recording only works in 16-bit stereo mode.
See Also Buffoper()


Setinterrupt()

LONG Setinterrupt(mode, cause)

WORD mode, cause;
Setinterrupt() defines the conditions under which an interrupt is generated by the sound system
Opcode135 (0x87)
Availability Available when bit #2 of the '_SND' cookie is set.
Parameters mode configures interrupts to occur when the end of a buffer is reached. A value of INT_TIMERA (0) for mode sets Timer A, a value of INT_I7 (1) sets the MFP i7 interrupt. cause defines the conditions for the interrupt as follows:
Name
cause
Meaning
INT_DISABLE
0
Disable interrupt
INT_PLAY
1
Interrupt at end of play buffer
INT_RECORD
2
Interrupt at end of record buffer
INT_BOTH
3
Interrupt at end of both buffers
Binding
        move.w  cause,-(sp)
        move.w  mode,-(sp)
        move.w  #$87,-(sp)
        trap    #14
        addq.l  #6,sp
Return Value Setinterrupt() returns 0 if no error occurred or non-zero otherwise.
Comments If either buffer is in repeat mode, these interrupts can be used to double-buffer sounds.
See Also Buffoper()


Buffoper()

LONG Buffoper(mode )

WORD mode;
Buffoper() sets/reads the state of the hardware sound system.
Opcode136 (0x88)
Availability Available if '_SND' cookie has bit #2 set.
Parameters mode is a bit array which may be composed of all or none of the following flags indicating the desired sound system state as follows:
Name
Bit Mask
Meaning
PLAY_ENABLE
0x01
Enable DMA Sound Playback. The sound must have been previously identified to the XBIOS with the Buffptr() function.
PLAY_REPEAT
0x02
Setting this flag will cause any sound currently playing or started as a result of this call to be looped indefinitely (until Buffoper(0) is used).
RECORD_ENABLE
0x04
Enable DMA Sound Recording. The sound must have been previously identified to the XBIOS with the Buffptr() function.
RECORD_REPEAT
0x08
Setting this flag during a record will cause the recording to continue indefinitely within the currently set recording buffer (as set by Buffptr())
Alternately, calling this function with a mode parameter of SND_INQUIRE (1) will return a bit mask indicating the current sound system state as shown above.
Binding
        move.w  mode,-(sp)
        move.w  #$88,-(sp)
        trap    #14
        addq.l  #4,sp
Return Value Buffoper() normally returns 0 for no error or non-zero otherwise (except in inquire mode as indicated above.
Comments The sound system uses a 32 bit FIFO. The FIFO is only guaranteed to be clear when the record enable bit is clear. When transferring new data to the record buffers, the record enable bit should be cleared to flush the FIFO.
See Also Setbuffer()


Devconnect()

LONG Devconnect(source, dest, clk, prescale, protocol)

WORD source, dest, clk, prescale, protocol;
Devconnect() attaches a source device in the sound system to one or multiple destination devices through the use of the connection matrix.
Opcode139 (0x8B)
Availability Available if '_SND' cookie has bit #2 set.
Parameters source indicates the source device to connect as follows:
Name
source
Meaning
DMAPLAY
0
DMA Playback
DSPXMIT
1
DSP Transmit
EXTINP
2
External Input
ADC
3
Microphone/Yamaha PSG
dest is a bit mask which is used to choose which destination devices to connect as follows:
Name
Mask
Meaning
DMAREC
0x01
DMA Record
DSPRECV
0x02
DSP Receive
EXTOUT
0x04
External Out
DAC
0x08
DAC (Headphone or Internal Speaker)
clk is the clock the source device will use as follows:
Name
clk
Meaning
CLK_25M
0
Internal 25.175 MHz clock
CLK_EXT
1
External clock
CLK_32M
2
Internal 32 MHz clock
prescale chooses the source clock prescaler. Sample rate is determined by the formula: Valid prescaler values for the internal CODEC using the 25.175 MHz clock are:
Name
prescale
Meaning/Sample Rate
CLK_COMPAT
0
TT030/STe compatiblity mode. Use prescale value set with Soundcmd().
CLK_50K
1
49170 Hz
CLK_33K
2
32880 Hz
CLK_25K
3
24585 Hz
CLK_20K
4
19668 Hz
CLK_16K
5
16390 Hz
CLK_12K
7
12292 Hz
CLK_10K
9
9834 Hz
CLK_8K
11
8195 Hz
protocol sets the handshaking mode. A value of HANDSHAKE (0) enables handshaking, NO_SHAKE (1) disables it. When transferring sound or video data through the CODEC it is usually recommended that handshaking be disabled. When incoming data must be 100% error free, however, handshaking should be enabled.
Binding
        move.w  protocol,-(sp)
        move.w  prescale,-(sp)
        move.w  clk,-(sp)
        move.w  dest,-(sp)
        move.w  source,-(sp)
        move.w  #$8B,-(sp)
        trap    #14
        lea     12(sp),sp
Return Value Devconnect() returns 0 if the operation was successful or non-zero otherwise.
Caveats Setting the prescaler to an invalid value will result in a mute condition.
See Also Soundcmd()


Sndstatus()

LONG Sndstatus(reset)

WORD reset;
Sndstatus() can be used to test the error condition of the sound system and to completely reset it.
Opcode140 (0x8C)
Availability Available only when bit #2 of the '_SND' cookie is set.
Parameters reset is a flag indicating whether the sound system should be reset. A value of SND_RESET (1) will reset the sound system.
Binding
        move.w  reset,-(sp)
        move.w  #$8C,-(sp)
        trap    #14
        addq.l  #4,sp
Return Value Sndstatus() returns a LONG bit array indicating the current error status of the sound system defined as follows:
Bit(s)
Meaning
0-3
These bits form a value indicating the error condition of the sound system as follows:
Name  Mask  Meaning
SND_ERROR 0xF  Use to mask error code
 
Name  Mask  Meaning
SND_OK 0  No Error
SND_BADCONTROL 1  Invalid Control Field
SND_BADSYNC 2  Invalid Sync Format
SND_BADCLOCK 3  Clock out of range
4
If this bit is set, left channel clipping has occurred. Use the mask SND_LEFTCLIP (0x10) to isolate this bit.
5
If this bit is set, right channel clipping has occurred. Use the mask SND_RIGHTCLIP (0x20) to isolate this bit.
6-31
Unused.
Comments On reset, the following things happen: DSP is tristated
  • Gain and attentuation are zeroed
  • Old matrix connections are reset
  • ADDERIN is disabled
  • Mode is set to 8-Bit Stereo
  • Play and record tracks are set to 0
  • Monitor track is set to 0
  • Interrupts are disabled
  • Buffer operation is disabled


Buffptr()

LONG Buffptr(sptr)

SBUFPTR *sptr;
Buffptr() returns the current position of the playback and record pointers.
Opcode141 (0x8D)
Availability Available if '_SND' cookie has bit #2 set.
Parameter sptr is a pointer to a SBUFPTR structure which is filled in with the current pointer values. SBUFPTR is defined as follows:
typedef struct
{
    VOIDP playptr;
    VOIDP recordptr;
    VOIDP reserved1;
    VOIDP reserved2;
} SBUFPTR;
Binding
        pea     sptr
        move.w  #$8d,-(sp)
        trap    #14
        addq.l  #6,sp
Return Value Buffptr() returns 0 if the operation was successful or non-zero otherwise.
See Also Setbuffer(), Buffoper()




STFA direct access

The STFA_control is a structure which allows you to control STFA. The following table describes every field of this structure.

Name Size Explanation STFA version
sound_enable 2 bytes
bit 0 0=stop the sound
1=play the sound
bit 1 0=play the sound once
1=play the sound and loop
1.00
sound_control 2 bytes
bits 0-3 0=5000 Hz
1=6250 Hz
2=7500 Hz
3=8200 Hz
4=9800 Hz
5=11025 Hz
6=12500 Hz
7=15000 Hz
8=16400 Hz
9=19700 Hz
10=22050 Hz
11=25000 Hz
12=30000 Hz
13=32800 Hz
14=44100 Hz
15=49200 Hz
bit 4 0=preset frequency
1=user frequency
bit 9 0=motorola
1=intel
bit 10 0=1x
1=2x
bit 11 Deprecated use
bit 12 Deprecated use
bit 13 0=8 bits
1=16 bits
bit 14 0=mono
1=stereo
bit 15 0=unsigned
1=signed
1.00
sound_output 2 bytes Originally used to set STFA output device. The programmer should not modify this field since the Configuration CPX is designed to do it correctly (i.e. conforming to the drivers_list field). 1.00
sound_start 4 bytes Starting address of the sound 1.00
sound_current 4 bytes Current address of the sound 1.00
sound_end 4 bytes End address of the sound 1.00
version 2 bytes STFA Version
The higher byte of this word is the major version number and the lower byte the minor version number.
1.00
old_vbl 4 bytes Deprecated use. 1.00
old_timerA 4 bytes Address of the old Timer A routine 1.00
old_mfp_status 4 bytes Address of a table which contains the old MFP status.
The table is:
old_IERA1 byte ($fffffa07)
old_IPRA1 byte ($fffffa0b)
old_ISRA1 byte ($fffffa0f)
old_IMRA1 byte ($fffffa13)
old_TACR1 byte ($fffffa19)
1.00
stfa_vbl 4 bytes Address of the STFA VBL vector routine. 1.01
drivers_list 4 bytes Address of a structure begining with a word containing the number of installed drivers. Following are the names of these drivers in C format strings each of length 23 (including the terminating null byte). 1.03
play_stop 4 bytes Address of a routine that process changes done in sound_enable (it allows you not to wait the next VBL to start a sound). 2.00
timer_a_setting 2 bytes Data to configure the Timer A.
The higher byte is the value for the CONTROL register and the lower byte is the value for the DATA register.
It is used if bit #4 of sound_control is set to 1.
2.00
set_frequency 4 bytes Address of a routine that sets correctly the field timer_a_setting to a custom frequency available through the Timer A. The parameter is an unsigned word given on the stack specifying the frequency in Hertz.
The function returns 0 if successful. In that case, the bit #4 of sound_control is set to 1.
LONG set_frequency(UWORD frequency_in_hertz);
2.00
frequency_treshold 2 bytes This unsigned value is used by the set_frequency function. If the asked value is over this treshold, set_frequency will automatically set the bit #10 (2x mode) in the sound_control field. If the asked value is below this treshold, the bit #10 of sound_control is cleared. This possibility is useful on system that may have a lack of power to render high frequency sounds. Note that the application may change this bit after calling set_frequency or may desactivate the treshold possibility by using the value 65535 as treshold. 2.00
custom_freq_table 4 bytes This field is a pointer to 3 custom tables of 11 unsigned words listing the frequencies available through Devconnect with prescale ranging from 1 to 11. Each of these 3 consecutive tables corresponds to a value of clk ranging from 0 to 2.
If this pointer is set to NULL (0) then the customisation is disabled and original Falcon frequencies (with an external 22.5792 MHz clock) are used.
2.00
stfa_on_off 2 bytes
This field is used to force XBIOS emulation through non DMA devices with a value of STFA_ON (-1).
A value of STFA_OFF (0) will have different meanings depending on available hardware and software.
If XBIOS functions are not available and DMA sound is available (e.g. STE/TT)
Then XBIOS emulation uses DMA output instead of other output devices.
In other cases (e.g. on Falcon or STF)
Then XBIOS emulation is disabled.
2.00
new_drivers_list 4 bytes Address of a table of long words that are the address of the strings that describes the drivers. The length of this table is equal to the number of the drivers (conforming to the first word of the drivers_list structure). This field has been created in order to make a pop-up menu in the CPX configuration tool. 2.00
old_bit_2_of_cookie_snd 4 bytes This field contains the old value of the bit # 2 of the cookie '_SND' ie old_value_of_cookie_SND && 0x0004 because the VBL routine of STFA modify this bit according the configuration of STFA... 2.00
it 4 bytes This field contains either NULL or the address of a function that will be called at the end of play buffer (in repeat mode or not). The function is called in supervisor mode at IPL 7 and should terminate by a rte. All the registers should be saved and restored. This field is erased (set to NULL) just before the call of the function (to prevent from inconsistencies). 2.00