Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / SB128 / interrupt.c
blobc5d3a88ec4f24c8cad8a5e9c667755dc271d28d1
1 /*
3 The contents of this file are subject to the AROS Public License Version 1.1 (the "License"); 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
6 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
7 ANY KIND, either express or implied. See the License for the specific language governing rights and
8 limitations under the License.
10 The Original Code is (C) Copyright 2004-2011 Ross Vumbaca.
12 The Initial Developer of the Original Code is Ross Vumbaca.
14 All Rights Reserved.
18 #if !defined(__AROS__)
19 #undef __USE_INLINE__
20 #include <proto/expansion.h>
21 #endif
22 #include <libraries/ahi_sub.h>
23 #include <proto/exec.h>
24 #include <stddef.h>
25 #include "library.h"
26 #include "regs.h"
27 #include "interrupt.h"
28 #include "pci_wrapper.h"
29 #ifdef __AROS__
30 #include <aros/debug.h>
31 #endif
33 #define min(a,b) ((a)<(b)?(a):(b))
35 unsigned long z = 0;
36 /******************************************************************************
37 ** Hardware interrupt handler *************************************************
38 ******************************************************************************/
41 LONG
42 CardInterrupt( struct SB128_DATA* card )
44 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
46 ULONG intreq;
47 LONG handled = 0;
49 D(bug("[CMI8738]: %s(card @ 0x%p)\n", __PRETTY_FUNCTION__, card));
51 while (((intreq = (pci_inl(SB128_STATUS, card))) & SB128_INT_PENDING) != 0)
53 if( intreq & SB128_INT_DAC2 && AudioCtrl != NULL )
55 /* Clear interrupt pending bit(s) and re-enable playback interrupts */
56 pci_outl((pci_inl(SB128_SCON, card) & ~SB128_DAC2_INTEN), SB128_SCON, card);
57 pci_outl((pci_inl(SB128_SCON, card) | SB128_DAC2_INTEN), SB128_SCON, card);
59 if (card->flip == 0) /* just played buf 1 */
61 card->flip = 1;
62 card->current_buffer = card->playback_buffer;
64 else /* just played buf 2 */
66 card->flip = 0;
67 card->current_buffer = (APTR) ((unsigned long) card->playback_buffer + card->current_bytesize);
70 card->playback_interrupt_enabled = FALSE;
71 Cause( &card->playback_interrupt );
74 if( intreq & SB128_INT_ADC && AudioCtrl != NULL )
76 /* Clear interrupt pending bit(s) and re-enable record interrupts */
77 pci_outl((pci_inl(SB128_SCON, card) & ~SB128_ADC_INTEN), SB128_SCON, card);
78 pci_outl((pci_inl(SB128_SCON, card) | SB128_ADC_INTEN), SB128_SCON, card);
80 if( card->record_interrupt_enabled )
82 /* Invoke softint to convert and feed AHI with the new sample data */
84 if (card->recflip == 0) /* just filled buf 1 */
86 card->recflip = 1;
87 card->current_record_buffer = card->record_buffer;
89 else /* just filled buf 2 */
91 card->recflip = 0;
92 card->current_record_buffer = (APTR) ((unsigned long) card->record_buffer + card->current_record_bytesize);
94 card->record_interrupt_enabled = FALSE;
95 Cause( &card->record_interrupt );
98 handled = 1;
102 return handled;
106 /******************************************************************************
107 ** Playback interrupt handler *************************************************
108 ******************************************************************************/
110 void
111 PlaybackInterrupt( struct SB128_DATA* card )
113 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
114 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
116 if( card->mix_buffer != NULL && card->current_buffer != NULL )
118 BOOL skip_mix;
120 WORD* src;
121 WORD* dst;
122 size_t skip;
123 size_t samples;
124 int i;
126 skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );
127 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, (Object*) AudioCtrl, NULL );
129 if( ! skip_mix )
131 CallHookPkt( AudioCtrl->ahiac_MixerFunc, (Object*) AudioCtrl, card->mix_buffer );
134 /* Now translate and transfer to the DMA buffer */
136 skip = ( AudioCtrl->ahiac_Flags & AHIACF_HIFI ) ? 2 : 1;
137 samples = card->current_bytesize >> 1;
139 src = card->mix_buffer;
140 #if !AROS_BIG_ENDIAN
141 if(skip == 2)
142 src++;
143 #endif
144 dst = card->current_buffer;
146 i = samples;
148 while( i > 0 )
150 #ifdef __AMIGAOS4__
151 *dst = ( ( *src & 0xff ) << 8 ) | ( ( *src & 0xff00 ) >> 8 );
152 #else
153 *dst = *src;
154 #endif
156 src += skip;
157 dst += 1;
159 --i;
162 //Flush cache so that data is completely written to the DMA buffer - Articia hack
163 CacheClearE(card->current_buffer, card->current_bytesize, CACRF_ClearD);
165 CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
167 card->playback_interrupt_enabled = TRUE;
171 /******************************************************************************
172 ** Record interrupt handler ***************************************************
173 ******************************************************************************/
175 void
176 RecordInterrupt( struct SB128_DATA* card )
178 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
179 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
181 struct AHIRecordMessage rm =
183 AHIST_S16S,
184 card->current_record_buffer,
185 RECORD_BUFFER_SAMPLES
188 #ifdef __AMIGAOS4__
189 int i = 0, shorts = card->current_record_bytesize / 2;
190 WORD* ptr = card->current_record_buffer;
191 #endif
193 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
194 CacheClearE(card->current_record_buffer, card->current_record_bytesize, CACRF_InvalidateD);
196 #ifdef __AMIGAOS4__
197 while( i < shorts )
199 *ptr = ( ( *ptr & 0xff ) << 8 ) | ( ( *ptr & 0xff00 ) >> 8 );
201 ++i;
202 ++ptr;
204 #endif
206 CallHookPkt( AudioCtrl->ahiac_SamplerFunc, (Object*) AudioCtrl, &rm );
208 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
209 CacheClearE(card->current_record_buffer, card->current_record_bytesize, CACRF_InvalidateD);
211 card->record_interrupt_enabled = TRUE;