2 Copyright © 2005-2013, Davy Wentzler. All rights reserved.
3 Copyright © 2010-2016, The AROS Development Team. All rights reserved.
10 #include <proto/expansion.h>
11 #include <libraries/ahi_sub.h>
12 #include <proto/exec.h>
16 #include "interrupt.h"
19 #include "pci_wrapper.h"
21 #define min(a,b) ((a)<(b)?(a):(b))
23 /******************************************************************************
24 ** Hardware interrupt handler *************************************************
25 ******************************************************************************/
29 LONG
CardInterrupt(struct ExceptionContext
*pContext
,
30 struct ExecBase
*SysBase
, struct CardData
* card
)
32 LONG
CardInterrupt(struct CardData
* card
)
36 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
42 intreq
= pci_inl(VIA_REG_SGD_SHADOW
, card
);
44 //DebugPrintF("INT %lx\n", intreq);
47 unsigned char play_status
= pci_inb(VIA_REG_OFFSET_STATUS
, card
),
48 rec_status
= pci_inb(VIA_REG_OFFSET_STATUS
+ RECORD
, card
);
50 play_status
&= (VIA_REG_STAT_EOL
|VIA_REG_STAT_FLAG
|VIA_REG_STAT_STOPPED
);
54 pci_outb(play_status
, VIA_REG_OFFSET_STATUS
, card
);
56 if (play_status
& VIA_REG_STAT_FLAG
)
59 card
->current_buffer
= card
->playback_buffer1
;
61 else if (play_status
& VIA_REG_STAT_EOL
)
64 card
->current_buffer
= card
->playback_buffer2
;
67 card
->playback_interrupt_enabled
= FALSE
;
68 Cause( &card
->playback_interrupt
);
71 rec_status
&= (VIA_REG_STAT_EOL
|VIA_REG_STAT_FLAG
|VIA_REG_STAT_STOPPED
);
74 //DebugPrintF("REC!\n");
75 pci_outb(rec_status
, VIA_REG_OFFSET_STATUS
+ RECORD
, card
);
77 if (rec_status
& VIA_REG_STAT_FLAG
)
80 card
->current_record_buffer
= card
->record_buffer1
;
82 else if (rec_status
& VIA_REG_STAT_EOL
)
85 card
->current_record_buffer
= card
->record_buffer2
;
88 card
->record_interrupt_enabled
= FALSE
;
89 Cause( &card
->record_interrupt
);
99 /******************************************************************************
100 ** Playback interrupt handler *************************************************
101 ******************************************************************************/
104 void PlaybackInterrupt(struct ExceptionContext
*pContext
,
105 struct ExecBase
*SysBase
, struct CardData
* card
)
107 void PlaybackInterrupt(struct CardData
* card
)
110 struct AHIAudioCtrlDrv
* AudioCtrl
;
111 struct DriverBase
* AHIsubBase
;
116 AudioCtrl
= card
->audioctrl
;
117 AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
119 if( card
->mix_buffer
!= NULL
&& card
->current_buffer
!= NULL
)
129 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
, (Object
*) AudioCtrl
, 0 );
130 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, (Object
*) AudioCtrl
, NULL
);
132 //DebugPrintF("skip_mix = %d\n", skip_mix);
136 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, (Object
*) AudioCtrl
, card
->mix_buffer
);
139 /* Now translate and transfer to the DMA buffer */
142 skip
= ( AudioCtrl
->ahiac_Flags
& AHIACF_HIFI
) ? 2 : 1;
143 samples
= card
->current_bytesize
>> 1;
145 src
= card
->mix_buffer
;
146 #if !defined(__amigaos4__) && !AROS_BIG_ENDIAN
150 dst
= card
->current_buffer
;
157 *dst
= ( ( *src
& 0xff ) << 8 ) | ( ( *src
& 0xff00 ) >> 8 );
159 *dst
= AROS_WORD2LE(*src
);
167 CacheClearE( card
->current_buffer
, (ULONG
) dst
- (ULONG
) card
->current_buffer
, CACRF_ClearD
);
168 CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
171 card
->playback_interrupt_enabled
= TRUE
;
175 /******************************************************************************
176 ** Record interrupt handler ***************************************************
177 ******************************************************************************/
180 void RecordInterrupt(struct ExceptionContext
*pContext
,
181 struct ExecBase
*SysBase
, struct CardData
* card
)
183 void RecordInterrupt(struct CardData
* card
)
186 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
187 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
189 struct AHIRecordMessage rm
=
192 card
->current_record_buffer
,
193 RECORD_BUFFER_SAMPLES
196 int i
= 0, shorts
= card
->current_record_bytesize
/ 2;
197 WORD
* ptr
= card
->current_record_buffer
;
202 #if defined(__AMIGAOS4__) || AROS_BIG_ENDIAN
203 *ptr
= ( ( *ptr
& 0xff ) << 8 ) | ( ( *ptr
& 0xff00 ) >> 8 );
209 CallHookPkt( AudioCtrl
->ahiac_SamplerFunc
, (Object
*) AudioCtrl
, &rm
);
211 card
->record_interrupt_enabled
= TRUE
;