Author:
Seb/The Removers
This document is available
here.
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.
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.
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:Of course, it is a limited emulation. Indeed, sound recording and matrix settings are not supported.
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() |
LONG Unlocksnd(VOID)
Unlocksnd() unlocks the sound system so that other applications may utilize it. | |
Opcode | 129 (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() |
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: | ||
Meaning | |||
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. | |||
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 | |||
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. | |||
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. | |||
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. | |||
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. | |||
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() |
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. | |
Opcode | 131 (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() |
LONG Setmode(mode)
WORD mode;
Setmode() sets the mode of operation for the play and record registers. | |||||
Opcode | 132 (0x84) | ||||
Availability | Available if bit #2 of the '_SND' cookie is set. | ||||
Parameters | mode defines the playback and record mode as follows: | ||||
Name | Meaning | ||||
MODE_STEREO8 | 8-bit Stereo Mode | ||||
MODE_STEREO16 | 16-bit Stereo Mode | ||||
MODE_MONO |
| 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() |
LONG Setinterrupt(mode, cause)
WORD mode, cause;
Setinterrupt() defines the conditions under which an interrupt is generated by the sound system | |||||
Opcode | 135 (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 | Meaning | ||||
INT_DISABLE | Disable interrupt | ||||
INT_PLAY | Interrupt at end of play buffer | ||||
INT_RECORD | Interrupt at end of record buffer | ||||
INT_BOTH | 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() |
LONG Buffoper(mode )
WORD mode;
Buffoper() sets/reads the state of the hardware sound system. | |||
Opcode | 136 (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 |
| Meaning | |
PLAY_ENABLE |
|
Enable DMA Sound Playback. The sound must have been previously identified to the XBIOS with the Buffptr() function. | |
PLAY_REPEAT | 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 | Enable DMA Sound Recording. The sound must have been previously identified to the XBIOS with the Buffptr() function. | ||
RECORD_REPEAT |
|
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() |
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. | ||||||||
Opcode | 139 (0x8B) | |||||||
Availability | Available if '_SND' cookie has bit #2 set. | |||||||
Parameters | source indicates the source device to connect as follows: | |||||||
Name |
| Meaning | ||||||
DMAPLAY |
| DMA Playback | ||||||
DSPXMIT |
| DSP Transmit | ||||||
EXTINP |
| External Input | ||||||
ADC |
| Microphone/Yamaha PSG | ||||||
dest is a bit mask which is used to choose which destination devices to connect as follows: | ||||||||
Name |
| Meaning | ||||||
DMAREC |
| DMA Record | ||||||
DSPRECV |
| DSP Receive | ||||||
EXTOUT |
| External Out | ||||||
DAC |
|
DAC (Headphone or Internal Speaker) | ||||||
clk is the clock the source device will use as follows: | ||||||||
Name |
| Meaning | ||||||
CLK_25M |
| Internal 25.175 MHz clock | ||||||
CLK_EXT |
| External clock | ||||||
CLK_32M |
| 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 |
| Meaning/Sample Rate | ||||||
CLK_COMPAT |
|
TT030/STe compatiblity mode. Use prescale value set with Soundcmd(). | ||||||
CLK_50K |
| 49170 Hz | ||||||
CLK_33K |
| 32880 Hz | ||||||
CLK_25K |
| 24585 Hz | ||||||
CLK_20K |
| 19668 Hz | ||||||
CLK_16K |
| 16390 Hz | ||||||
CLK_12K |
| 12292 Hz | ||||||
CLK_10K |
| 9834 Hz | ||||||
CLK_8K |
| 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() |
LONG Sndstatus(reset)
WORD reset;
Sndstatus() can be used to test the error condition of the sound system and to completely reset it. | ||||||||||||||||||||||||||
Opcode | 140 (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: | |||||||||||||||||||||||||
Meaning | ||||||||||||||||||||||||||
These bits form a value indicating the error condition of
the sound system as follows:
|
||||||||||||||||||||||||||
If this bit is set, left channel clipping has occurred. Use the mask SND_LEFTCLIP (0x10) to isolate this bit. | ||||||||||||||||||||||||||
If this bit is set, right channel clipping has occurred. Use the mask SND_RIGHTCLIP (0x20) to isolate this bit. | ||||||||||||||||||||||||||
Unused. | ||||||||||||||||||||||||||
Comments |
On reset, the following things happen: DSP is tristated
|
LONG Buffptr(sptr)
SBUFPTR *sptr;
Buffptr() returns the current position of the playback and record pointers. | |
Opcode | 141 (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() |
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 |
|
1.00 | ||||||||||||||||||
sound_control | 2 bytes |
|
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:
|
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.
|
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 |
A value of STFA_OFF (0) will have different meanings depending on available hardware and software.
|
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 |