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
;
62 /* Note that in OS4, we cannot call FindTask(NULL) here, since IExec
63 * is inside AHIsubBase! */
64 AudioCtrl
= (struct AHIAudioCtrlDrv
*) FindTask(NULL
)->tc_UserData
;
65 AHIsubBase
= (struct DriverBase
*) dd
->ahisubbase
;
67 dd
->slavesignal
= AllocSignal( -1 );
69 if( dd
->slavesignal
!= -1 )
71 struct MsgPort
* ahi_mp
= NULL
;
72 struct AHIRequest
* ahi_iorequest
= NULL
;
73 APTR ahi_iocopy
= NULL
;
76 struct AHIRequest
* ahi_io
[ 2 ] = { NULL
, NULL
};
77 BOOL ahi_io_used
[ 2 ] = { FALSE
, FALSE
};
79 ULONG frame_length
= 0;
81 ahi_mp
= CreateMsgPort();
85 ahi_iorequest
= (struct AHIRequest
*) CreateIORequest( ahi_mp
, sizeof( struct AHIRequest
) );
87 if( ahi_iorequest
!= NULL
)
89 ahi_iorequest
->ahir_Version
= 4;
91 ahi_device
= OpenDevice( AHINAME
, dd
->unit
,
92 (struct IORequest
*) ahi_iorequest
, 0 );
96 struct Library
* AHIBase
= (struct Library
*) ahi_iorequest
->ahir_Std
.io_Device
;
98 struct AHIIFace
* IAHI
= (struct AHIIFace
*) GetInterface(AHIBase
, "main", 1, NULL
);
101 ahi_iocopy
= AllocVec( sizeof( *ahi_iorequest
), MEMF_ANY
);
103 if( ahi_iocopy
!= NULL
)
105 bcopy( ahi_iorequest
, ahi_iocopy
, sizeof( *ahi_iorequest
) );
107 ahi_io
[ 0 ] = ahi_iorequest
;
108 ahi_io
[ 1 ] = ahi_iocopy
;
110 // Everything set up. Tell Master we're alive and healthy.
112 Signal( (struct Task
*) dd
->mastertask
,
113 1L << dd
->mastersignal
);
117 // The main playback loop follow
123 struct AHIRequest
* tmp_io
;
125 if( ahi_io_used
[ 0 ] )
128 ULONG mask
= ( SIGBREAKF_CTRL_C
|
129 (1L << dd
->slavesignal
) |
130 (1L << ahi_mp
->mp_SigBit
) );
132 signals
= Wait( mask
);
134 if( signals
& ( SIGBREAKF_CTRL_C
|
135 (1L << dd
->slavesignal
) ) )
141 err
= WaitIO( (struct IORequest
*) ahi_io
[ 0 ] );
145 KPrintF( DRIVER
": AHI device error %ld\n", err
);
151 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
,
152 (Object
*) AudioCtrl
, 0 );
154 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, AudioCtrl
, NULL
);
158 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, AudioCtrl
,
159 dd
->mixbuffers
[ 0 ] );
162 CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
164 if( frame_length
== 0 )
166 frame_length
= AHI_SampleFrameSize( AudioCtrl
->ahiac_BuffType
);
169 ahi_io
[ 0 ]->ahir_Std
.io_Command
= CMD_WRITE
;
170 ahi_io
[ 0 ]->ahir_Std
.io_Data
= dd
->mixbuffers
[ 0 ];
171 ahi_io
[ 0 ]->ahir_Std
.io_Length
= ( AudioCtrl
->ahiac_BuffSamples
*
173 ahi_io
[ 0 ]->ahir_Std
.io_Offset
= 0;
174 ahi_io
[ 0 ]->ahir_Frequency
= AudioCtrl
->ahiac_MixFreq
;
175 ahi_io
[ 0 ]->ahir_Type
= AudioCtrl
->ahiac_BuffType
;
176 ahi_io
[ 0 ]->ahir_Volume
= 0x10000;
177 ahi_io
[ 0 ]->ahir_Position
= 0x08000;
178 ahi_io
[ 0 ]->ahir_Link
= ( ahi_io_used
[ 1 ] ?
179 ahi_io
[ 1 ] : NULL
);
181 SendIO( (struct IORequest
*) ahi_io
[ 0 ] );
183 tmp_io
= ahi_io
[ 0 ];
184 ahi_io
[ 0 ] = ahi_io
[ 1 ];
185 ahi_io
[ 1 ] = tmp_io
;
187 tmp_buff
= dd
->mixbuffers
[ 0 ];
188 dd
->mixbuffers
[ 0 ] = dd
->mixbuffers
[ 1 ];
189 dd
->mixbuffers
[ 1 ] = tmp_buff
;
191 ahi_io_used
[ 0 ] = ahi_io_used
[ 1 ];
192 ahi_io_used
[ 1 ] = TRUE
;
196 if( ahi_io_used
[ 0 ] )
198 AbortIO( (struct IORequest
*) ahi_io
[ 0 ] );
199 WaitIO( (struct IORequest
*) ahi_io
[ 0 ] );
202 if( ahi_io_used
[ 1 ] )
204 AbortIO( (struct IORequest
*) ahi_io
[ 1 ] );
205 WaitIO( (struct IORequest
*) ahi_io
[ 1 ] );
208 FreeVec( ahi_iocopy
);
212 DropInterface((struct Interface
*) IAHI
);
214 CloseDevice( (struct IORequest
*) ahi_iorequest
);
217 DeleteIORequest( (struct IORequest
*) ahi_iorequest
);
220 DeleteMsgPort( ahi_mp
);
224 FreeSignal( dd
->slavesignal
);
225 dd
->slavesignal
= -1;
229 // Tell the Master we're dying
231 Signal( (struct Task
*) dd
->mastertask
,
232 1L << dd
->mastersignal
);
234 dd
->slavetask
= NULL
;
236 // Multitasking will resume when we are dead.