PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
st.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "libspu2_internal.h"
12
13static unsigned int _st_core = 0u;
14static int _spu_st_stat_int = 0;
15static int _spu_st_start_voice_bit = 0;
16static int _spu_st_start_tmp_voice_bit = 0;
17static int _spu_st_start_add_voice_bit = 0;
18static int _spu_st_start_prepare_voice_bit = 0;
19static int _spu_st_start_prepare_tmp_voice_bit = 0;
20static int _spu_st_start_prepared_voice_bit = 0;
21static int _spu_st_stop_voice_bit = 0;
22static int _spu_st_stop_saved_voice_bit = 0;
23static int _spu_st_tmp_voice_bit = 0;
24
25static SpuStEnv _spu_st_Info;
26static u32 _spu_st_buf_sizeSBhalf;
27static int _spu_st_save_final_block[98];
28static int _spu_st_start_prepare_voice_current;
29static SpuTransferCallbackProc _spu_st_cb_transfer_saved;
30static SpuStCallbackProc _spu_st_cb_prepare_finished;
31static int _spu_st_start_prepare_lock;
32static int _spu_st_bufferP;
33static int _spu_st_start_voice_smallest;
34static int _spu_st_stop_voice_smallest;
35static SpuIRQCallbackProc _spu_st_cb_IRQ_saved;
36static SpuStCallbackProc _spu_st_cb_stream_finished;
37static unsigned int _spu_st_addrIRQ;
38static int _spu_st_start_tmp_voice_current;
39static int _spu_st_start_add_lock;
40static SpuStCallbackProc _spu_st_cb_transfer_finished;
41static int _spu_st_start_prepare_voice_smallest;
42
43static void _SpuStSetMarkSTART(int voice)
44{
45 u8 *v1;
46
47 v1 = (u8 *)(_spu_st_Info.voice[voice].data_addr + 1);
48 *v1 = 6;
49 v1[16] = 2;
50 v1[_spu_st_buf_sizeSBhalf - 16] = 2;
51 FlushDcache();
52}
53
54static void _SpuStSetMarkEND(int voice)
55{
56 u8 *v1;
57
58 v1 = (u8 *)(_spu_st_Info.voice[voice].data_addr + 1);
59 *v1 = 2;
60 v1[16] = 2;
61 v1[_spu_st_buf_sizeSBhalf - 16] = 3;
62 FlushDcache();
63}
64
65static void _SpuStSetMarkFINAL(int voice)
66{
67 unsigned int v1;
68 int *v2;
69 u8 *v3;
70 int v4;
71 u8 *v5;
72 u8 *v6;
73
74 v1 = 16 * voice;
75 v2 = &_spu_st_save_final_block[v1 / 4];
76 v3 = (u8 *)(_spu_st_Info.voice[v1 / 0x10].data_addr + _spu_st_Info.voice[v1 / 0x10].last_size - 16);
77 *(u8 *)v2 = *v3;
78 *v3 = 0;
79 v3 += 1;
80 v2 = (int *)((char *)v2 + 1);
81 *(u8 *)v2 = *v3;
82 v5 = (u8 *)v2 + 1;
83 *v3 = 7;
84 v6 = v3 + 1;
85 for ( v4 = 0; v4 < 14; v4 += 1 )
86 {
87 v5[v4] = v6[v4];
88 v6[v4] = 0;
89 }
90 FlushDcache();
91}
92
93static void _SpuStSetMarkFINALrecover(int voice)
94{
95 unsigned int v1;
96 int *v2;
97 int v3;
98 u8 *v4;
99
100 v1 = 16 * voice;
101 v2 = &_spu_st_save_final_block[v1 / 4];
102 v4 = (u8 *)(_spu_st_Info.voice[v1 / 0x10].data_addr + _spu_st_Info.voice[v1 / 0x10].last_size - 16);
103 for ( v3 = 0; v3 < 16; v3 += 1 )
104 {
105 v4[v3] = ((u8 *)v2)[v3];
106 }
107 FlushDcache();
108}
109
110static SpuStVoiceAttr *_SpuStSetPrepareEnv(int voice)
111{
112 SpuStVoiceAttr *v2;
113
114 v2 = &_spu_st_Info.voice[voice];
115 _spu_t(2, 8 * (v2->buf_addr >> 4));
116 _SpuStSetMarkSTART(voice);
117 _spu_t(1);
118 return v2;
119}
120
121void _SpuStCBPrepare(void)
122{
123 int v0;
124
125 v0 = _spu_st_start_prepare_voice_bit & ~(1 << _spu_st_start_prepare_voice_current);
126 _spu_st_start_prepare_voice_bit = v0;
127 if ( v0 )
128 {
129 int v1;
130
131 for ( v1 = _spu_st_start_prepare_voice_current + 1; v1 < 24; v1 += 1 )
132 {
133 if ( (v0 & (1 << v1)) != 0 )
134 break;
135 }
136 _spu_st_start_prepare_voice_current = v1;
137 if ( v1 < 24 )
138 {
139 _spu_t(3, _SpuStSetPrepareEnv(v1)->data_addr, _spu_st_buf_sizeSBhalf);
140 }
141 }
142 else
143 {
144 SpuSetTransferCallback(_spu_st_cb_transfer_saved);
145 if ( _spu_st_Info.low_priority == SPU_ON )
146 _spu_FsetPCR(1);
147 _spu_st_stat_int = 34;
148 if ( _spu_st_cb_prepare_finished )
149 {
150 _spu_st_cb_prepare_finished(_spu_st_start_prepare_tmp_voice_bit, SPU_ST_PREPARE);
151 _spu_st_start_prepare_tmp_voice_bit = 0;
152 }
153 }
154 FlushDcache();
155}
156
157static int _SpuStStartPrepare(int voice_bit)
158{
159 int v1;
160 int v3;
161
162 for ( v1 = 0; v1 < 24; v1 += 1 )
163 {
164 if ( (voice_bit & (1 << v1)) != 0 )
165 break;
166 }
167 v3 = _spu_st_stat_int & 0xF0;
168 if ( v3 == 32 )
169 return SPU_ST_WRONG_STATUS;
170 if ( (_spu_st_stat_int & 0xF0u) >= 0x21 )
171 {
172 if ( v3 == 48 )
173 {
174 _spu_st_start_prepare_tmp_voice_bit = voice_bit;
175 _spu_st_start_prepare_voice_bit = voice_bit;
176 _spu_st_start_prepare_voice_current = v1;
177 _spu_st_start_prepare_lock = 0;
178 return SPU_ST_ACCEPT;
179 }
180 }
181 else
182 {
183 if ( v3 == 16 )
184 {
185 unsigned int data_addr;
186
187 _spu_st_stat_int = 32;
188 _spu_st_start_prepare_tmp_voice_bit = voice_bit;
189 _spu_st_start_prepare_voice_bit = voice_bit;
190 _spu_st_buf_sizeSBhalf = _spu_st_Info.size >> 1;
191 _spu_st_cb_transfer_saved = SpuSetTransferCallback(_SpuStCBPrepare);
192 if ( _spu_st_Info.low_priority == SPU_ON )
193 _spu_FsetPCR(0);
194 _spu_st_bufferP = 0;
195 _spu_st_start_prepare_voice_current = v1;
196 data_addr = _SpuStSetPrepareEnv(v1)->data_addr;
197 _spu_st_stat_int = 33;
198 _spu_t(3, data_addr, _spu_st_buf_sizeSBhalf);
199 return SPU_ST_ACCEPT;
200 }
201 }
202 return SPU_ST_WRONG_STATUS;
203}
204
205int IntFunc(void)
206{
207 Kprintf("*********------------\n");
208 Kprintf("*********------------\n");
209 Kprintf("*********------------\n");
210 Kprintf("*********------------\n");
211 Kprintf("*********------------\n");
212 FlushDcache();
213 return 1;
214}
215
216static SpuStVoiceAttr *_SpuStSetTransferEnv(int voice)
217{
218 SpuStVoiceAttr *v2;
219 int v3;
220
221 v2 = &_spu_st_Info.voice[voice];
222 v3 = (v2->buf_addr >> 4) << 4;
223 if ( _spu_st_bufferP )
224 {
225 v3 += _spu_st_buf_sizeSBhalf;
226 _SpuStSetMarkEND(voice);
227 }
228 else
229 {
230 _SpuStSetMarkSTART(voice);
231 }
232 _spu_t(2, v3 >> 1);
233 if ( v2->status == 2 )
234 {
235 int v4;
236
237 _spu_st_start_voice_bit &= ~(1 << voice);
238 _spu_st_stop_voice_bit |= 1 << voice;
239 _SpuStSetMarkFINAL(voice);
240 if ( _spu_st_start_voice_bit )
241 {
242 for ( v4 = 0; v4 < 24; v4 += 1 )
243 {
244 if ( (_spu_st_start_voice_bit & (1 << v4)) != 0 )
245 break;
246 }
247 _spu_st_start_voice_smallest = v4;
248 }
249 else
250 {
251 _spu_st_start_voice_smallest = 24;
252 for ( v4 = 0; v4 < 24; v4 += 1 )
253 {
254 if ( (_spu_st_stop_voice_bit & (1 << v4)) != 0 )
255 break;
256 }
257 _spu_st_stop_voice_smallest = v4;
258 }
259 }
260 _spu_t(1);
261 return v2;
262}
263
264void _SpuStCB_IRQfinal(void)
265{
266 unsigned int v0;
267
268 v0 = SpuSetCore(_st_core);
269 SpuSetIRQ(SPU_OFF);
270 SpuSetCore(v0);
271 _spu_st_stat_int = 67;
272 SpuSetIRQCallback(_spu_st_cb_IRQ_saved);
273 SpuSetTransferCallback(_spu_st_cb_transfer_saved);
274 if ( _spu_st_Info.low_priority == SPU_ON )
275 _spu_FsetPCR(1);
276 if ( _spu_st_cb_stream_finished && _spu_st_stop_voice_bit )
277 _spu_st_cb_stream_finished(_spu_st_stop_voice_bit, SPU_ST_FINAL);
278 _spu_st_stop_voice_bit = 0;
279 _spu_st_stop_saved_voice_bit = 0;
280 _spu_st_stat_int = 16;
281}
282
283static void _SpuStCB_IRQ(void)
284{
285 int v0;
286 unsigned int v1;
287 int v2;
288 int v3;
289
290 FlushDcache();
291 v0 = -1;
292 v1 = SpuSetCore(_st_core);
293 SpuSetIRQ(SPU_OFF);
294 SpuSetCore(v1);
295 v2 = 0;
296 if ( (_spu_st_stat_int & 0xF0) == 64 )
297 v3 = 66;
298 else
299 v3 = 51;
300 _spu_st_stat_int = v3;
301 if ( _spu_st_stop_voice_bit )
302 {
303 int v4;
304
305 for ( v4 = 0; v4 < 24; v4 += 1 )
306 {
307 if ( (_spu_st_stop_voice_bit & (1 << v4)) != 0 )
308 {
309 int last_size;
310 unsigned int v8;
311 int v9;
312
313 last_size = _spu_st_Info.voice[v4].last_size;
314#ifdef LIB_1300
315 v8 = ((_spu_st_Info.voice[v4].buf_addr >> 4) << 4) + last_size - 8;
316#else
317 // Added in OSDSND 110U
318 v8 = ((_spu_st_Info.voice[v4].buf_addr >> 4) << 4) + last_size - 16;
319#endif
320 if ( !_spu_st_bufferP )
321 v8 += _spu_st_buf_sizeSBhalf;
322 v9 = SpuSetCore(_st_core);
323 _spu_FsetRXX(226 + (v4 * 6), (v8 >> 4) << 4, 1);
324 _spu_core = v9;
325 if ( v2 < last_size )
326 {
327 v2 = last_size;
328 v0 = v4;
329 }
330 }
331 }
332 }
333 if ( !_spu_st_start_voice_bit )
334 {
335 unsigned int v10;
336 unsigned int v11;
337
338#ifdef LIB_1300
339 if ( v2 < 9 )
340#else
341 // Added in OSDSND 110U
342 if ( v2 < 17 )
343#endif
344 {
345 _SpuStCB_IRQfinal();
346 return;
347 }
348 SpuSetIRQCallback(_SpuStCB_IRQfinal);
349#ifdef LIB_1300
350 v10 = ((_spu_st_Info.voice[v0].buf_addr >> 4) << 4) + v2 - 8;
351#else
352 // Added in OSDSND 110U
353 v10 = ((_spu_st_Info.voice[v0].buf_addr >> 4) << 4) + v2 - 16;
354#endif
355 _spu_st_addrIRQ = v10;
356 if ( !_spu_st_bufferP )
357 _spu_st_addrIRQ = v10 + _spu_st_buf_sizeSBhalf;
358 v11 = SpuSetCore(_st_core);
359 SpuSetIRQAddr(_spu_st_addrIRQ);
360 SpuSetCore(v11);
361 }
362 if ( _spu_st_cb_stream_finished && _spu_st_stop_saved_voice_bit )
363 _spu_st_cb_stream_finished(_spu_st_stop_saved_voice_bit, SPU_ST_PLAY);
364 if ( _spu_st_start_voice_bit )
365 {
366 _spu_st_start_tmp_voice_bit = _spu_st_start_voice_bit;
367 _spu_st_stop_saved_voice_bit = _spu_st_stop_voice_bit;
368 _spu_st_start_tmp_voice_current = _spu_st_start_voice_smallest;
369 if ( _spu_st_bufferP )
370 {
371 if ( _spu_st_start_add_voice_bit && _spu_st_start_prepared_voice_bit && !_spu_st_start_add_lock )
372 {
373 int v16;
374 unsigned int v17;
375 int v18;
376 int v20;
377
378 v16 = _spu_st_start_add_voice_bit & _spu_st_start_prepared_voice_bit;
379 v17 = SpuSetCore(_st_core);
380 SpuSetKey(SPU_ON, v16);
381 SpuSetCore(v17);
382 if ( (_spu_env & 1) != 0 )
383 {
384 unsigned int v19;
385
386 v19 = SpuSetCore(_st_core);
387 SpuFlush(SPU_EVENT_KEY);
388 SpuSetCore(v19);
389 }
390 _spu_st_start_prepared_voice_bit = 0;
391 _spu_st_start_add_voice_bit = 0;
392 v20 = _spu_st_start_voice_bit | v16;
393 _spu_st_start_voice_bit = v20;
394 _spu_st_start_tmp_voice_bit = v20;
395 for ( v18 = 0; v18 < 24; v18 += 1 )
396 {
397 if ( (v20 & (1 << v18)) != 0 )
398 break;
399 }
400 _spu_st_start_tmp_voice_current = v18;
401 _spu_st_start_voice_smallest = v18;
402 }
403 }
404 else
405 {
406 int v13;
407
408 v13 = _spu_st_start_prepare_voice_bit;
409 if ( _spu_st_start_prepare_voice_bit && !_spu_st_start_prepare_lock )
410 {
411 int v14;
412
413 _spu_st_start_tmp_voice_bit = _spu_st_start_voice_bit | _spu_st_start_prepare_voice_bit;
414 _spu_st_start_prepared_voice_bit = _spu_st_start_prepare_voice_bit;
415 _spu_st_start_prepare_tmp_voice_bit = _spu_st_start_prepare_voice_bit;
416 _spu_st_start_prepare_voice_bit = 0;
417 for ( v14 = 0; v14 < 24; v14 += 1 )
418 {
419 if ( ((_spu_st_start_voice_bit | v13) & (1 << v14)) != 0 )
420 break;
421 }
422 _spu_st_start_tmp_voice_current = v14;
423 }
424 }
425 _spu_st_stop_voice_bit = 0;
426 _spu_st_stat_int = 49;
427 _spu_t(3, _SpuStSetTransferEnv(_spu_st_start_tmp_voice_current)->data_addr, _spu_st_buf_sizeSBhalf);
428 }
429 else
430 {
431 unsigned int v12;
432
433 _spu_st_stat_int = 65;
434 v12 = SpuSetCore(_st_core);
435 SpuSetIRQ(SPU_ON);
436 SpuSetCore(v12);
437 }
438 FlushDcache();
439}
440
441static void _SpuStCB_Transfer(void)
442{
443 SpuStVoiceAttr *v0;
444 unsigned int v1;
445
446 FlushDcache();
447 _spu_st_start_tmp_voice_bit &= ~(1 << _spu_st_start_tmp_voice_current);
448 v0 = &_spu_st_Info.voice[_spu_st_start_tmp_voice_current];
449 if ( v0->status == 2 )
450 {
451 _SpuStSetMarkFINALrecover(_spu_st_start_tmp_voice_current);
452 v0->status = 6;
453 }
454 v1 = SpuSetCore(_st_core);
455 _spu_FsetRXX(6 * _spu_st_start_tmp_voice_current + 226, (v0->buf_addr >> 4) << 4, 1);
456 SpuSetCore(v1);
457 if ( _spu_st_start_tmp_voice_bit )
458 {
459 int v6;
460
461 for ( v6 = _spu_st_start_tmp_voice_current + 1; v6 < 24; v6 += 1 )
462 {
463 if ( (_spu_st_start_tmp_voice_bit & (1 << v6)) != 0 )
464 break;
465 }
466 _spu_st_start_tmp_voice_current = v6;
467 _spu_t(3, _SpuStSetTransferEnv(v6)->data_addr, _spu_st_buf_sizeSBhalf);
468 }
469 else
470 {
471 int v2;
472 unsigned int v3;
473 unsigned int v4;
474 unsigned int v5;
475
476 if ( !_spu_st_bufferP && _spu_st_cb_prepare_finished && _spu_st_start_prepare_tmp_voice_bit )
477 {
478 _spu_st_cb_prepare_finished(_spu_st_start_prepare_tmp_voice_bit, SPU_ST_PLAY);
479 _spu_st_start_prepare_tmp_voice_bit = 0;
480 }
481 if ( _spu_st_cb_transfer_finished && _spu_st_start_voice_bit )
482 _spu_st_cb_transfer_finished(_spu_st_start_voice_bit, SPU_ST_PLAY);
483 v2 = _spu_st_stop_voice_smallest;
484 if ( _spu_st_start_voice_smallest < 24 )
485 v2 = _spu_st_start_voice_smallest;
486 v3 = (_spu_st_Info.voice[v2].buf_addr >> 4) << 4;
487 _spu_st_addrIRQ = v3;
488 _spu_st_bufferP = _spu_st_bufferP != 1;
489 if ( _spu_st_bufferP != 1 )
490 _spu_st_addrIRQ = v3 + _spu_st_buf_sizeSBhalf;
491 v4 = SpuSetCore(_st_core);
492 SpuSetIRQAddr(_spu_st_addrIRQ);
493 SpuSetCore(v4);
494 v5 = SpuSetCore(_st_core);
495 SpuSetIRQ(SPU_ON);
496 SpuSetCore(v5);
497 _spu_st_stat_int = 64;
498 if ( _spu_st_start_voice_smallest < 24 )
499 _spu_st_stat_int = 50;
500 }
501 FlushDcache();
502}
503
504static int _SpuStStart(unsigned int voice_bit)
505{
506 FlushDcache();
507 if ( (_spu_st_stat_int & 0xF0) == 32 )
508 {
509 if ( _spu_st_stat_int == 34 )
510 {
511 int v3;
512 unsigned int v5;
513 const SpuStVoiceAttr *v6;
514 unsigned int v7;
515
516 _spu_st_stat_int = 48;
517 for ( v3 = 0; v3 < 24; v3 += 1 )
518 {
519 if ( (voice_bit & (1 << v3)) != 0 )
520 break;
521 }
522 v5 = SpuSetCore(_st_core);
523 SpuSetKey(SPU_ON, voice_bit);
524 SpuSetCore(v5);
525 if ( (_spu_env & 1) != 0 )
526 SpuFlush(SPU_EVENT_KEY);
527 _spu_st_start_voice_bit = voice_bit;
528 _spu_st_start_tmp_voice_bit = voice_bit;
529 _spu_st_stop_saved_voice_bit = 0;
530 _spu_st_stop_voice_bit = 0;
531 _spu_st_cb_transfer_saved = SpuSetTransferCallback(_SpuStCB_Transfer);
532 if ( _spu_st_Info.low_priority == SPU_ON )
533 _spu_FsetPCR(0);
534 _spu_st_cb_IRQ_saved = SpuSetIRQCallback(_SpuStCB_IRQ);
535 _spu_st_bufferP = 1;
536 _spu_st_start_tmp_voice_current = v3;
537 _spu_st_start_voice_smallest = v3;
538 v6 = _SpuStSetTransferEnv(v3);
539 v7 = SpuSetCore(_st_core);
540 SpuSetIRQ(SPU_OFF);
541 SpuSetCore(v7);
542 _spu_st_stat_int = 49;
543 _spu_t(3, v6->data_addr, _spu_st_buf_sizeSBhalf);
544 FlushDcache();
545 return SPU_ST_ACCEPT;
546 }
547 }
548 else
549 {
550 if ( (_spu_st_stat_int & 0xF0u) >= 0x21 )
551 {
552 if ( (_spu_st_stat_int & 0xF0) == 48 )
553 {
554 _spu_st_start_add_voice_bit = voice_bit;
555 _spu_st_start_add_lock = 0;
556 return SPU_ST_ACCEPT;
557 }
558 }
559 }
560 return SPU_ST_WRONG_STATUS;
561}
562
563int SpuStTransfer(int flag, unsigned int voice_bit)
564{
565 unsigned int v4;
566
567 if ( !_spu_st_stat_int )
568 return 0;
569 v4 = voice_bit & 0xFFFFFF;
570 if ( (voice_bit & 0xFFFFFF) == 0 )
571 {
572 return SPU_ST_INVALID_ARGUMENT;
573 }
574 if ( flag == SPU_ST_PREPARE )
575 {
576 return _SpuStStartPrepare(v4);
577 }
578 if ( flag >= SPU_ST_PREPARE && flag <= SPU_ST_PLAY )
579 {
580 return _SpuStStart(v4);
581 }
582 return SPU_ST_INVALID_ARGUMENT;
583}
584
585static void _SpuStReset(void)
586{
587 int v0;
588
589 _spu_st_cb_transfer_finished = 0;
590 _spu_st_cb_prepare_finished = 0;
591 _spu_st_cb_stream_finished = 0;
592 _spu_st_cb_transfer_saved = 0;
593 _spu_st_cb_IRQ_saved = 0;
594 _spu_st_start_voice_bit = 0;
595 _spu_st_start_tmp_voice_bit = 0;
596 _spu_st_start_add_voice_bit = 0;
597 _spu_st_start_prepare_voice_bit = 0;
598 _spu_st_start_prepare_tmp_voice_bit = 0;
599 _spu_st_start_prepared_voice_bit = 0;
600 _spu_st_stop_voice_bit = 0;
601 _spu_st_stop_saved_voice_bit = 0;
602 _spu_st_tmp_voice_bit = 0;
603 _spu_st_start_voice_smallest = 24;
604 _spu_st_start_tmp_voice_current = 24;
605 _spu_st_start_prepare_voice_current = 24;
606 _spu_st_start_prepare_voice_smallest = 24;
607 _spu_st_stop_voice_smallest = 24;
608 for ( v0 = 0; v0 < 24; v0 += 1 )
609 {
610 _spu_st_Info.voice[v0].status = 6;
611 _spu_st_Info.voice[v0].last_size = 0;
612 _spu_st_Info.voice[v0].buf_addr = 0;
613 _spu_st_Info.voice[v0].data_addr = 0;
614 }
615 _spu_st_Info.size = 0;
616 _spu_st_Info.low_priority = SPU_OFF;
617 _spu_st_buf_sizeSBhalf = 0;
618 _spu_st_bufferP = 0;
619 _spu_st_start_prepare_lock = 0;
620 _spu_st_start_add_lock = 0;
621}
622
623SpuStEnv *SpuStInit(int mode)
624{
625 (void)mode;
626
627 _spu_st_stat_int = 16;
628 _SpuStReset();
629 return &_spu_st_Info;
630}
631
632int SpuStQuit(void)
633{
634 if ( _spu_st_stat_int != 16 )
635 return SPU_ST_WRONG_STATUS;
636 _spu_st_stat_int = 0;
637 _SpuStReset();
638 return SPU_ST_ACCEPT;
639}
640
641int SpuStGetStatus(void)
642{
643 switch ( _spu_st_stat_int & 0xF0 )
644 {
645 case 0:
646 return SPU_ST_NOT_AVAILABLE;
647 case 16:
648 return SPU_ST_IDLE;
649 case 32:
650 return SPU_ST_PREPARE;
651 case 48:
652 return SPU_ST_TRANSFER;
653 case 64:
654 return SPU_ST_FINAL;
655 default:
656 return SPU_ST_WRONG_STATUS;
657 }
658}
659
660unsigned int SpuStGetVoiceStatus(void)
661{
662 return _spu_st_start_voice_bit;
663}
664
665SpuStCallbackProc SpuStSetPreparationFinishedCallback(SpuStCallbackProc func)
666{
667 SpuStCallbackProc result;
668
669 result = _spu_st_cb_prepare_finished;
670 if ( func != _spu_st_cb_prepare_finished )
671 _spu_st_cb_prepare_finished = func;
672 return result;
673}
674
675SpuStCallbackProc SpuStSetTransferFinishedCallback(SpuStCallbackProc func)
676{
677 SpuStCallbackProc result;
678
679 result = _spu_st_cb_transfer_finished;
680 if ( func != _spu_st_cb_transfer_finished )
681 _spu_st_cb_transfer_finished = func;
682 return result;
683}
684
685SpuStCallbackProc SpuStSetStreamFinishedCallback(SpuStCallbackProc func)
686{
687 SpuStCallbackProc result;
688
689 result = _spu_st_cb_stream_finished;
690 if ( func != _spu_st_cb_stream_finished )
691 _spu_st_cb_stream_finished = func;
692 return result;
693}
694
695unsigned int SpuStSetCore(unsigned int core)
696{
697 unsigned int result;
698
699 result = _st_core;
700 _st_core = core & 1;
701 return result;
702}