ProSOUND logo by LST

ProSOUND Driver

(not only a driver, in fact)

1 - What is ProSOUND ?

The full version includes a board that you must plug to the parallel (printer) port, and a program (XTENDTOS.PRG) to copy in your AUTO folder. The bord is just a very simple DAC (Digital to Analog Converter). The output quality is the same than a 8-bit SoundBlaster.

But the driver also supports many other sound systems: the board is just one of them. Many programs now use ProSOUND's features, which is becoming a new standard on Atari computers. The programmer can forget all he knows about his machine's sound hardware, since ProSOUND makes coding easier.

2 - Required Hardware

For the board:

A Hades 40 or 60 (other Atari computers don't need this board since they already have a correct sound hardware), and powered speakers or a stereo. The output volume is at line level, so it needs to be amplified.

For the driver:

An Atari or compatible computer, with at least a 68030 processor. So it works at least with a TT.

3 - How to use ProSOUND ?

You just have to plug the board to the parallel port of your computer (with POWER set to OFF!) and copy the XTENDTOS.PRG and PSOUND.INF files in your AUTO folder. That's all. You can copy these files in any order, but if you want to play a sample at start-up, put them before all other programs.

All the programs which will detect ProSOUND will send all datas to the standard output, which is much faster than the Yamaha, and which provides a much better quality too.

The full version (driver and board) is available for 100FF.

The driver is available for 50FF, but please contact the author first if you're outside France.

Please read the PSOUND.INF file to choose the options and output.

4 - Programming ProSOUND

4.1 - XBIOS Vector

The driver adds several functions to the XBIOS. If you want to detect ProSOUND, just look out for the "PSND" cookie in the Cookie Jar.

Since the new XBIOS function is not definitive and can be modified in the future, you should everytime take its value in the two bytes just after "PSND" in the Cookie Jar. You will not have to modify your programs later.

In GfA Basic:
' Reading the Cookie Jar
cookie$=SPACE$(4)   ! 4-byte buffer to store the name of the Cookie
adrcj%=LPEEK(&H5A0) ! Cookie Jar's Address
IF adrcj%‹›0        ! If there's a Cookie Jar
  REPEAT            ! Scan the Cookie Jar 
    BMOVE V:cookie%,V:cookie$,4
    IF cookie$="PSND"
    ADD adrcj%,8
  UNTIL cookie%=0
This program reads the Cookie Jar and looks for the "PSND" cookie. Then it stores the Xbios Vector in xbios.vector& (16-bit integer) and saves the version number in a string called psnd.ver$. If you prefer to get a numerical value, just replace:

The boolean psnd! returns TRUE if ProSOUND has been detected.

In Assembler:
' a0="PSND" Cookie address
    move.w	4(a0),Xbios_vector
Xbios_vector now contains the XBIOS function number of ProSOUND.

4.2 - ProSOUND Version Number

Just after Xbios_vector, there are two other interesting bytes, which contain the version number:

Octet Version number
Version number
Bit 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0
$02 $3E
2 62

4.3 - ProSOUND's functions

The XBIOS vector includes the following sub-routines:

Number Name Description
1 Replay Once Replays a 8-bit unsigned sample.
2 Replay Loop Replays a 8-bit unsigned sample in loop mode.
3 Replay Frame Replays several 8-bits unsigned samples.
4 Stop Replay Stops the replay.
5 Convert S-M 8 Bits Converts a Stereo unsigned 8 bits sample to 8-bit unsigned mono format.
6 Change Preset Allows you to modify the free frequency preset (#15).
7 Convert S-M 16 Bits Converts a Stereo 16 signed bits sample to 16-bit signed mono format.
8 Sign/Unsign 8 Bits Signs or unsigns a 8 bits unsigned sample.
9 Resample 8 Bits Resample a 8 Bits unsigned sample to a new rate.
10 Convert Intel/Motorola Switches a 16 bits signed sample to Intel or Motorola format.
11 Replay Once 16 Replays a 16-bit signed sample.
12 Replay Loop 16 Replays a 16-bit signed sample in loop mode.
13 Replay Frame 16 Replays several 16-bit signed samples.
14 Maximize 8 Bits Amplifies the volume of a 8 Bits unsigned sample to the max, with no distortions.
15 Maximize 16 Bits Amplifies the volume of a 16 Bits signed sample to the max, with no distortions.
Nb Filter Filtering functions. Unimplemented yet.

All the parameters are given through the stack like all other XBIOS functions. You can use either the user mode or the supervisor mode. The ProSOUND functions which need the address of temporary buffer allow to keep the original sample and to have a modified copy. Just remember that only the Resample function needs a buffer address which is not the same than the sample's address, when the new rate is greater than the previous one.

The D0 data register is a pointer to the number of samples remaining. The A0 address register contains a pointer to the sample being replayed. These two informations are available with all the Replay functions.

Here's a little example :

5 - How to call ProSOUND's functions ?

5.1 - Replay Once

This function allows you to replay a 8-bit unsigned sample.

    move.l      #sample_start,-(sp)          ; Sample start address
    move.l      #sample_end,-(sp)            ; Sample end address
    move.w      #Frequency,-(sp)             ; Replay frequency
    move.w      #1,-(sp)                     ; Function #1
    move.w      Xbios_vector,-(sp)           ; XBIOS Vector
    trap        #14                          ; Call to XBIOS
    lea         14(sp),sp                    ; Clear the stack
    tst.l       d0                           ; D0=-1 in case of error
    bmi         error
    move.l      d0,a1                        
    ; Your code...
    tst.l       (a1)
    beq         end                          ; No more data to replay...
5.2 - Replay Loop

This functions allows you to replay a 8-bit unsigned sample in loop mode. This may be useful for a Soundtracker routine or any application which needs a spinning buffer.
    move.l      #sample_start,-(sp)          ; Sample start address
    move.l      #sample_end,-(sp)            ; Sample end address
    move.w      #Frequence,-(sp)             ; Replay frequency
    move.w      #2,-(sp)                     ; Function #2
    move.w      Xbios_vector,-(sp)           ; XBIOS Vector
    trap        #14                          ; Call to XBIOS
    lea         14(sp),sp                    ; Clear the stack
    tst.l       d0                           ; D0=-1 in case of error 
    bmi         error
    move.l      d0,a1                        ; Address containing the number
                                             ; of samples remaining to replay 
5.3 - Replay Frame

This function allows you to replay several 8-bit unsigned samples, defined in a sort structure called a Frame. The Frame can be either replayed in loop mode or not. The Frame is made of several pointers (sample start address, sample end address and the number of times the sample must be replayed), as many as there are samples to replay. This function may be useful for a Soundtracker routine or any application which needs a double spinning buffer.

You must pile in the stack all the following parameters in this order: frame address, replay frequency (which is used for all samples), the ProSOUND function number (here it's #3), and then the XBIOS vector number.
    move.l      #frame_adress,-(sp)          ; Frame address
    move.w      #Frequency,-(sp)             ; The frequency used for all samples
    move.w      #3,-(sp)                     ; Fonction #3
    move.w      Xbios_vector,-(sp)           ; XBIOS Vector
    trap        #14                          ; Call to XBIOS
    lea         10(sp),sp                    ; Clear the stack
Let's see now how is made the Frame. All values are long words (4 bytes), so the sequence for coding a sample has a length of 12 bytes.

Offset 1st long word
2nd long word
3rd long word
0 Start 1 End 1 Nb 1
12 Start 2 End 2 Nb 2
24 Start 3 End 3 Nb 3
? Restart Not Used -1

The values in the previous table are the following:

Start X Start adress of sample #X.
End X End address of sample #X.
Nb X The number of loops assigned to the sample #X before processing the next sample.
Restart Tells ProSOUND where in the Frame it must go after replaying all samples. This value must be a multiple of 12, since it must point out to the offset of the start address of a sample.
-1 This value marks the end of the Frame.

5.4 - Stop Replay

This function allows you to stop the replay.
    move.w      #4,-(sp)                     ; Function #4
    move.w      Xbios_vector,-(sp)
    trap        #14
    addq.l      #4,sp
5.5 - Convert S-M 8/16 Bits

This functions converts a stereo sample to mono format. The buffer's address can be the same than the sample's address (Sample_start in the following example), else, if the address is different, the original sample is not modified. The result will be stored at the buffer's address.
    move.l      #sample_start,-(sp)
    move.l      #sample_end,-(sp)
    move.l      #Buffer,-(sp)
    move.w      #5 or #7,-(sp)         8 bits unsigned = 5
    move.w      Xbios_vector,-(sp)    16 bits signed   = 7
    trap        #14
    lea         16(sp),sp
5.6 - Change Preset

This function allows you to assign your own value to the frequency preset #15. ProSOUND uses the Timer A of the MFP, which is running at 2 457 600 Hz. You have to give a pre-divide and a divide value to ProSOUND, to obtain the right frequency. Val is a word (2 bytes) which contains these two values.

Byte #0 Pre-divide value of Timer A
Byte #1 Divide value of Timer A

Byte #0 can take a value from 1 to 7, which are fixed pre-divide values, as represented in the following table:

Value 1 2 3 4 5 6 7
Pre-divide by 4 10 16 50 64 100 200

Byte #1 can take a value from 1 to 255. Caution! Do not set one of these two bytes to zero, because the processor will hang! Well, there's no processor on this planet which will accept to divide a number by zero... The replay frequency is given by the following equation:

Frequency = ( 2457600 / Pre-divide value ) / Divide value

So, if you set the pre-divide value to 4 and the divide value to 15, you will obtain a replay frequency of 40960 Hz. Val is then equal to $010F (01 is "pre-divide by 4" and $0F is "divide by 15", since $F in hexadecimal equals to 15 in decimal). But let's see now how it works in assembler:
    move.w      #Val,-(sp)
    move.w      #6,-(sp)		; function #6
    move.w      Xbios_vector,-(sp)
    trap        #14
    addq.l      #6,sp
5.7 - Sign/Unsign

This function allows you to convert as many times as you want a 8 Bits sample to unsigned format, or a unsigned sample to signed format. Unsigned samples use values between 0 and 255, whereas signed samples use values between -128 and +127.
    move.l      #sample_start,-(sp)
    move.l      #sample_end,-(sp)
    move.l      #Buffer,-(sp)
    move.w      #8,-(sp)
    move.w      Xbios_vector,-(sp)
    trap        #14
    lea         16(sp),sp
5.8 - Resample 8/16 Bits

This function allows to change the original recording frequency of a sample. If the original frequency is greater than the new one, the buffer's address can be the same than the sample's one. But if the new frequency is greater than the original frequency, the buffer's address must be different than the sample's address. In this case, ProSOUND use a linear interpolation routine.
    move.l      #sample_start,-(sp)
    move.l      #sample_end,-(sp)
    move.l      #Buffer,-(sp)
    move.w      #freq_start,-(sp)    ex : 11025
    move.w      #freq_dest,-(sp)     ex : 12800
    move.w      #9 or #16,-(sp)      8 bits unsigned = 9
    move.w      Xbios_vector,-(sp)  16 bits signed   = 16
    trap        #14
    lea         20(sp),sp
5.9 - Convert Intel/Motorola

Like the Sign/Unsign function, you can use this function as many times as you want. It allows you to swap the most significant byte with the less significant byte. The address of the buffer can be the same than the sample's one.
    move.l	#sample_start,-(sp)
    move.l	#sample_end,-(sp)
    move.l	#buffer,-(sp)
    move.w	#10,-(sp)
    move.w	Xbios_vector,-(sp)
    trap	#14
    lea	16(sp),sp
5.10 - The 16-bit Replay functions

The Replay Once 16, Replay Loop 16 and Replay Frame 16 only use signed samples, which are automatically converted to 8-bit format (in real time) if an 8-bit output is used. This is the case with the Yamaha YM2149 soundhip, the parallel port (ProSOUND board) or the ST-Replay cartridge.

The examples are the same than the 8-bit Replay functions.

5.11 - Maximize 8/16 Bits

This function stretches the sample's volume to its maximum, such as a compressor. Samples are not distorted. Please use function #14 for 8-bit unsigned samples, and function #15 for 16-bit signed samples.
    move.l	#sample_start,-(sp)
    move.l	#sample_end,-(sp)
    move.l	#buffer,-(sp)
    move.w	#14 ou #15 ,-(sp)    8 Bits unsigned = 14
    move.w	Xbios_vector,-(sp)  16 Bits signed   = 15
    trap	#14
    lea	16(sp),sp
5.12 - Filter

Well, these functions aren't available yet.

6 - Replay frequencies

You can use many pre-set frequencies or define your own. For preset #15, please read chapter 5.6 (Change Preset).

Here's the list of the available replay frequencies:

Value 0 1 2 3 4 5 6 7
8 192 9 600 11 170 12 288 12 538 12 800 16 384 24 576
Value 8 9 10 11 12 13 14 15
25 600 30 720 38 400 40 960 49 152 51 200 61 440 Free Preset

On the Atari TT, the maximum recommended frequency is 38400 Hz (preset #10). Preset #14 works without any problem on Hades 60, because this computer is fast enough to go up to 100 Kb/s, under interrupts!

7 - The PSOUND.INF file

This file is very important. It must be in the AUTO folder of your boot device (A: for floppy disk, C: for hard disk). This file contains some information about your ProSOUND system configuration. Please read carefully this file or use PSNDCFIG.PRG by LST of LaserForce to set the parameters.

8 - Contacting the author

To contact me, please write to the following address:

Loïc Sébald
1 bis, rue du Stade

or call the following phone number:

(+33) 04 66 63 40 16

9 - Greetings and Thanks to:

Emmanuel BARANGER (EBSound, EBModel), François LE COAT (Eureka), Guillaume TELLO (M_Player), Didier MEQUIGNON (Aniplayer, Sondigit), Eric Reboux (Start-it, View-it, Find-it), Marc GABARD (MODalyser, X~Command... moral, physical, financial, political support and well... Oh yeah, this HTML documentation!)