bcpl: Fill in some missing functions, discovered from L:Shell-Seg from KS 1.3
[AROS.git] / workbench / devs / AHI / Drivers / SB128 / SB128 / interrupt.c
blob25de32d1ff7dc28874b161c3969b5d02f4fa0097
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 #include <config.h>
20 #undef __USE_INLINE__
21 #include <proto/expansion.h>
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"
29 #define min(a,b) ((a)<(b)?(a):(b))
31 unsigned long z = 0;
32 /******************************************************************************
33 ** Hardware interrupt handler *************************************************
34 ******************************************************************************/
37 LONG
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;
44 ULONG intreq;
45 LONG handled = 0;
46 while (((intreq = (dev->InLong(card->iobase + SB128_STATUS))) & SB128_INT_PENDING) != 0)
48 if( intreq & SB128_INT_DAC2 && AudioCtrl != NULL )
50 /* Clear interrupt pending bit(s) and re-enable playback interrupts */
51 dev->OutLong(card->iobase + SB128_SCON, (dev->InLong(card->iobase + SB128_SCON) & ~SB128_DAC2_INTEN));
52 dev->OutLong(card->iobase + SB128_SCON, (dev->InLong(card->iobase + SB128_SCON) | SB128_DAC2_INTEN));
54 if (card->flip == 0) /* just played buf 1 */
56 card->flip = 1;
57 card->current_buffer = card->playback_buffer;
59 else /* just played buf 2 */
61 card->flip = 0;
62 card->current_buffer = (APTR) ((unsigned long) card->playback_buffer + card->current_bytesize);
65 card->playback_interrupt_enabled = FALSE;
66 IExec->Cause( &card->playback_interrupt );
69 if( intreq & SB128_INT_ADC && AudioCtrl != NULL )
71 /* Clear interrupt pending bit(s) and re-enable record interrupts */
72 dev->OutLong(card->iobase + SB128_SCON, (dev->InLong(card->iobase + SB128_SCON) & ~SB128_ADC_INTEN));
73 dev->OutLong(card->iobase + SB128_SCON, (dev->InLong(card->iobase + SB128_SCON) | SB128_ADC_INTEN));
75 if( card->record_interrupt_enabled )
77 /* Invoke softint to convert and feed AHI with the new sample data */
79 if (card->recflip == 0) /* just filled buf 1 */
81 card->recflip = 1;
82 card->current_record_buffer = card->record_buffer;
84 else /* just filled buf 2 */
86 card->recflip = 0;
87 card->current_record_buffer = (APTR) ((unsigned long) card->record_buffer + card->current_record_bytesize);
89 card->record_interrupt_enabled = FALSE;
90 IExec->Cause( &card->record_interrupt );
93 exit:
94 handled = 1;
98 return handled;
102 /******************************************************************************
103 ** Playback interrupt handler *************************************************
104 ******************************************************************************/
106 void
107 PlaybackInterrupt( struct ExceptionContext *pContext, struct ExecBase *SysBase, struct CardData* card )
109 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
110 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
111 struct PCIDevice *dev = (struct PCIDevice * ) card->pci_dev;
113 if( card->mix_buffer != NULL && card->current_buffer != NULL )
115 BOOL skip_mix;
117 WORD* src;
118 WORD* dst;
119 size_t skip;
120 size_t samples;
121 int i;
123 skip_mix = IUtility->CallHookPkt( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );
124 IUtility->CallHookPkt( AudioCtrl->ahiac_PlayerFunc, (Object*) AudioCtrl, NULL );
126 if( ! skip_mix )
128 IUtility->CallHookPkt( AudioCtrl->ahiac_MixerFunc, (Object*) AudioCtrl, card->mix_buffer );
131 /* Now translate and transfer to the DMA buffer */
133 skip = ( AudioCtrl->ahiac_Flags & AHIACF_HIFI ) ? 2 : 1;
134 samples = card->current_bytesize >> 1;
136 src = card->mix_buffer;
137 dst = card->current_buffer;
139 i = samples;
141 while( i > 0 )
143 *dst = ( ( *src & 0xff ) << 8 ) | ( ( *src & 0xff00 ) >> 8 );
145 src += skip;
146 dst += 1;
148 --i;
151 //Flush cache so that data is completely written to the DMA buffer - Articia hack
152 IExec->CacheClearE(card->current_buffer, card->current_bytesize, CACRF_ClearD);
154 IUtility->CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
156 card->playback_interrupt_enabled = TRUE;
160 /******************************************************************************
161 ** Record interrupt handler ***************************************************
162 ******************************************************************************/
164 void
165 RecordInterrupt( struct ExceptionContext *pContext, struct ExecBase *SysBase, struct CardData* card )
167 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
168 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
169 struct PCIDevice *dev = (struct PCIDevice * ) card->pci_dev;
171 struct AHIRecordMessage rm =
173 AHIST_S16S,
174 card->current_record_buffer,
175 RECORD_BUFFER_SAMPLES
178 int i = 0, shorts = card->current_record_bytesize / 2;
179 WORD* ptr = card->current_record_buffer;
181 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
182 IExec->CacheClearE(card->current_record_buffer, card->current_record_bytesize, CACRF_InvalidateD);
184 while( i < shorts )
186 *ptr = ( ( *ptr & 0xff ) << 8 ) | ( ( *ptr & 0xff00 ) >> 8 );
188 ++i;
189 ++ptr;
192 IUtility->CallHookPkt( AudioCtrl->ahiac_SamplerFunc, (Object*) AudioCtrl, &rm );
194 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
195 IExec->CacheClearE(card->current_record_buffer, card->current_record_bytesize, CACRF_InvalidateD);
197 card->record_interrupt_enabled = TRUE;