Date: Fri, 29 Oct 2004 11:47:09 +0200
authorPatrice Mandin <patmandin@gmail.com>
Fri, 29 Oct 2004 09:56:53 +0000
changeset 961185acc07127a
parent 960 eec28a5278be
child 962 176240cf4405
Date: Fri, 29 Oct 2004 11:47:09 +0200
From: Patrice Mandin
Subject: Reworked audio drivers for Atari platform

These are reworked audio drivers for the Atari platform.

Previous drivers were missing some features:
- Test external clock plugged to DSP port on Atari Falcon 030.
- Ability to select internal or external clock.

So now, I generate a list of frequencies available, with the master clock
and predivisor to use. One big caveat to this: I do not have an external
clock, so I hope it works.
src/audio/mint/SDL_mintaudio.c
src/audio/mint/SDL_mintaudio.h
src/audio/mint/SDL_mintaudio_dma8.c
src/audio/mint/SDL_mintaudio_dma8.h
src/audio/mint/SDL_mintaudio_gsxb.c
src/audio/mint/SDL_mintaudio_it.S
src/audio/mint/SDL_mintaudio_mcsn.c
src/audio/mint/SDL_mintaudio_stfa.c
src/audio/mint/SDL_mintaudio_xbios.c
     1.1 --- a/src/audio/mint/SDL_mintaudio.c	Sat Oct 09 22:11:45 2004 +0000
     1.2 +++ b/src/audio/mint/SDL_mintaudio.c	Fri Oct 29 09:56:53 2004 +0000
     1.3 @@ -41,6 +41,7 @@
     1.4  unsigned long SDL_MintAudio_audiosize;		/* Length of audio buffer=spec->size */
     1.5  unsigned short SDL_MintAudio_numbuf;		/* Buffer to play */
     1.6  unsigned short SDL_MintAudio_mutex;
     1.7 +unsigned long SDL_MintAudio_clocktics;
     1.8  cookie_stfa_t	*SDL_MintAudio_stfa;
     1.9  
    1.10  /* The callback function, called by each driver whenever needed */
    1.11 @@ -64,30 +65,57 @@
    1.12  	}
    1.13  }
    1.14  
    1.15 -/* Simple function to search for the nearest frequency */
    1.16 -int SDL_MintAudio_SearchFrequency(_THIS, int falcon_codec, int desired_freq)
    1.17 +/* Add a new frequency/clock/predivisor to the current list */
    1.18 +void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, Uint32 prediv)
    1.19 +{
    1.20 +	int i, p;
    1.21 +
    1.22 +	if (MINTAUDIO_freqcount==MINTAUDIO_maxfreqs) {
    1.23 +		return;
    1.24 +	}
    1.25 +
    1.26 +	/* Search where to insert the frequency (highest first) */
    1.27 +	for (p=0; p<MINTAUDIO_freqcount; p++) {
    1.28 +		if (frequency > MINTAUDIO_frequencies[p].frequency) {
    1.29 +			break;
    1.30 +		}
    1.31 +	}
    1.32 +
    1.33 +	/* Put all following ones farer */
    1.34 +	if (MINTAUDIO_freqcount>0) {
    1.35 +		for (i=MINTAUDIO_freqcount; i>p; i--) {
    1.36 +			MINTAUDIO_frequencies[i].frequency = MINTAUDIO_frequencies[i-1].frequency;
    1.37 +			MINTAUDIO_frequencies[i].masterclock = MINTAUDIO_frequencies[i-1].masterclock;
    1.38 +			MINTAUDIO_frequencies[i].predivisor = MINTAUDIO_frequencies[i-1].predivisor;
    1.39 +		}
    1.40 +	}
    1.41 +
    1.42 +	/* And insert new one */
    1.43 +	MINTAUDIO_frequencies[p].frequency = frequency;
    1.44 +	MINTAUDIO_frequencies[p].masterclock = clock;
    1.45 +	MINTAUDIO_frequencies[p].predivisor = prediv;
    1.46 +
    1.47 +	MINTAUDIO_freqcount++;
    1.48 +}
    1.49 +
    1.50 +/* Search for the nearest frequency */
    1.51 +int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq)
    1.52  {
    1.53  	int i;
    1.54  
    1.55  	/* Only 1 freq ? */
    1.56 -	if (MINTAUDIO_nfreq==1) {
    1.57 -		return(MINTAUDIO_sfreq);
    1.58 +	if (MINTAUDIO_freqcount==1) {
    1.59 +		return 0;
    1.60  	}
    1.61  
    1.62  	/* Check the array */
    1.63 -	for (i=MINTAUDIO_sfreq; i<MINTAUDIO_nfreq-1; i++) {
    1.64 -		/* Remove unusable falcon codec frequencies */
    1.65 -		if (falcon_codec) {
    1.66 -			if ((i==6) || (i==8) || (i==10)) {
    1.67 -				continue;
    1.68 -			}
    1.69 -		}
    1.70 -
    1.71 -		if (desired_freq >= ((MINTAUDIO_hardfreq[i]+MINTAUDIO_hardfreq[i+1])>>1)) {
    1.72 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
    1.73 +		if (desired_freq >= ((MINTAUDIO_frequencies[i].frequency+
    1.74 +			MINTAUDIO_frequencies[i+1].frequency)>>1)) {
    1.75  			return i;
    1.76  		}
    1.77  	}
    1.78  
    1.79  	/* Not in the array, give the latest */
    1.80 -	return MINTAUDIO_nfreq-1;
    1.81 +	return MINTAUDIO_freqcount-1;
    1.82  }
     2.1 --- a/src/audio/mint/SDL_mintaudio.h	Sat Oct 09 22:11:45 2004 +0000
     2.2 +++ b/src/audio/mint/SDL_mintaudio.h	Fri Oct 29 09:56:53 2004 +0000
     2.3 @@ -35,17 +35,25 @@
     2.4  /* Hidden "this" pointer for the audio functions */
     2.5  #define _THIS	SDL_AudioDevice *this
     2.6  
     2.7 +/* 16 predivisors with 3 clocks max. */
     2.8 +#define MINTAUDIO_maxfreqs		(16*3)		
     2.9 +
    2.10 +typedef struct {
    2.11 +	Uint32	frequency;
    2.12 +	Uint32	masterclock;
    2.13 +	Uint32	predivisor;
    2.14 +} mint_frequency_t;
    2.15 +
    2.16  struct SDL_PrivateAudioData {
    2.17 -	Uint32	hardfreq[16];	/* Array of replay freqs of the hardware */
    2.18 -	int		sfreq;			/* First number of freq to use in the array */
    2.19 -	int 	nfreq;			/* Number of freqs to use in the array */
    2.20 +	mint_frequency_t	frequencies[MINTAUDIO_maxfreqs];
    2.21 +	int 	freq_count;		/* Number of frequencies in the array */
    2.22  	int		numfreq;		/* Number of selected frequency */
    2.23  };
    2.24  
    2.25  /* Old variable names */
    2.26 -#define MINTAUDIO_hardfreq		(this->hidden->hardfreq)
    2.27 -#define MINTAUDIO_sfreq			(this->hidden->sfreq)
    2.28 -#define MINTAUDIO_nfreq			(this->hidden->nfreq)
    2.29 +
    2.30 +#define MINTAUDIO_frequencies	(this->hidden->frequencies)
    2.31 +#define MINTAUDIO_freqcount		(this->hidden->freq_count)
    2.32  #define MINTAUDIO_numfreq		(this->hidden->numfreq)
    2.33  
    2.34  /* _MCH cookie (values>>16) */
    2.35 @@ -110,14 +118,17 @@
    2.36  extern unsigned short SDL_MintAudio_numbuf;		/* Buffer to play */
    2.37  extern unsigned short SDL_MintAudio_mutex;
    2.38  extern cookie_stfa_t *SDL_MintAudio_stfa;
    2.39 +extern unsigned long SDL_MintAudio_clocktics;
    2.40  
    2.41  /* Functions */
    2.42  void SDL_MintAudio_Callback(void);
    2.43 -int SDL_MintAudio_SearchFrequency(_THIS, int falcon_codec, int desired_freq);
    2.44 +void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, Uint32 prediv);
    2.45 +int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq);
    2.46  
    2.47  /* ASM interrupt functions */
    2.48  void SDL_MintAudio_GsxbInterrupt(void);
    2.49  void SDL_MintAudio_EmptyGsxbInterrupt(void);
    2.50 +void SDL_MintAudio_XbiosInterruptMeasureClock(void);
    2.51  void SDL_MintAudio_XbiosInterrupt(void);
    2.52  void SDL_MintAudio_Dma8Interrupt(void);
    2.53  void SDL_MintAudio_StfaInterrupt(void);
     3.1 --- a/src/audio/mint/SDL_mintaudio_dma8.c	Sat Oct 09 22:11:45 2004 +0000
     3.2 +++ b/src/audio/mint/SDL_mintaudio_dma8.c	Fri Oct 29 09:56:53 2004 +0000
     3.3 @@ -53,7 +53,7 @@
     3.4  
     3.5  /* Debug print info */
     3.6  #define DEBUG_NAME "audio:dma8: "
     3.7 -#if 0
     3.8 +#if 1
     3.9  #define DEBUG_PRINT(what) \
    3.10  	{ \
    3.11  		printf what; \
    3.12 @@ -100,11 +100,12 @@
    3.13  	}
    3.14  
    3.15  	/* Check if we have 8 bits audio */
    3.16 +/*
    3.17  	if ((cookie_snd & SND_8BIT)==0) {
    3.18  		DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
    3.19  	    return(0);
    3.20  	}
    3.21 -
    3.22 +*/
    3.23  	if ((cookie_mch>>16)>MCH_F30) {
    3.24  		DEBUG_PRINT((DEBUG_NAME "unknown 8 bits audio chip\n"));
    3.25  		return 0;
    3.26 @@ -218,7 +219,7 @@
    3.27  
    3.28  static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
    3.29  {
    3.30 -	int i, masterprediv;
    3.31 +	int i, masterprediv, sfreq;
    3.32  	unsigned long masterclock;
    3.33  
    3.34  	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
    3.35 @@ -231,8 +232,7 @@
    3.36  	spec->format = AUDIO_S8;
    3.37  	
    3.38  	/* Calculate and select the closest frequency */
    3.39 -	MINTAUDIO_nfreq=4;
    3.40 -	MINTAUDIO_sfreq=0;
    3.41 +	sfreq=0;
    3.42  	masterclock=MASTERCLOCK_STE;
    3.43  	masterprediv=MASTERPREDIV_STE;
    3.44  	switch(cookie_mch>>16) {
    3.45 @@ -248,18 +248,27 @@
    3.46  			break;
    3.47  		case MCH_F30:
    3.48  			masterclock=MASTERCLOCK_FALCON1;
    3.49 -			masterprediv=MASTERPREDIV_FALCON<<1;
    3.50 -			MINTAUDIO_nfreq=3;
    3.51 -			MINTAUDIO_sfreq=1;
    3.52 +			masterprediv=MASTERPREDIV_FALCON;
    3.53 +			sfreq=1;
    3.54  			break;
    3.55  	}
    3.56 -	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
    3.57 -		MINTAUDIO_hardfreq[i]=masterclock/(masterprediv*(1<<i));
    3.58 -		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
    3.59 +	
    3.60 +	MINTAUDIO_freqcount=0;
    3.61 +	for (i=sfreq;i<4;i++) {
    3.62 +		SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), masterclock, i-sfreq);
    3.63  	}
    3.64  
    3.65 -	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 0, spec->freq);
    3.66 -	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
    3.67 +#if 1
    3.68 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
    3.69 +		DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
    3.70 +			i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock,
    3.71 +			MINTAUDIO_frequencies[i].predivisor
    3.72 +		));
    3.73 +	}
    3.74 +#endif
    3.75 +
    3.76 +	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq);
    3.77 +	spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
    3.78  
    3.79  	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
    3.80  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
    3.81 @@ -298,11 +307,11 @@
    3.82  	DMAAUDIO_IO.end_mid = (buffer>>8) & 255;
    3.83  	DMAAUDIO_IO.end_low = buffer & 255;
    3.84  
    3.85 -	mode = 3-MINTAUDIO_numfreq;
    3.86 +	mode = 3-MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
    3.87  	if (spec->channels==1) {
    3.88  		mode |= 1<<7;
    3.89  	}
    3.90 -	DMAAUDIO_IO.mode = mode;	
    3.91 +	DMAAUDIO_IO.sound_ctrl = mode;	
    3.92  
    3.93  	/* Set interrupt */
    3.94  	Jdisint(MFP_DMASOUND);
     4.1 --- a/src/audio/mint/SDL_mintaudio_dma8.h	Sat Oct 09 22:11:45 2004 +0000
     4.2 +++ b/src/audio/mint/SDL_mintaudio_dma8.h	Fri Oct 29 09:56:53 2004 +0000
     4.3 @@ -21,9 +21,9 @@
     4.4  */
     4.5  
     4.6  /*
     4.7 -	DMA 8bits audio definitions
     4.8 +	DMA 8bits and Falcon Codec audio definitions
     4.9  
    4.10 -	Patrice Mandin
    4.11 +	Patrice Mandin, Didier Méquignon
    4.12  */
    4.13  
    4.14  #ifndef _SDL_mintaudio_dma8_h
    4.15 @@ -57,8 +57,27 @@
    4.16  
    4.17  	unsigned char dummy10[12];
    4.18  
    4.19 -	unsigned char track_select; /* CODEC only */
    4.20 -	unsigned char mode;
    4.21 +	unsigned char track_ctrl; /* CODEC only */
    4.22 +	unsigned char sound_ctrl;
    4.23 +	unsigned short sound_data;
    4.24 +	unsigned short sound_mask;
    4.25 +
    4.26 +	unsigned char dummy11[10];
    4.27 +	
    4.28 +	unsigned short dev_ctrl;
    4.29 +	unsigned short dest_ctrl;
    4.30 +	unsigned short sync_div;
    4.31 +	unsigned char track_rec;
    4.32 +	unsigned char adderin_input;
    4.33 +	unsigned char channel_input;
    4.34 +	unsigned char channel_amplification;
    4.35 +	unsigned char channel_reduction;
    4.36 +	
    4.37 +	unsigned char dummy12[6];
    4.38 +
    4.39 +	unsigned char data_direction;
    4.40 +	unsigned char dummy13;
    4.41 +	unsigned char dev_data;
    4.42  };
    4.43  #define DMAAUDIO_IO ((*(volatile struct DMAAUDIO_IO_S *)DMAAUDIO_IO_BASE))
    4.44  
     5.1 --- a/src/audio/mint/SDL_mintaudio_gsxb.c	Sat Oct 09 22:11:45 2004 +0000
     5.2 +++ b/src/audio/mint/SDL_mintaudio_gsxb.c	Fri Oct 29 09:56:53 2004 +0000
     5.3 @@ -53,7 +53,7 @@
     5.4  
     5.5  /* Debug print info */
     5.6  #define DEBUG_NAME "audio:gsxb: "
     5.7 -#if 0
     5.8 +#if 1
     5.9  #define DEBUG_PRINT(what) \
    5.10  	{ \
    5.11  		printf what; \
    5.12 @@ -179,29 +179,21 @@
    5.13  	/* Stop replay */
    5.14  	Buffoper(0);
    5.15  
    5.16 -	DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
    5.17 -
    5.18  	/* Uninstall interrupt */
    5.19  	if (NSetinterrupt(2, SI_NONE, SDL_MintAudio_EmptyGsxbInterrupt)<0) {
    5.20  		DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
    5.21  	}
    5.22  
    5.23 -	DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
    5.24 -
    5.25  	/* Wait if currently playing sound */
    5.26  	while (SDL_MintAudio_mutex != 0) {
    5.27  	}
    5.28  
    5.29 -	DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
    5.30 -
    5.31  	/* Clear buffers */
    5.32  	if (SDL_MintAudio_audiobuf[0]) {
    5.33  		Mfree(SDL_MintAudio_audiobuf[0]);
    5.34  		SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
    5.35  	}
    5.36  
    5.37 -	DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
    5.38 -
    5.39  	/* Unlock sound system */
    5.40  	Unlocksnd();
    5.41  }
    5.42 @@ -278,15 +270,22 @@
    5.43  	}
    5.44  	
    5.45  	/* Calculate and select the closest frequency */
    5.46 -	MINTAUDIO_sfreq=1;
    5.47 -	MINTAUDIO_nfreq=12;
    5.48 -	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
    5.49 -		MINTAUDIO_hardfreq[i]=MASTERCLOCK_44K/(MASTERPREDIV_MILAN*(i+1));
    5.50 -		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
    5.51 +	MINTAUDIO_freqcount=0;
    5.52 +	for (i=1;i<4;i++) {
    5.53 +		SDL_MintAudio_AddFrequency(this, MASTERCLOCK_44K/(MASTERPREDIV_MILAN*(1<<i)), MASTERCLOCK_44K, (1<<i)-1);
    5.54  	}
    5.55  
    5.56 -	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 1, spec->freq);
    5.57 -	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
    5.58 +#if 1
    5.59 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
    5.60 +		DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
    5.61 +			i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock,
    5.62 +			MINTAUDIO_frequencies[i].predivisor
    5.63 +		));
    5.64 +	}
    5.65 +#endif
    5.66 +
    5.67 +	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq);
    5.68 +	spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
    5.69  
    5.70  	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
    5.71  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
    5.72 @@ -299,7 +298,7 @@
    5.73  
    5.74  static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
    5.75  {
    5.76 -	int channels_mode;
    5.77 +	int channels_mode, prediv;
    5.78  	void *buffer;
    5.79  
    5.80  	/* Stop currently playing sound */
    5.81 @@ -333,7 +332,8 @@
    5.82  		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
    5.83  	}
    5.84  
    5.85 -	Devconnect(DMAPLAY, DAC, CLKEXT, MINTAUDIO_numfreq, 1);
    5.86 +	prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
    5.87 +	Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1);
    5.88  
    5.89  	/* Set buffer */
    5.90  	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
     6.1 --- a/src/audio/mint/SDL_mintaudio_it.S	Sat Oct 09 22:11:45 2004 +0000
     6.2 +++ b/src/audio/mint/SDL_mintaudio_it.S	Fri Oct 29 09:56:53 2004 +0000
     6.3 @@ -23,7 +23,7 @@
     6.4  /*
     6.5  	Audio interrupts
     6.6  
     6.7 -	Patrice Mandin
     6.8 +	Patrice Mandin, Didier Méquignon
     6.9   */
    6.10  
    6.11  	.text
    6.12 @@ -33,6 +33,7 @@
    6.13  	.globl	_SDL_MintAudio_GsxbInterrupt
    6.14  	.globl	_SDL_MintAudio_EmptyGsxbInterrupt
    6.15  	.globl	_SDL_MintAudio_XbiosInterrupt
    6.16 +	.globl	_SDL_MintAudio_XbiosInterruptMeasureClock
    6.17  	.globl	_SDL_MintAudio_Dma8Interrupt
    6.18  	.globl	_SDL_MintAudio_StfaInterrupt
    6.19  
    6.20 @@ -40,6 +41,7 @@
    6.21  	.globl	_SDL_MintAudio_audiobuf
    6.22  	.globl	_SDL_MintAudio_numbuf
    6.23  	.globl	_SDL_MintAudio_audiosize
    6.24 +	.globl	_SDL_MintAudio_clocktics
    6.25  
    6.26  	.globl	_SDL_MintAudio_stfa
    6.27  
    6.28 @@ -94,6 +96,17 @@
    6.29  _SDL_MintAudio_EmptyGsxbInterrupt:
    6.30  	rts
    6.31  
    6.32 +/*--- Xbios interrupt vector to measure Falcon external clock ---*/
    6.33 +
    6.34 +_SDL_MintAudio_XbiosInterruptMeasureClock:          /* 1 mS */
    6.35 +
    6.36 +	btst	#0,0xFFFF8901:w	/* state DMA sound */
    6.37 +	beqs	SDL_MintAudio_EndIntMeasure
    6.38 +	addql	#1,_SDL_MintAudio_clocktics
    6.39 +SDL_MintAudio_EndIntMeasure:
    6.40 +	bclr	#5,0xFFFFFA0F:w	/* Clear service bit */
    6.41 +	rte
    6.42 +
    6.43  /*--- Xbios interrupt vector ---*/
    6.44  
    6.45  _SDL_MintAudio_XbiosInterrupt:
     7.1 --- a/src/audio/mint/SDL_mintaudio_mcsn.c	Sat Oct 09 22:11:45 2004 +0000
     7.2 +++ b/src/audio/mint/SDL_mintaudio_mcsn.c	Fri Oct 29 09:56:53 2004 +0000
     7.3 @@ -53,7 +53,7 @@
     7.4  
     7.5  /* Debug print info */
     7.6  #define DEBUG_NAME "audio:mcsn: "
     7.7 -#if 0
     7.8 +#if 1
     7.9  #define DEBUG_PRINT(what) \
    7.10  	{ \
    7.11  		printf what; \
    7.12 @@ -217,14 +217,12 @@
    7.13  	DEBUG_PRINT(("freq=%d\n", spec->freq));
    7.14  
    7.15  	/* Check formats available */
    7.16 -	MINTAUDIO_nfreq=4;
    7.17 -	MINTAUDIO_sfreq=0;
    7.18 +	MINTAUDIO_freqcount=0;
    7.19  	switch(cookie_mcsn->play) {
    7.20  		case MCSN_ST:
    7.21  			spec->channels=1;
    7.22  			spec->format=8; /* FIXME: is it signed or unsigned ? */
    7.23 -			MINTAUDIO_nfreq=1;
    7.24 -			MINTAUDIO_hardfreq[0]=12500;
    7.25 +			SDL_MintAudio_AddFrequency(this, 12500, 0, 0);
    7.26  			break;
    7.27  		case MCSN_TT:	/* Also STE, Mega STE */
    7.28  			spec->format=AUDIO_S8;
    7.29 @@ -234,21 +232,22 @@
    7.30  				masterclock=MASTERCLOCK_TT;
    7.31  				masterprediv=MASTERPREDIV_TT;
    7.32  			}
    7.33 -			for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
    7.34 -				MINTAUDIO_hardfreq[i]=masterclock/(masterprediv*(1<<i));
    7.35 -				DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
    7.36 +			for (i=0; i<4; i++) {
    7.37 +				SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), masterclock, 3-i);
    7.38  			}
    7.39  			break;
    7.40  		case MCSN_FALCON:	/* Also Mac */
    7.41 -			MINTAUDIO_nfreq=12;
    7.42 -			MINTAUDIO_sfreq=1;
    7.43 -			masterclock=MASTERCLOCK_FALCON1;
    7.44 +			for (i=1; i<12; i++) {
    7.45 +				/* Remove unusable Falcon codec predivisors */
    7.46 +				if ((i==6) || (i==8) || (i==10)) {
    7.47 +					continue;
    7.48 +				}
    7.49 +				SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), CLK25M, i+1);
    7.50 +			}
    7.51  			if (cookie_mcsn->res1 != 0) {
    7.52 -				masterclock=cookie_mcsn->res1;
    7.53 -			}
    7.54 -			for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
    7.55 -				MINTAUDIO_hardfreq[i]=masterclock/(MASTERPREDIV_FALCON*(i+1));
    7.56 -				DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
    7.57 +				for (i=1; i<4; i++) {
    7.58 +					SDL_MintAudio_AddFrequency(this, (cookie_mcsn->res1)/(MASTERPREDIV_FALCON*(1<<i)), CLKEXT, (1<<i)-1);
    7.59 +				}
    7.60  			}
    7.61  			spec->format |= 0x8000;	/* Audio is always signed */
    7.62  			if ((spec->format & 0x00ff)==16) {
    7.63 @@ -258,8 +257,17 @@
    7.64  			break;
    7.65  	}
    7.66  
    7.67 -	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, (cookie_mch>>16)==MCH_F30, spec->freq);
    7.68 -	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
    7.69 +#if 1
    7.70 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
    7.71 +		DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
    7.72 +			i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock,
    7.73 +			MINTAUDIO_frequencies[i].predivisor
    7.74 +		));
    7.75 +	}
    7.76 +#endif
    7.77 +
    7.78 +	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq);
    7.79 +	spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
    7.80  
    7.81  	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
    7.82  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
    7.83 @@ -272,7 +280,7 @@
    7.84  
    7.85  static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
    7.86  {
    7.87 -	int channels_mode;
    7.88 +	int channels_mode, prediv, dmaclock;
    7.89  	void *buffer;
    7.90  
    7.91  	/* Stop currently playing sound */
    7.92 @@ -297,20 +305,17 @@
    7.93  		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
    7.94  	}
    7.95  
    7.96 +	dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock;
    7.97 +	prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
    7.98  	switch(cookie_mcsn->play) {
    7.99  		case MCSN_TT:
   7.100  			Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1);
   7.101 -			Soundcmd(SETPRESCALE, 3-MINTAUDIO_numfreq);
   7.102 +			Soundcmd(SETPRESCALE, prediv);
   7.103  			DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n"));
   7.104  			break;
   7.105  		case MCSN_FALCON:
   7.106 -			if (cookie_mcsn->res1 != 0) {
   7.107 -				Devconnect(DMAPLAY, DAC, CLKEXT, MINTAUDIO_numfreq, 1);
   7.108 -				DEBUG_PRINT((DEBUG_NAME "External clock selected, prescaler %d\n", MINTAUDIO_numfreq));
   7.109 -			} else {
   7.110 -				Devconnect(DMAPLAY, DAC, CLK25M, MINTAUDIO_numfreq, 1);
   7.111 -				DEBUG_PRINT((DEBUG_NAME "25.175 MHz clock selected, prescaler %d\n", MINTAUDIO_numfreq));
   7.112 -			}
   7.113 +			Devconnect(DMAPLAY, DAC, dmaclock, prediv, 1);
   7.114 +			DEBUG_PRINT((DEBUG_NAME "Falcon prescaler selected\n"));
   7.115  			break;
   7.116  	}
   7.117  
     8.1 --- a/src/audio/mint/SDL_mintaudio_stfa.c	Sat Oct 09 22:11:45 2004 +0000
     8.2 +++ b/src/audio/mint/SDL_mintaudio_stfa.c	Fri Oct 29 09:56:53 2004 +0000
     8.3 @@ -53,7 +53,7 @@
     8.4  
     8.5  /* Debug print info */
     8.6  #define DEBUG_NAME "audio:stfa: "
     8.7 -#if 0
     8.8 +#if 1
     8.9  #define DEBUG_PRINT(what) \
    8.10  	{ \
    8.11  		printf what; \
    8.12 @@ -211,15 +211,22 @@
    8.13  	DEBUG_PRINT(("freq=%d\n", spec->freq));
    8.14  
    8.15  	/* Check formats available */
    8.16 -	MINTAUDIO_nfreq=16;
    8.17 -	MINTAUDIO_sfreq=0;
    8.18 -	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
    8.19 -		MINTAUDIO_hardfreq[i]=freqs[15-i];
    8.20 -		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
    8.21 +	MINTAUDIO_freqcount=0;
    8.22 +	for (i=0;i<16;i++) {
    8.23 +		SDL_MintAudio_AddFrequency(this, freqs[i], 0, i);
    8.24  	}
    8.25  
    8.26 -	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 0, spec->freq);
    8.27 -	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
    8.28 +#if 1
    8.29 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
    8.30 +		DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
    8.31 +			i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock,
    8.32 +			MINTAUDIO_frequencies[i].predivisor
    8.33 +		));
    8.34 +	}
    8.35 +#endif
    8.36 +
    8.37 +	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq);
    8.38 +	spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
    8.39  
    8.40  	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
    8.41  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
    8.42 @@ -243,7 +250,7 @@
    8.43  	cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
    8.44  
    8.45  	/* Select replay format */
    8.46 -	cookie_stfa->sound_control = 15-MINTAUDIO_numfreq;
    8.47 +	cookie_stfa->sound_control = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
    8.48  	if ((spec->format & 0xff)==8) {
    8.49  		cookie_stfa->sound_control |= STFA_FORMAT_8BIT;
    8.50  	} else {
     9.1 --- a/src/audio/mint/SDL_mintaudio_xbios.c	Sat Oct 09 22:11:45 2004 +0000
     9.2 +++ b/src/audio/mint/SDL_mintaudio_xbios.c	Fri Oct 29 09:56:53 2004 +0000
     9.3 @@ -24,12 +24,13 @@
     9.4  	MiNT audio driver
     9.5  	using XBIOS functions (Falcon)
     9.6  
     9.7 -	Patrice Mandin
     9.8 +	Patrice Mandin, Didier Méquignon
     9.9  */
    9.10  
    9.11  #include <stdlib.h>
    9.12  #include <stdio.h>
    9.13  #include <string.h>
    9.14 +#include <unistd.h>
    9.15  
    9.16  /* Mint includes */
    9.17  #include <mint/osbind.h>
    9.18 @@ -45,6 +46,7 @@
    9.19  #include "SDL_atarimxalloc_c.h"
    9.20  
    9.21  #include "SDL_mintaudio.h"
    9.22 +#include "SDL_mintaudio_dma8.h"
    9.23  
    9.24  /*--- Defines ---*/
    9.25  
    9.26 @@ -52,7 +54,7 @@
    9.27  
    9.28  /* Debug print info */
    9.29  #define DEBUG_NAME "audio:xbios: "
    9.30 -#if 0
    9.31 +#if 1
    9.32  #define DEBUG_PRINT(what) \
    9.33  	{ \
    9.34  		printf what; \
    9.35 @@ -186,9 +188,150 @@
    9.36  	Unlocksnd();
    9.37  }
    9.38  
    9.39 +/* Falcon XBIOS implementation of Devconnect() is buggy with external clock */
    9.40 +static void Devconnect2(int src, int dst, int sclk, int pre)
    9.41 +{		
    9.42 +	static const unsigned short MASK1[3] = { 0, 0x6000, 0 };
    9.43 +	static const unsigned short MASK2[4] = { 0xFFF0, 0xFF8F, 0xF0FF, 0x0FFF };
    9.44 +	static const unsigned short INDEX1[4] = {  1, 3, 5, 7 };
    9.45 +	static const unsigned short INDEX2[4] = {  0, 2, 4, 6 };
    9.46 +	unsigned short sync_div,dev_ctrl,dest_ctrl;
    9.47 +	void *oldstack;
    9.48 +
    9.49 +	if (dst==0) {
    9.50 +		return;
    9.51 +	}
    9.52 +
    9.53 +	oldstack=(void *)Super(0);
    9.54 +
    9.55 +	dev_ctrl = DMAAUDIO_IO.dev_ctrl;
    9.56 +	dest_ctrl = DMAAUDIO_IO.dest_ctrl;
    9.57 +	dev_ctrl &= MASK2[src];
    9.58 +
    9.59 +	if (src==ADC) {
    9.60 +		dev_ctrl |= MASK1[sclk];
    9.61 +	} else {
    9.62 +		dev_ctrl |= (INDEX1[sclk] << (src<<4));
    9.63 +	}
    9.64 +
    9.65 +	if (dst & DMAREC) {		
    9.66 +		dest_ctrl &= 0xFFF0;
    9.67 +		dest_ctrl |= INDEX1[src];
    9.68 +	}
    9.69 +
    9.70 +	if (dst & DSPRECV) {		
    9.71 +		dest_ctrl &= 0xFF8F;
    9.72 +		dest_ctrl |= (INDEX1[src]<<4); 
    9.73 +	}
    9.74 +
    9.75 +	if (dst & EXTOUT) {		
    9.76 +		dest_ctrl &= 0xF0FF;
    9.77 +		dest_ctrl |= (INDEX1[src]<<8); 
    9.78 +	}
    9.79 +
    9.80 +	if (dst & DAC) {		
    9.81 +		dev_ctrl &= 0x0FFF;
    9.82 +		dev_ctrl |= MASK1[sclk]; 
    9.83 +		dest_ctrl &=  0x0FFF;
    9.84 +		dest_ctrl |= (INDEX2[src]<<12); 
    9.85 +	}
    9.86 +
    9.87 +	sync_div = DMAAUDIO_IO.sync_div;
    9.88 +	if (sclk==CLKEXT) {
    9.89 +		pre<<=8;
    9.90 +		sync_div &= 0xF0FF;
    9.91 +	} else {
    9.92 +		sync_div &= 0xFFF0;
    9.93 +	}
    9.94 +	sync_div |= pre;
    9.95 +
    9.96 +	DMAAUDIO_IO.dev_ctrl = dev_ctrl;
    9.97 +	DMAAUDIO_IO.dest_ctrl = dest_ctrl;
    9.98 +	DMAAUDIO_IO.sync_div = sync_div;
    9.99 +
   9.100 +	Super(oldstack);
   9.101 +}
   9.102 +
   9.103 +static Uint32 Mint_CheckExternalClock(void)
   9.104 +{
   9.105 +#define SIZE_BUF_CLOCK_MEASURE (44100/10)
   9.106 +
   9.107 +	unsigned long cookie_snd;
   9.108 +	Uint32 masterclock;
   9.109 +	char *buffer;
   9.110 +	int i;
   9.111 +
   9.112 +	/* DSP present with its GPIO port ? */
   9.113 +	if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
   9.114 +		return 0;
   9.115 +	}
   9.116 +	if ((cookie_snd & SND_DSP)==0) {
   9.117 +		return 0;
   9.118 +	}
   9.119 +
   9.120 +	buffer = Atari_SysMalloc(SIZE_BUF_CLOCK_MEASURE, MX_STRAM);
   9.121 +	if (buffer==NULL) {
   9.122 +		DEBUG_PRINT((DEBUG_NAME "Not enough memory for the measure\n"));
   9.123 +		return 0;
   9.124 +	}
   9.125 +	memset(buffer, 0, SIZE_BUF_CLOCK_MEASURE);
   9.126 +
   9.127 +	masterclock=0;
   9.128 +
   9.129 +	Buffoper(0);
   9.130 +	Settracks(0,0);
   9.131 +	Setmontracks(0);
   9.132 +	Setmode(MONO8);
   9.133 +	Jdisint(MFP_TIMERA);
   9.134 +
   9.135 +	for (i=0; i<2; i++) {
   9.136 +		Gpio(GPIO_SET,7);      /* DSP port gpio outputs */
   9.137 +		Gpio(GPIO_WRITE,2+i);  /* 22.5792/24.576 MHz for 44.1/48KHz */
   9.138 +		Devconnect2(DMAPLAY, DAC, CLKEXT, CLK50K);  /* Matrix and clock source */
   9.139 +		Setbuffer(0, buffer, buffer + SIZE_BUF_CLOCK_MEASURE);		           /* Set buffer */
   9.140 +		Xbtimer(XB_TIMERA, 5, 38, SDL_MintAudio_XbiosInterruptMeasureClock); /* delay mode timer A, prediv /64, 1KHz */
   9.141 +		Jenabint(MFP_TIMERA);
   9.142 +		SDL_MintAudio_clocktics = 0;
   9.143 +		Buffoper(SB_PLA_ENA);
   9.144 +		usleep(110000);
   9.145 +
   9.146 +		if((Buffoper(-1) & 1)==0) {
   9.147 +			if (SDL_MintAudio_clocktics) {
   9.148 +				unsigned long khz;
   9.149 +
   9.150 +				khz = ((SIZE_BUF_CLOCK_MEASURE/SDL_MintAudio_clocktics) +1) & 0xFFFFFFFE;
   9.151 +				DEBUG_PRINT((DEBUG_NAME "measure %d: freq=%lu KHz\n", i+1, khz));
   9.152 +
   9.153 +				if (i==0) {
   9.154 +					if(khz==44) {
   9.155 +						masterclock = MASTERCLOCK_44K;
   9.156 +					}
   9.157 +				} else {
   9.158 +					if(khz==48) {
   9.159 +						masterclock = MASTERCLOCK_48K;
   9.160 +					}
   9.161 +				}
   9.162 +			} else {
   9.163 +				DEBUG_PRINT((DEBUG_NAME "No measure\n"));
   9.164 +			}
   9.165 +		} else {
   9.166 +			DEBUG_PRINT((DEBUG_NAME "No SDMA clock\n"));
   9.167 +		}
   9.168 +
   9.169 +		Buffoper(0);             /* stop */
   9.170 +		Jdisint(MFP_TIMERA);     /* Uninstall interrupt */
   9.171 +		if (masterclock == 0)
   9.172 +			break;
   9.173 +	}
   9.174 +
   9.175 +	Mfree(buffer);
   9.176 +	return masterclock;
   9.177 +}
   9.178 +
   9.179  static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
   9.180  {
   9.181  	int i;
   9.182 +	Uint32 extclock;
   9.183  
   9.184  	DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
   9.185  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
   9.186 @@ -202,16 +345,35 @@
   9.187  		spec->channels=2;	/* 16 bits always stereo */
   9.188  	}
   9.189  
   9.190 -	/* FIXME: check for an external clock */
   9.191 -	MINTAUDIO_sfreq=1;
   9.192 -	MINTAUDIO_nfreq=12;
   9.193 -	for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
   9.194 -		MINTAUDIO_hardfreq[i]=MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1));
   9.195 -		DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
   9.196 +	extclock=Mint_CheckExternalClock();
   9.197 +
   9.198 +	/* Standard clocks */
   9.199 +	MINTAUDIO_freqcount=0;
   9.200 +	for (i=1;i<12;i++) {
   9.201 +		/* Remove unusable Falcon codec predivisors */
   9.202 +		if ((i==6) || (i==8) || (i==10)) {
   9.203 +			continue;
   9.204 +		}
   9.205 +		SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), MASTERCLOCK_FALCON1, i);
   9.206  	}
   9.207  
   9.208 -	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 1, spec->freq);
   9.209 -	spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
   9.210 +	if (extclock>0) {
   9.211 +		for (i=1; i<4; i++) {
   9.212 +			SDL_MintAudio_AddFrequency(this, extclock/(MASTERPREDIV_FALCON*(1<<i)), extclock, (1<<i)-1);
   9.213 +		}
   9.214 +	}
   9.215 +
   9.216 +#if 1
   9.217 +	for (i=0; i<MINTAUDIO_freqcount; i++) {
   9.218 +		DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
   9.219 +			i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock,
   9.220 +			MINTAUDIO_frequencies[i].predivisor
   9.221 +		));
   9.222 +	}
   9.223 +#endif
   9.224 +
   9.225 +	MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq);
   9.226 +	spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
   9.227  
   9.228  	DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
   9.229  	DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
   9.230 @@ -224,7 +386,7 @@
   9.231  
   9.232  static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
   9.233  {
   9.234 -	int channels_mode;
   9.235 +	int channels_mode, dmaclock, prediv;
   9.236  	void *buffer;
   9.237  
   9.238  	/* Stop currently playing sound */
   9.239 @@ -249,10 +411,19 @@
   9.240  		DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n"));
   9.241  	}
   9.242  
   9.243 -	/* FIXME: select an external clock */
   9.244 -
   9.245 -	Devconnect(DMAPLAY, DAC, CLK25M, MINTAUDIO_numfreq, 1);
   9.246 -	DEBUG_PRINT((DEBUG_NAME "25.175 MHz clock selected, prescaler %d\n", MINTAUDIO_numfreq));
   9.247 +	dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock;
   9.248 +	prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
   9.249 +	if (dmaclock != MASTERCLOCK_FALCON1) {
   9.250 +		Gpio(GPIO_SET,7);		/* DSP port gpio outputs */
   9.251 +		if (dmaclock == MASTERCLOCK_44K) {
   9.252 +			Gpio(GPIO_WRITE,2);	/* 22.5792 MHz for 44.1KHz */
   9.253 +		} else {
   9.254 +			Gpio(GPIO_WRITE,3);	/* 24.576 MHz for 48KHz */
   9.255 +		}
   9.256 +		Devconnect2(DMAPLAY, DAC, CLKEXT, prediv);
   9.257 +	} else {
   9.258 +		Devconnect(DMAPLAY, DAC, CLK25M, prediv, 1);
   9.259 +	}
   9.260  
   9.261  	/* Set buffer */
   9.262  	buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];