Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / Toccata / asmfuncs.a
blob51b140d2c3a6cbc59d2b5eee53ba81c248fe5f1f
2 incdir include:
3 include exec/memory.i
4 include exec/tasks.i
5 include lvo/exec_lib.i
6 include devices/ahi.i
7 include libraries/ahi_sub.i
8 include libraries/toccata.i
9 include lvo/toccata_lib.i
10 include utility/hooks.i
11 include toccata.i
12 include macros.i
14 XDEF _intAHIsub_Disable
15 XDEF _intAHIsub_Enable
16 XDEF _intAHIsub_Update
17 XDEF _intAHIsub_SetVol
18 XDEF _intAHIsub_SetFreq
19 XDEF _intAHIsub_SetSound
20 XDEF _intAHIsub_SetEffect
21 XDEF _intAHIsub_LoadSound
22 XDEF _intAHIsub_UnloadSound
24 XDEF _SlaveProcessEntry
26 XDEF _RecordFunc
28 XDEF _PlayFuncMono
29 XDEF _PlayFuncStereo
30 XDEF _PlayFuncMono32
31 XDEF _PlayFuncStereo32
33 XDEF _MixFunc
35 XREF _SlaveProcess
36 XREF _NoTask
38 *******************************************************************************
40 ;in:
41 * a2 struct AHI_AudioCtrl
42 _intAHIsub_Disable:
43 push a6
44 move.l 4.w,a6
45 call Disable
46 pop a6
47 rts
49 ;in:
50 * a2 struct AHI_AudioCtrl
51 _intAHIsub_Enable:
52 push a6
53 move.l 4.w,a6
54 call Enable
55 pop a6
56 rts
59 * Unused functions
61 _intAHIsub_SetVol:
62 _intAHIsub_SetFreq:
63 _intAHIsub_SetSound:
64 _intAHIsub_SetEffect:
65 _intAHIsub_LoadSound:
66 _intAHIsub_UnloadSound:
67 moveq #AHIS_UNKNOWN,d0
68 _intAHIsub_Update:
69 rts
72 *******************************************************************************
74 _SlaveProcessEntry:
75 move.l 4.w,a6
76 suba.l a1,a1
77 call FindTask
78 move.l d0,a0
79 move.l TC_Userdata(a0),a2
80 move.l ahiac_DriverData(a2),a0
81 move.l t_AHIsubBase(a0),a6
82 bra _SlaveProcess
84 *******************************************************************************
85 ;in:
86 * d0 size
87 * a0 buffer
88 * a1 AudioCtrl
89 _RecordFunc:
90 pushm a2/a3
91 move.l a1,a2
92 move.l ahiac_DriverData(a2),a1
94 * Update dd->t_RecMessage->ahirm_Length:
95 move.l t_RecMessage(a1),a3
96 lsr.l #2,d0 ;bytes => samples
97 move.l d0,ahirm_Length(a3)
99 * Copy sample buffer
100 move.l t_RecBuffer(a1),a3
101 lsr.l #1,d0
102 bcs .1
103 subq.l #1,d0
104 bmi .exit
105 .loop
106 move.l (a0)+,(a3)+
108 move.l (a0)+,(a3)+
109 dbf d0,.loop
111 * Call the SamplerFunc Hook
112 move.l t_RecMessage(a1),a1
113 move.l ahiac_SamplerFunc(a2),a0
114 move.l h_Entry(a0),a3
115 jsr (a3)
116 .exit
117 moveq #TRUE,d0
118 popm a2/a3
121 *******************************************************************************
123 TocSamplesCnt EQUR d7
124 TocBuffer EQUR a6
127 * These functions fills the Toccata buffer with the mixed output. Since
128 * the Toccata buffer is not the same size as the mixing buffer, the mixing
129 * routine may have to be called several times each interrupt. Or if the mixing
130 * buffer is larger than the Toccata buffer, it may not be called at all.
132 * The routines are not very well commented, but they should be pretty stright-
133 * forward once you know what they actually do.
136 ;in:
137 * d0 scratch
138 * d1 scratch
139 * a0 scratch
140 * a1 ato_SoftIntData
141 * a5 scratch
143 PlayFunc_Pre MACRO
144 pushm d7/a2-a3/a6
145 move.l a1,a2 ;a2 is later used as Hook object
146 move.l ahiac_DriverData(a2),a5
148 * Swap Toccata buffer buffers and get pointer to one of them.
149 move.l t_SampBuffer1(a5),TocBuffer
150 move.l t_SampBuffer2(a5),t_SampBuffer1(a5)
151 move.l TocBuffer,t_SampBuffer2(a5)
153 * TocSamplesCnt is number of samples left in Toccata buffer to fill.
154 move.l t_TocSamples(a5),TocSamplesCnt
156 * t_MixSamplesCnt is uncopied samples left in mixing buffer
157 .loop
158 tst.l t_MixSamplesCnt(a5)
159 bne .fillTocBuffer
161 * There are no unplayed samples in the mixing buffer. Fill it again!
163 move.l ahiac_BuffSamples(a2),t_MixSamplesCnt(a5)
165 move.l t_MixBuffer1(a5),d0
166 move.l t_MixBuffer2(a5),t_MixBuffer1(a5)
167 move.l t_MixBuffer3(a5),t_MixBuffer2(a5)
168 move.l d0,t_MixBuffer3(a5)
170 move.l t_MixBuffer1(a5),t_MixBufferPtr(a5)
172 ; Now check if the mixing routine will mix more samples than are transfered
173 ; each software interrupt. If so, signal a (high-priority) task to do the
174 ; actual mixing. This is because one cannot be sure that the mixing routine
175 ; terminates before FIFO is empty. If the routine will mix less samples than
176 ; transfered, there is no need to use a task for it (in fact that would be a
177 ; pretty stupid idea, since the mixing hook may have to be called several
178 ; times during the interrupt.
180 move.l t_TocSamples(a5),d0
181 cmp.l ahiac_BuffSamples(a2),d0
182 bmi .taskmix
184 ; The mixing buffer is smaller than the toccata one => Mix in soft interrupt
186 .mixinline
187 move.l ahiac_PlayerFunc(a2),a0
188 suba.l a1,a1
189 move.l h_Entry(a0),a3
190 jsr (a3) ;Call Player Hook
192 *** NOTE: No protection against CPU overload when mixing inline!
193 move.l ahiac_MixerFunc(a2),a0
194 move.l t_MixBuffer3(a5),a1
195 move.l h_Entry(a0),a3
196 jsr (a3) ;Call Mixer Hook
197 bra .fillTocBuffer
198 .taskmix
200 ; The mixing buffer is larger than the toccata one => Signal task to mix.
201 ; But first, check if we're using a hard interrupt. If so, we Cause() a
202 ; SoftInt instead of signalling a task.
204 move.w sr,d0
205 and.w #%0000011100000000,d0 ;Check if we run as SoftInt (lev 0)
206 beq .nohardint
208 push a6
209 move.l 4.w,a6
210 move.l t_MixSoftInt(a5),a1
211 call Cause
212 pop a6
213 bra .fillTocBuffer
214 .nohardint
216 ; If the flag t_NoTask is TRUE, we mix in the software interrupt anyway.
218 tst.w t_NoTask(a5)
219 bne .mixinline
221 push a6
222 move.l 4.w,a6
223 move.l t_SlaveProcess(a5),a1
224 move.b t_MixSignal(a5),d1
225 moveq #0,d0
226 bset d1,d0
227 call Signal
228 pop a6
230 .fillTocBuffer
231 move.l t_MixSamplesCnt(a5),d0
232 sub.l d0,TocSamplesCnt
233 bpl .1
234 add.l TocSamplesCnt,d0
235 moveq #0,TocSamplesCnt
237 * d0 is now how many samples should be copied before either the Toccata buffer
238 * is full or the mixing is empty.
240 sub.l d0,t_MixSamplesCnt(a5)
242 * t_MixBufferPtr is the address (in the mixing buffer) where the next untouched
243 * sample is located.
244 move.l t_MixBufferPtr(a5),a0
245 lsr.l #1,d0 ;Just unrolling...
246 bcs .2
247 subq.l #1,d0
248 .transferLoop
249 ENDM
251 * Example:
252 * move.w (a0)+,(TocBuffer)+
254 * move.w (a0)+,(TocBuffer)+
256 PlayFunc_Post MACRO
257 dbf d0,.transferLoop
258 move.l a0,t_MixBufferPtr(a5) ;Update pointer till next time
259 tst.l TocSamplesCnt ;Is Toccata buffer full now?
260 bne .loop ;Nope, loop.
262 popm d7/a2-a3/a6
264 ENDM
271 _PlayFuncMono:
272 PlayFunc_Pre
273 move.w (a0)+,(TocBuffer)+
275 move.w (a0)+,(TocBuffer)+
276 PlayFunc_Post
279 _PlayFuncStereo:
280 PlayFunc_Pre
281 move.l (a0)+,(TocBuffer)+ ; 2 WORDs == left and right data
283 move.l (a0)+,(TocBuffer)+
284 PlayFunc_Post
286 _PlayFuncMono32:
287 PlayFunc_Pre
288 move.w (a0),(TocBuffer)+ ; Upper 16 bits...
289 addq.l #4,a0
291 move.w (a0),(TocBuffer)+ ; Upper 16 bits...
292 addq.l #4,a0
293 PlayFunc_Post
295 _PlayFuncStereo32:
296 PlayFunc_Pre
297 move.w (a0),(TocBuffer)+ ; Upper 16 bits...
298 move.w 4(a0),(TocBuffer)+ ; Upper 16 bits...
299 addq.l #8,a0
301 move.w (a0),(TocBuffer)+ ; Upper 16 bits...
302 move.w 4(a0),(TocBuffer)+ ; Upper 16 bits...
303 addq.l #8,a0
304 PlayFunc_Post
309 _MixFunc:
310 pushm a2-a3
311 move.l a1,a2 ;a2 is Hook object
312 move.l ahiac_DriverData(a2),a5
314 move.l ahiac_PlayerFunc(a2),a0
315 suba.l a1,a1
316 move.l h_Entry(a0),a3
317 jsr (a3) ;Call Player Hook
319 move.l ahiac_PreTimer(a2),a0
320 jsr (a0)
321 bne .mixed ;Skip mixing!
322 move.l ahiac_MixerFunc(a2),a0
323 move.l t_MixBuffer3(a5),a1
324 move.l h_Entry(a0),a3
325 jsr (a3) ;Call Mixer Hook
326 .mixed
327 move.l ahiac_PostTimer(a2),a0
328 jsr (a0)
330 popm a2-a3