PS2SDK
PS2 Homebrew Libraries
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 
13 static unsigned int _st_core = 0u;
14 static int _spu_st_stat_int = 0;
15 static int _spu_st_start_voice_bit = 0;
16 static int _spu_st_start_tmp_voice_bit = 0;
17 static int _spu_st_start_add_voice_bit = 0;
18 static int _spu_st_start_prepare_voice_bit = 0;
19 static int _spu_st_start_prepare_tmp_voice_bit = 0;
20 static int _spu_st_start_prepared_voice_bit = 0;
21 static int _spu_st_stop_voice_bit = 0;
22 static int _spu_st_stop_saved_voice_bit = 0;
23 static int _spu_st_tmp_voice_bit = 0;
24 
25 static SpuStEnv _spu_st_Info;
26 static u32 _spu_st_buf_sizeSBhalf;
27 static int _spu_st_save_final_block[98];
28 static int _spu_st_start_prepare_voice_current;
29 static SpuTransferCallbackProc _spu_st_cb_transfer_saved;
30 static SpuStCallbackProc _spu_st_cb_prepare_finished;
31 static int _spu_st_start_prepare_lock;
32 static int _spu_st_bufferP;
33 static int _spu_st_start_voice_smallest;
34 static int _spu_st_stop_voice_smallest;
35 static SpuIRQCallbackProc _spu_st_cb_IRQ_saved;
36 static SpuStCallbackProc _spu_st_cb_stream_finished;
37 static unsigned int _spu_st_addrIRQ;
38 static int _spu_st_start_tmp_voice_current;
39 static int _spu_st_start_add_lock;
40 static SpuStCallbackProc _spu_st_cb_transfer_finished;
41 static int _spu_st_start_prepare_voice_smallest;
42 
43 static 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 
54 static 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 
65 static 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 
93 static 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 
110 static 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 
121 void _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 
157 static 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 
205 int 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 
216 static 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 
264 void _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 
283 static 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 
441 static 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 
504 static 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 
563 int 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 
585 static 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 
623 SpuStEnv *SpuStInit(int mode)
624 {
625  (void)mode;
626 
627  _spu_st_stat_int = 16;
628  _SpuStReset();
629  return &_spu_st_Info;
630 }
631 
632 int 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 
641 int 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 
660 unsigned int SpuStGetVoiceStatus(void)
661 {
662  return _spu_st_start_voice_bit;
663 }
664 
665 SpuStCallbackProc 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 
675 SpuStCallbackProc 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 
685 SpuStCallbackProc 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 
695 unsigned int SpuStSetCore(unsigned int core)
696 {
697  unsigned int result;
698 
699  result = _st_core;
700  _st_core = core & 1;
701  return result;
702 }
SpuStVoiceAttr_
Definition: libspu2.h:316
SpuStEnv_
Definition: libspu2.h:327