4 #include <devices/ahi.h>
6 #include <exec/execbase.h>
7 #include <libraries/ahi_sub.h>
9 #include <proto/exec.h>
10 #include <proto/utility.h>
14 #include "DriverData.h"
17 #define dd ((struct DeviceData*) AudioCtrl->ahiac_DriverData)
19 /******************************************************************************
20 ** The slave process **********************************************************
21 ******************************************************************************/
25 static void Slave( struct ExecBase
* SysBase
);
27 #if defined( __AROS__ )
29 #include <aros/asmcall.h>
31 AROS_UFH3(LONG
, SlaveEntry
,
32 AROS_UFHA(STRPTR
, argPtr
, A0
),
33 AROS_UFHA(ULONG
, argSize
, D0
),
34 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
46 struct ExecBase
* SysBase
= *((struct ExecBase
**) 4);
55 Slave( struct ExecBase
* SysBase
)
57 struct AHIAudioCtrlDrv
* AudioCtrl
;
58 struct DriverBase
* AHIsubBase
;
59 struct DeviceBase
* DeviceBase
;
63 /* Note that in OS4, we cannot call FindTask(NULL) here, since IExec
64 * is inside AHIsubBase! */
65 AudioCtrl
= (struct AHIAudioCtrlDrv
*) FindTask(NULL
)->tc_UserData
;
66 AHIsubBase
= (struct DriverBase
*) dd
->ahisubbase
;
67 DeviceBase
= (struct DeviceBase
*) AHIsubBase
;
69 dd
->slavesignal
= AllocSignal( -1 );
71 if( dd
->slavesignal
!= -1 )
73 struct MsgPort
* ahi_mp
= NULL
;
74 struct AHIRequest
* ahi_iorequest
= NULL
;
75 APTR ahi_iocopy
= NULL
;
78 struct AHIRequest
* ahi_io
[ 2 ] = { NULL
, NULL
};
79 BOOL ahi_io_used
[ 2 ] = { FALSE
, FALSE
};
81 ULONG frame_length
= 0;
83 ahi_mp
= CreateMsgPort();
87 ahi_iorequest
= (struct AHIRequest
*) CreateIORequest( ahi_mp
, sizeof( struct AHIRequest
) );
89 if( ahi_iorequest
!= NULL
)
91 ahi_iorequest
->ahir_Version
= 4;
93 ahi_device
= OpenDevice( AHINAME
, dd
->unit
,
94 (struct IORequest
*) ahi_iorequest
, 0 );
98 struct Library
* AHIBase
= (struct Library
*) ahi_iorequest
->ahir_Std
.io_Device
;
100 struct AHIIFace
* IAHI
= (struct AHIIFace
*) GetInterface(AHIBase
, "main", 1, NULL
);
103 ahi_iocopy
= AllocVec( sizeof( *ahi_iorequest
), MEMF_ANY
);
105 if( ahi_iocopy
!= NULL
)
107 bcopy( ahi_iorequest
, ahi_iocopy
, sizeof( *ahi_iorequest
) );
109 ahi_io
[ 0 ] = ahi_iorequest
;
110 ahi_io
[ 1 ] = ahi_iocopy
;
112 // Everything set up. Tell Master we're alive and healthy.
114 Signal( (struct Task
*) dd
->mastertask
,
115 1L << dd
->mastersignal
);
119 // The main playback loop follow
125 struct AHIRequest
* tmp_io
;
127 if( ahi_io_used
[ 0 ] )
130 ULONG mask
= ( SIGBREAKF_CTRL_C
|
131 (1L << dd
->slavesignal
) |
132 (1L << ahi_mp
->mp_SigBit
) );
134 signals
= Wait( mask
);
136 if( signals
& ( SIGBREAKF_CTRL_C
|
137 (1L << dd
->slavesignal
) ) )
143 err
= WaitIO( (struct IORequest
*) ahi_io
[ 0 ] );
147 KPrintF( DRIVER
": AHI device error %ld\n", err
);
153 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
,
154 (Object
*) AudioCtrl
, 0 );
156 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, AudioCtrl
, NULL
);
160 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, AudioCtrl
,
161 dd
->mixbuffers
[ 0 ] );
164 CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
166 if( frame_length
== 0 )
168 frame_length
= AHI_SampleFrameSize( AudioCtrl
->ahiac_BuffType
);
171 ahi_io
[ 0 ]->ahir_Std
.io_Command
= CMD_WRITE
;
172 ahi_io
[ 0 ]->ahir_Std
.io_Data
= dd
->mixbuffers
[ 0 ];
173 ahi_io
[ 0 ]->ahir_Std
.io_Length
= ( AudioCtrl
->ahiac_BuffSamples
*
175 ahi_io
[ 0 ]->ahir_Std
.io_Offset
= 0;
176 ahi_io
[ 0 ]->ahir_Frequency
= AudioCtrl
->ahiac_MixFreq
;
177 ahi_io
[ 0 ]->ahir_Type
= AudioCtrl
->ahiac_BuffType
;
178 ahi_io
[ 0 ]->ahir_Volume
= 0x10000;
179 ahi_io
[ 0 ]->ahir_Position
= 0x08000;
180 ahi_io
[ 0 ]->ahir_Link
= ( ahi_io_used
[ 1 ] ?
181 ahi_io
[ 1 ] : NULL
);
183 SendIO( (struct IORequest
*) ahi_io
[ 0 ] );
185 tmp_io
= ahi_io
[ 0 ];
186 ahi_io
[ 0 ] = ahi_io
[ 1 ];
187 ahi_io
[ 1 ] = tmp_io
;
189 tmp_buff
= dd
->mixbuffers
[ 0 ];
190 dd
->mixbuffers
[ 0 ] = dd
->mixbuffers
[ 1 ];
191 dd
->mixbuffers
[ 1 ] = tmp_buff
;
193 ahi_io_used
[ 0 ] = ahi_io_used
[ 1 ];
194 ahi_io_used
[ 1 ] = TRUE
;
198 if( ahi_io_used
[ 0 ] )
200 AbortIO( (struct IORequest
*) ahi_io
[ 0 ] );
201 WaitIO( (struct IORequest
*) ahi_io
[ 0 ] );
204 if( ahi_io_used
[ 1 ] )
206 AbortIO( (struct IORequest
*) ahi_io
[ 1 ] );
207 WaitIO( (struct IORequest
*) ahi_io
[ 1 ] );
210 FreeVec( ahi_iocopy
);
214 DropInterface((struct Interface
*) IAHI
);
216 CloseDevice( (struct IORequest
*) ahi_iorequest
);
219 DeleteIORequest( (struct IORequest
*) ahi_iorequest
);
222 DeleteMsgPort( ahi_mp
);
226 FreeSignal( dd
->slavesignal
);
227 dd
->slavesignal
= -1;
231 // Tell the Master we're dying
233 Signal( (struct Task
*) dd
->mastertask
,
234 1L << dd
->mastersignal
);
236 dd
->slavetask
= NULL
;
238 // Multitaking will resume when we are dead.