11#include "libspu2_internal.h"
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;
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;
43static void _SpuStSetMarkSTART(
int voice)
47 v1 = (u8 *)(_spu_st_Info.voice[voice].data_addr + 1);
50 v1[_spu_st_buf_sizeSBhalf - 16] = 2;
54static void _SpuStSetMarkEND(
int voice)
58 v1 = (u8 *)(_spu_st_Info.voice[voice].data_addr + 1);
61 v1[_spu_st_buf_sizeSBhalf - 16] = 3;
65static void _SpuStSetMarkFINAL(
int 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);
80 v2 = (
int *)((
char *)v2 + 1);
85 for ( v4 = 0; v4 < 14; v4 += 1 )
93static void _SpuStSetMarkFINALrecover(
int 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 )
105 v4[v3] = ((u8 *)v2)[v3];
114 v2 = &_spu_st_Info.voice[voice];
115 _spu_t(2, 8 * (v2->buf_addr >> 4));
116 _SpuStSetMarkSTART(voice);
121void _SpuStCBPrepare(
void)
125 v0 = _spu_st_start_prepare_voice_bit & ~(1 << _spu_st_start_prepare_voice_current);
126 _spu_st_start_prepare_voice_bit = v0;
131 for ( v1 = _spu_st_start_prepare_voice_current + 1; v1 < 24; v1 += 1 )
133 if ( (v0 & (1 << v1)) != 0 )
136 _spu_st_start_prepare_voice_current = v1;
139 _spu_t(3, _SpuStSetPrepareEnv(v1)->data_addr, _spu_st_buf_sizeSBhalf);
144 SpuSetTransferCallback(_spu_st_cb_transfer_saved);
145 if ( _spu_st_Info.low_priority == SPU_ON )
147 _spu_st_stat_int = 34;
148 if ( _spu_st_cb_prepare_finished )
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;
157static int _SpuStStartPrepare(
int voice_bit)
162 for ( v1 = 0; v1 < 24; v1 += 1 )
164 if ( (voice_bit & (1 << v1)) != 0 )
167 v3 = _spu_st_stat_int & 0xF0;
169 return SPU_ST_WRONG_STATUS;
170 if ( (_spu_st_stat_int & 0xF0u) >= 0x21 )
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;
185 unsigned int data_addr;
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 )
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;
202 return SPU_ST_WRONG_STATUS;
207 Kprintf(
"*********------------\n");
208 Kprintf(
"*********------------\n");
209 Kprintf(
"*********------------\n");
210 Kprintf(
"*********------------\n");
211 Kprintf(
"*********------------\n");
221 v2 = &_spu_st_Info.voice[voice];
222 v3 = (v2->buf_addr >> 4) << 4;
223 if ( _spu_st_bufferP )
225 v3 += _spu_st_buf_sizeSBhalf;
226 _SpuStSetMarkEND(voice);
230 _SpuStSetMarkSTART(voice);
233 if ( v2->status == 2 )
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 )
242 for ( v4 = 0; v4 < 24; v4 += 1 )
244 if ( (_spu_st_start_voice_bit & (1 << v4)) != 0 )
247 _spu_st_start_voice_smallest = v4;
251 _spu_st_start_voice_smallest = 24;
252 for ( v4 = 0; v4 < 24; v4 += 1 )
254 if ( (_spu_st_stop_voice_bit & (1 << v4)) != 0 )
257 _spu_st_stop_voice_smallest = v4;
264void _SpuStCB_IRQfinal(
void)
268 v0 = SpuSetCore(_st_core);
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 )
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;
283static void _SpuStCB_IRQ(
void)
292 v1 = SpuSetCore(_st_core);
296 if ( (_spu_st_stat_int & 0xF0) == 64 )
300 _spu_st_stat_int = v3;
301 if ( _spu_st_stop_voice_bit )
305 for ( v4 = 0; v4 < 24; v4 += 1 )
307 if ( (_spu_st_stop_voice_bit & (1 << v4)) != 0 )
313 last_size = _spu_st_Info.voice[v4].last_size;
315 v8 = ((_spu_st_Info.voice[v4].buf_addr >> 4) << 4) + last_size - 8;
318 v8 = ((_spu_st_Info.voice[v4].buf_addr >> 4) << 4) + last_size - 16;
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);
325 if ( v2 < last_size )
333 if ( !_spu_st_start_voice_bit )
348 SpuSetIRQCallback(_SpuStCB_IRQfinal);
350 v10 = ((_spu_st_Info.voice[v0].buf_addr >> 4) << 4) + v2 - 8;
353 v10 = ((_spu_st_Info.voice[v0].buf_addr >> 4) << 4) + v2 - 16;
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);
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 )
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 )
371 if ( _spu_st_start_add_voice_bit && _spu_st_start_prepared_voice_bit && !_spu_st_start_add_lock )
378 v16 = _spu_st_start_add_voice_bit & _spu_st_start_prepared_voice_bit;
379 v17 = SpuSetCore(_st_core);
380 SpuSetKey(SPU_ON, v16);
382 if ( (_spu_env & 1) != 0 )
386 v19 = SpuSetCore(_st_core);
387 SpuFlush(SPU_EVENT_KEY);
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 )
397 if ( (v20 & (1 << v18)) != 0 )
400 _spu_st_start_tmp_voice_current = v18;
401 _spu_st_start_voice_smallest = v18;
408 v13 = _spu_st_start_prepare_voice_bit;
409 if ( _spu_st_start_prepare_voice_bit && !_spu_st_start_prepare_lock )
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 )
419 if ( ((_spu_st_start_voice_bit | v13) & (1 << v14)) != 0 )
422 _spu_st_start_tmp_voice_current = v14;
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);
433 _spu_st_stat_int = 65;
434 v12 = SpuSetCore(_st_core);
441static void _SpuStCB_Transfer(
void)
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 )
451 _SpuStSetMarkFINALrecover(_spu_st_start_tmp_voice_current);
454 v1 = SpuSetCore(_st_core);
455 _spu_FsetRXX(6 * _spu_st_start_tmp_voice_current + 226, (v0->buf_addr >> 4) << 4, 1);
457 if ( _spu_st_start_tmp_voice_bit )
461 for ( v6 = _spu_st_start_tmp_voice_current + 1; v6 < 24; v6 += 1 )
463 if ( (_spu_st_start_tmp_voice_bit & (1 << v6)) != 0 )
466 _spu_st_start_tmp_voice_current = v6;
467 _spu_t(3, _SpuStSetTransferEnv(v6)->data_addr, _spu_st_buf_sizeSBhalf);
476 if ( !_spu_st_bufferP && _spu_st_cb_prepare_finished && _spu_st_start_prepare_tmp_voice_bit )
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;
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);
494 v5 = SpuSetCore(_st_core);
497 _spu_st_stat_int = 64;
498 if ( _spu_st_start_voice_smallest < 24 )
499 _spu_st_stat_int = 50;
504static int _SpuStStart(
unsigned int voice_bit)
507 if ( (_spu_st_stat_int & 0xF0) == 32 )
509 if ( _spu_st_stat_int == 34 )
516 _spu_st_stat_int = 48;
517 for ( v3 = 0; v3 < 24; v3 += 1 )
519 if ( (voice_bit & (1 << v3)) != 0 )
522 v5 = SpuSetCore(_st_core);
523 SpuSetKey(SPU_ON, voice_bit);
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 )
534 _spu_st_cb_IRQ_saved = SpuSetIRQCallback(_SpuStCB_IRQ);
536 _spu_st_start_tmp_voice_current = v3;
537 _spu_st_start_voice_smallest = v3;
538 v6 = _SpuStSetTransferEnv(v3);
539 v7 = SpuSetCore(_st_core);
542 _spu_st_stat_int = 49;
543 _spu_t(3, v6->data_addr, _spu_st_buf_sizeSBhalf);
545 return SPU_ST_ACCEPT;
550 if ( (_spu_st_stat_int & 0xF0u) >= 0x21 )
552 if ( (_spu_st_stat_int & 0xF0) == 48 )
554 _spu_st_start_add_voice_bit = voice_bit;
555 _spu_st_start_add_lock = 0;
556 return SPU_ST_ACCEPT;
560 return SPU_ST_WRONG_STATUS;
563int SpuStTransfer(
int flag,
unsigned int voice_bit)
567 if ( !_spu_st_stat_int )
569 v4 = voice_bit & 0xFFFFFF;
570 if ( (voice_bit & 0xFFFFFF) == 0 )
572 return SPU_ST_INVALID_ARGUMENT;
574 if ( flag == SPU_ST_PREPARE )
576 return _SpuStStartPrepare(v4);
578 if ( flag >= SPU_ST_PREPARE && flag <= SPU_ST_PLAY )
580 return _SpuStStart(v4);
582 return SPU_ST_INVALID_ARGUMENT;
585static void _SpuStReset(
void)
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 )
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;
615 _spu_st_Info.size = 0;
616 _spu_st_Info.low_priority = SPU_OFF;
617 _spu_st_buf_sizeSBhalf = 0;
619 _spu_st_start_prepare_lock = 0;
620 _spu_st_start_add_lock = 0;
627 _spu_st_stat_int = 16;
629 return &_spu_st_Info;
634 if ( _spu_st_stat_int != 16 )
635 return SPU_ST_WRONG_STATUS;
636 _spu_st_stat_int = 0;
638 return SPU_ST_ACCEPT;
641int SpuStGetStatus(
void)
643 switch ( _spu_st_stat_int & 0xF0 )
646 return SPU_ST_NOT_AVAILABLE;
650 return SPU_ST_PREPARE;
652 return SPU_ST_TRANSFER;
656 return SPU_ST_WRONG_STATUS;
660unsigned int SpuStGetVoiceStatus(
void)
662 return _spu_st_start_voice_bit;
665SpuStCallbackProc SpuStSetPreparationFinishedCallback(SpuStCallbackProc func)
667 SpuStCallbackProc result;
669 result = _spu_st_cb_prepare_finished;
670 if ( func != _spu_st_cb_prepare_finished )
671 _spu_st_cb_prepare_finished = func;
675SpuStCallbackProc SpuStSetTransferFinishedCallback(SpuStCallbackProc func)
677 SpuStCallbackProc result;
679 result = _spu_st_cb_transfer_finished;
680 if ( func != _spu_st_cb_transfer_finished )
681 _spu_st_cb_transfer_finished = func;
685SpuStCallbackProc SpuStSetStreamFinishedCallback(SpuStCallbackProc func)
687 SpuStCallbackProc result;
689 result = _spu_st_cb_stream_finished;
690 if ( func != _spu_st_cb_stream_finished )
691 _spu_st_cb_stream_finished = func;
695unsigned int SpuStSetCore(
unsigned int core)