2 The contents of this file are subject to the AROS Public License Version 1.1 (the "License");
3 you may not use this file except in compliance with the License. You may obtain a copy of the License at
4 http://www.aros.org/license.html
5 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
6 ANY KIND, either express or implied. See the License for the specific language governing rights and
7 limitations under the License.
9 The Original Code is written by Davy Wentzler.
15 #include <proto/expansion.h>
16 #include <libraries/ahi_sub.h>
17 #include <proto/exec.h>
21 #include "interrupt.h"
24 #define min(a,b) ((a)<(b)?(a):(b))
29 //struct tester t[10];
32 /******************************************************************************
33 ** Hardware interrupt handler *************************************************
34 ******************************************************************************/
38 CardInterrupt( struct ExceptionContext
*pContext
, struct ExecBase
*SysBase
, struct CardData
* card
)
40 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
41 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
42 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
47 while ( (( intreq
= ( dev
->InLong(card
->iobase
+ CMPCI_REG_INTR_STATUS
) ) ) & CMPCI_REG_ANY_INTR
)!= 0 )
49 //IExec->DebugPrintF("INT %lx\n", intreq);
50 if( intreq
& CMPCI_REG_CH0_INTR
&& AudioCtrl
!= NULL
)
52 unsigned long diff
= dev
->InLong(card
->iobase
+ CMPCI_REG_DMA0_BASE
) - (unsigned long) card
->playback_buffer_phys
;
54 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
61 t[z].flip = card->flip;
62 t[z].oldflip = card->oldflip;
65 /*if ((diff > 50 && diff < card->current_bytesize) ||
66 (diff > card->current_bytesize + 50 && diff < 2 * card->current_bytesize))
67 IExec->DebugPrintF("Delayed IRQ %lu %lu\n", diff % card->current_bytesize, card->current_bytesize);*/
70 if (diff
>= card
->current_bytesize
) //card->flip == 0) // just played buf 1
73 IExec
->DebugPrintF("A:Missed IRQ! diff = %lu\n", diff
);
76 card
->current_buffer
= card
->playback_buffer
;
78 else // just played buf 2
81 IExec
->DebugPrintF("B:Missed IRQ! diff = %lu\n", diff
);
84 card
->current_buffer
= (APTR
) ((long) card
->playback_buffer
+ card
->current_bytesize
);
91 card
->playback_interrupt_enabled
= FALSE
;
92 IExec
->Cause( &card
->playback_interrupt
);
95 if( intreq
& CMPCI_REG_CH1_INTR
&& AudioCtrl
!= NULL
)
97 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
100 IExec->DebugPrintF("rec\n");*/
105 if( card
->record_interrupt_enabled
)
107 /* Invoke softint to convert and feed AHI with the new sample data */
109 if (card
->recflip
== 0) // just played buf 1
112 card
->current_record_buffer
= card
->record_buffer
;
114 else // just played buf 2
117 card
->current_record_buffer
= (APTR
) ((long) card
->record_buffer
+ card
->current_record_bytesize
);
120 card
->record_interrupt_enabled
= FALSE
;
121 IExec
->Cause( &card
->record_interrupt
);
133 /******************************************************************************
134 ** Playback interrupt handler *************************************************
135 ******************************************************************************/
138 PlaybackInterrupt( struct ExceptionContext
*pContext
, struct ExecBase
*SysBase
, struct CardData
* card
)
140 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
141 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
142 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
144 if( card
->mix_buffer
!= NULL
&& card
->current_buffer
!= NULL
)
154 skip_mix
= IUtility
->CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
, (Object
*) AudioCtrl
, 0 );
155 IUtility
->CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, (Object
*) AudioCtrl
, NULL
);
157 //IExec->DebugPrintF("skip_mix = %d\n", skip_mix);
161 IUtility
->CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, (Object
*) AudioCtrl
, card
->mix_buffer
);
164 /* Now translate and transfer to the DMA buffer */
167 skip
= ( AudioCtrl
->ahiac_Flags
& AHIACF_HIFI
) ? 2 : 1;
168 samples
= card
->current_bytesize
>> 1;
170 src
= card
->mix_buffer
;
171 dst
= card
->current_buffer
;
177 *dst
= ( ( *src
& 0xff ) << 8 ) | ( ( *src
& 0xff00 ) >> 8 );
185 IExec
->CacheClearE( card
->current_buffer
, (ULONG
) dst
- (ULONG
) card
->current_buffer
, CACRF_ClearD
);
187 IUtility
->CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
190 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
191 card
->playback_interrupt_enabled
= TRUE
;
195 /******************************************************************************
196 ** Record interrupt handler ***************************************************
197 ******************************************************************************/
200 RecordInterrupt( struct ExceptionContext
*pContext
, struct ExecBase
*SysBase
, struct CardData
* card
)
202 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
203 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
204 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
206 struct AHIRecordMessage rm
=
209 card
->current_record_buffer
,
210 RECORD_BUFFER_SAMPLES
213 int i
= 0, shorts
= card
->current_record_bytesize
/ 2;
214 WORD
* ptr
= (WORD
*) card
->current_record_buffer
;
217 IExec
->CacheClearE( card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_ClearD
);
221 *ptr
= ( ( *ptr
& 0xff ) << 8 ) | ( ( *ptr
& 0xff00 ) >> 8 );
227 IUtility
->CallHookPkt( AudioCtrl
->ahiac_SamplerFunc
, (Object
*) AudioCtrl
, &rm
);
229 IExec
->CacheClearE( card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_ClearD
);
232 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
233 card
->record_interrupt_enabled
= TRUE
;