Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / Envy24 / interrupt.c
blobde26c55b53a55653d7d72a0ce518cc11a3d50122
1 /*
2 Copyright © 2004-2014, Davy Wentzler. All rights reserved.
3 Copyright © 2014-2016, The AROS Development Team. All rights reserved.
4 $Id$
5 */
7 #include <config.h>
9 #undef __USE_INLINE__
10 #include <proto/expansion.h>
11 #include <libraries/ahi_sub.h>
12 #include <proto/exec.h>
13 #include <stddef.h>
14 #include "library.h"
15 #include "regs.h"
16 #include "interrupt.h"
17 #include "pci_wrapper.h"
19 #define min(a,b) ((a)<(b)?(a):(b))
22 /******************************************************************************
23 ** Hardware interrupt handler *************************************************
24 ******************************************************************************/
27 AROS_INTH1(CardInterrupt, struct CardData *, card)
29 AROS_INTFUNC_INIT
31 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
33 unsigned char intreq;
34 LONG handled = 0;
36 //DebugPrintF("INT\n");
37 while ( ( intreq = ( pci_inb(CCS_INTR_STATUS, card) ) ) != 0 )
39 //DebugPrintF("INT %x\n", intreq);
41 if (intreq & CCS_INTR_PRO_MACRO)
43 unsigned char mtstatus = pci_inb_mt(MT_INTR_MASK_STATUS, card);
45 //DebugPrintF("CCS_INTR_PRO_MACRO, mtstatus = %x\n", mtstatus);
47 if( (mtstatus & MT_PLAY_STATUS) && AudioCtrl != NULL )
49 pci_outb_mt(mtstatus | MT_PLAY_STATUS, MT_INTR_MASK_STATUS, card); // clear interrupt
51 if (card->flip == 0) // just played buf 1
53 card->flip = 1;
54 card->current_buffer = card->playback_buffer;
56 else // just played buf 2
58 card->flip = 0;
59 card->current_buffer = (APTR) ((long) card->playback_buffer + card->current_bytesize);
62 card->playback_interrupt_enabled = FALSE;
63 Cause( &card->playback_interrupt );
66 if( (mtstatus & MT_REC_STATUS) && AudioCtrl != NULL )
68 pci_outb_mt(mtstatus | MT_REC_STATUS, MT_INTR_MASK_STATUS, card); // clear interrupt
69 //DebugPrintF("rec\n");
71 if( card->record_interrupt_enabled )
73 const unsigned long diff = pci_inl_mt(MT_DMA_REC_ADDRESS, card) - (unsigned long) card->record_buffer_32bit_phys;
75 //DebugPrintF("%lu\n", diff % card->current_record_bytesize_32bit);
77 /* Invoke softint to convert and feed AHI with the new sample data */
79 if (diff >= card->current_record_bytesize_32bit) // just played buf 1
81 if (card->recflip == 1)
82 DebugPrintF("A: Missed IRQ!\n");
84 card->recflip = 1;
85 card->current_record_buffer = card->record_buffer;
86 card->current_record_buffer_32bit = card->record_buffer_32bit;
88 else // just played buf 2
90 if (card->recflip == 0)
91 DebugPrintF("B: Missed IRQ!\n");
93 card->recflip = 0;
94 card->current_record_buffer = (APTR) ((unsigned long) card->record_buffer + card->current_record_bytesize_target);
95 card->current_record_buffer_32bit = (APTR) ((unsigned long) card->record_buffer_32bit + card->current_record_bytesize_32bit);
97 card->record_interrupt_enabled = FALSE;
98 Cause( &card->record_interrupt );
103 else
105 DebugPrintF("Oh dear, it's not CCS_INTR_PLAYREC!\n");
108 handled = 1;
111 return handled;
113 AROS_INTFUNC_EXIT
117 /******************************************************************************
118 ** Playback interrupt handler *************************************************
119 ******************************************************************************/
121 AROS_INTH1(PlaybackInterrupt, struct CardData *, card)
123 AROS_INTFUNC_INIT
125 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
126 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
127 BOOL stereo = (AudioCtrl->ahiac_Flags & AHIACF_STEREO) != 0;
129 if( card->mix_buffer != NULL && card->current_buffer != NULL )
131 BOOL skip_mix;
133 WORD* src;
134 int i;
135 LONG *srclong, *dstlong, left, right;
136 int frames = card->current_frames;
138 skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );
139 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, (Object*) AudioCtrl, NULL );
141 //DebugPrintF("skip_mix = %d\n", skip_mix);
143 if( ! skip_mix )
145 CallHookPkt( AudioCtrl->ahiac_MixerFunc, (Object*) AudioCtrl, card->mix_buffer );
148 /* Now translate and transfer to the DMA buffer */
150 src = card->mix_buffer;
151 srclong = (LONG*) card->mix_buffer;
152 dstlong = (LONG*) card->current_buffer;
154 i = frames;
156 while( i > 0 )
158 if (AudioCtrl->ahiac_Flags & AHIACF_HIFI)
160 left = AROS_LONG2LE(*srclong++);
161 if (stereo)
162 right = AROS_LONG2LE(*srclong++);
163 else
164 right = left;
166 else
168 left = AROS_LONG2LE(*src++ << 16);
169 if (stereo)
170 right = AROS_LONG2LE(*src++ << 16);
171 else
172 right = left;
175 *dstlong++ = left; // out 1 - 2
176 *dstlong++ = right;
178 *dstlong++ = left;
179 *dstlong++ = right;
181 dstlong+= 4;
183 // S/PDIF
184 *dstlong++ = left;
185 *dstlong++ = right;
187 --i;
190 CacheClearE(card->current_buffer, (ULONG) dstlong - (ULONG) card->current_buffer, CACRF_ClearD);
191 CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
194 card->playback_interrupt_enabled = TRUE;
196 return FALSE;
198 AROS_INTFUNC_EXIT
202 /******************************************************************************
203 ** Record interrupt handler ***************************************************
204 ******************************************************************************/
206 AROS_INTH1(RecordInterrupt, struct CardData *, card)
208 AROS_INTFUNC_INIT
210 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
211 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
213 struct AHIRecordMessage rm =
215 AHIST_S16S,
216 card->current_record_buffer,
217 RECORD_BUFFER_SAMPLES
220 long *src = card->current_record_buffer_32bit;
221 WORD* dst = card->current_record_buffer;
222 int i = 0, frames = RECORD_BUFFER_SAMPLES;
224 CacheClearE( card->current_record_buffer, card->current_record_bytesize_target, CACRF_ClearD);
225 CacheClearE( card->current_record_buffer_32bit, card->current_record_bytesize_32bit, CACRF_ClearD);
227 i = frames;
229 if (card->SubType == PHASE88 || card->SubType == MAUDIO_1010LT)
231 src += card->input * 2;
232 while( i > 0 )
234 *dst++ = AROS_LE2LONG(*src++) >> 16;
235 *dst++ = AROS_LE2LONG(*src) >> 16;
237 src+=11;
239 i--;
242 else
244 if (card->input != 1)
246 while( i > 0 )
248 *dst++ = AROS_LE2LONG(*src++) >> 16;
249 *dst++ = AROS_LE2LONG(*src) >> 16;
251 src+=11;
253 i--;
256 else
258 while( i > 0 )
260 src+=2;
262 *dst++ = AROS_LE2LONG(*src++) >> 16;
263 *dst++ = AROS_LE2LONG(*src) >> 16;
265 src+=9;
267 i--;
272 CallHookPkt( AudioCtrl->ahiac_SamplerFunc, (Object*) AudioCtrl, &rm );
273 CacheClearE( card->current_record_buffer, card->current_record_bytesize_target, CACRF_ClearD);
274 CacheClearE( card->current_record_buffer_32bit, card->current_record_bytesize_32bit, CACRF_ClearD);
276 card->record_interrupt_enabled = TRUE;
278 return FALSE;
280 AROS_INTFUNC_EXIT