11#include "libspu2_internal.h"
13vu16 *_spu_RXX = (vu16 *)0xBF900000;
14u32 _spu_tsa[2] = {0u, 0u};
15u32 _spu_transMode = 0u;
16u32 _spu_inTransfer = 1u;
17SpuTransferCallbackProc _spu_transferCallback = NULL;
18SpuTransferCallbackProc _spu_AutoDMACallback = NULL;
19SpuIRQCallbackProc _spu_IRQCallback = NULL;
20static int g_DmaCoreIndex = 0;
21static int _spu_dma_mode = 0;
22static int _spu_transfer_startaddr = 0;
23static int _spu_transfer_time = 0;
28static int gBufferSize48;
32static void _spu_FsetDelayW(
int flag);
33static void _spu_FsetDelayR(
int flag);
35int _spu_init(
int flag)
41 *((vu32 *)0xBF8010F0) |= 0xB0000u;
42 v2 = &_spu_RXX[20 * _spu_core];
49 *((vu16 *)0xBF9007C0) = 0;
52 *((vu16 *)0xBF9007C0) = 0x8000;
55 for ( _spu_core = 0; (
unsigned int)_spu_core < 2; _spu_core += 1 )
65 _spu_tsa[_spu_core] = 0;
68 *(u16 *)((_spu_core << 10) + 0xbf9001b0) = 0;
70 _spu_RXX[512 * _spu_core + 205] = 0;
73 v7 = &_spu_RXX[512 * _spu_core];
75 v8 = &_spu_RXX[20 * _spu_core];
79 while ( (v7[418] & 0x7FF) != 0 )
83 printf(
"SPU:T/O [%s]\n",
"wait (reset)");
88 v11 = &_spu_RXX[20 * _spu_core];
89 v12 = &_spu_RXX[512 * _spu_core];
94 _spu_RXX[205] &= ~0x80u;
95 for ( v13 = 0; v13 < 10; v13 += 1 )
100 for ( _spu_core = 0; (
unsigned int)_spu_core < 2; _spu_core += 1 )
105 v17 = &_spu_RXX[512 * _spu_core];
110 v18 = &_spu_RXX[20 * _spu_core];
120 _spu_transferCallback = 0;
121 _spu_IRQCallback = 0;
125int spu_do_set_DmaCoreIndex(
int dma_core_index)
129 g_DmaCoreIndex = dma_core_index;
130 if ( dma_core_index )
132 _SpuDataCallback(_spu_FiAutoDMA);
137 _SpuDataCallback(_spu_FiDMA);
140 _SpuAutoDMACallback(v1);
141 return g_DmaCoreIndex;
144int spu_do_get_DmaCoreIndex(
void)
146 return g_DmaCoreIndex;
149static void _spu_FwriteByIO(
void *addr, u32 size)
151 _spu_RXX[725] = _spu_tsa[1];
152 _spu_RXX[724] = (_spu_tsa[1] >> 16) & 0xFFFF;
162 for ( i = 0; i < v6; i += 2 )
164 *((vu16 *)0xBF9001AC) = *(u16 *)((
char *)addr + 2 * i);
166 *((vu16 *)0xBF90019A) = (*((vu16 *)0xBF90019A) & ~0x30) | 0x10;
168 while ( (*((vu16 *)0xBF900344) & 0x400) != 0 )
172 printf(
"SPU:T/O [%s]\n",
"wait (SPU2_STATX_WRDY_M)");
179 *((vu16 *)0xBF90019A) &= ~0x30;
182int _spu_FiDMA(
void *userdata)
190 while ( (*((vu16 *)0xBF900744) & 0x80) != 0 )
192 if ( v1 > 0x1000000 )
194 printf(
"SPU:T/O [%s]\n",
"wait (SPU2_STATX_DREQ)");
199 _spu_RXX[717] &= ~0x30;
201 while ( (_spu_RXX[717] & 0x30) != 0 )
207 if ( _spu_transferCallback )
208 _spu_transferCallback();
210 gDMADeliverEvent = 1;
215int _spu_FiAutoDMA(
void *userdata)
220 if ( gMode != SPU_AUTODMA_ONESHOT )
222 gWhichBuff = 1 - gWhichBuff;
224 *((vu32 *)0xBF8010C0) = (u32)&gHostAddr[512 * (gBufferSize48 / 512)];
226 *((vu32 *)0xBF8010C0) = (u32)&gHostAddr[0];
232 v1 = (gBufferSize48 / 512) << 9;
233 v2 = (2 * gBufferSize48 - v1) >> 6;
234 if ( 2 * gBufferSize48 - v1 < 0 )
235 v2 = (2 * gBufferSize48 - v1 + 63) >> 6;
236 *((vu16 *)0xBF8010C6) = v2 + ((2 * gBufferSize48 - ((gBufferSize48 / 512) << 9)) % 64 > 0);
240 *((vu16 *)0xBF8010C6) = 8 * (gBufferSize48 / 512);
242 *((vu32 *)0xBF8010C8) = 0x1000201;
245 if ( (gMode & SPU_AUTODMA_LOOP) != 0 )
247 gWhichBuff = 1 - gWhichBuff;
249 *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C0) = (u32)&gHostAddr[512 * (gBufferSize48 / 512)];
251 *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C0) = (u32)gHostAddr;
253 *(u16 *)(1088 * g_DmaCoreIndex + 0xBF8010C6) = (2 * gBufferSize48 - ((gBufferSize48 / 512) << 9)) / 64
254 + ((2 * gBufferSize48 - ((gBufferSize48 / 512) << 9)) % 64 > 0);
256 *(u16 *)(1088 * g_DmaCoreIndex + 0xBF8010C6) = 8 * (gBufferSize48 / 512);
257 *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C8) = 0x1000201;
262 *((vu16 *)0xBF90019A) &= ~0x30;
263 *((vu16 *)0xBF900198) &= ~0xc0;
264 *((vu16 *)0xBF9001B0) = 0;
266 if ( _spu_AutoDMACallback )
267 _spu_AutoDMACallback();
272void _spu_Fr_(
void *data,
int addr, u32 size)
274 _spu_RXX[725] = addr;
275 _spu_RXX[724] = (addr >> 16) & 0xFFFF;
276 _spu_RXX[717] |= 0x30u;
278 *((vu32 *)0xBF8010C0) = (vu32)data;
279 *((vu32 *)0xBF8010C4) = (size << 16) | 0x10;
281 *((vu32 *)0xBF8010C8) = 16777728;
284int _spu_t(
int count, ...)
292 spu_tmp = va_arg(va, u32);
293 ck = va_arg(va, u32);
299 _spu_RXX[717] = _spu_RXX[717] | 0x30;
303 _spu_RXX[717] = (_spu_RXX[717] & ~0x30) | 0x20;
306 _spu_tsa[1] = spu_tmp;
307 _spu_RXX[725] = spu_tmp;
308 _spu_RXX[724] = (_spu_tsa[1] >> 16) & 0xFFFF;
311 if ( _spu_dma_mode == 1 )
315 _spu_transfer_startaddr = spu_tmp;
316 _spu_transfer_time = (ck >> 6) + ((ck & 0x3F) != 0);
317 ((vu32 *)0xBF8010C0)[272] = spu_tmp;
318 ((vu32 *)0xBF8010C4)[272] = (_spu_transfer_time << 16) | 0x10;
320 if ( _spu_dma_mode == 1 )
322 ((vu32 *)0xBF8010C8)[272] = v6;
330int _spu_Fw(
void *addr, u32 size)
332 if ( _spu_transMode )
334 _spu_FwriteByIO(addr, size);
338 _spu_t(2, _spu_tsa[1]);
340 _spu_t(3, addr, size);
345int _spu_StopAutoDMA(
void)
348 *((vu16 *)0xBF90019A) &= ~0x30;
354 if ( *((vu16 *)0xBF9001B0) )
355 v0 = *((vu32 *)0xBF8010C0);
356 *((vu32 *)0xBF8010C8) &= ~0x1000000u;
358 int do_set_dmacoreindex;
361 do_set_dmacoreindex = 0;
362 if ( (*((vu16 *)0xBF9007C0) & 4) != 0 )
364 do_set_dmacoreindex = 1;
365 *((vu16 *)0xBF9007C0) &= ~0xc0;
367 v2 = (u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0);
369 v0 = *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C0);
370 *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C8) &= ~0x1000000u;
374 *((vu16 *)0xBF900198) &= ~0xf0;
375 *((vu16 *)0xBF9001B0) = 0;
376 *((vu16 *)0xBF90076E) = 0;
377 *((vu16 *)0xBF90076C) = 0;
379 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF900198) &= ~0xf0;
381 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076E) = 0;
382 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076C) = *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076E);
383 if ( (*((vu16 *)0xBF9007C0) & 4) != 0 )
384 *((vu16 *)0xBF9007C0) &= ~0xc4;
385 if ( do_set_dmacoreindex )
386 spu_do_set_DmaCoreIndex(0);
391 return (gWhichBuff << 24) | (v0 & 0xFFFFFF);
395int _spu_AutoDMAGetStatus(
void)
401 if ( *((vu16 *)0xBF9001B0) )
402 v0 = *((vu32 *)0xBF8010C0);
404 if ( *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0) )
405 v0 = *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C0);
407 return (gWhichBuff << 24) | (v0 & 0xFFFFFF);
410unsigned int _spu_FwAutoDMA(u8 *addr,
unsigned int size,
int mode)
414 gBufferSize48 = size;
417 *((vu16 *)0xBF90019A) &= ~0x30;
418 *((vu16 *)0xBF9001A8) = 0;
419 *((vu16 *)0xBF9001AA) = 0;
420 *((vu16 *)0xBF9001B0) = 1;
421 *((vu32 *)0xBF8010C0) = (u32)addr;
422 *((vu32 *)0xBF8010C4) = 16;
423 *((vu16 *)0xBF8010C6) = 8 * ((int)size / 512);
424 *((vu32 *)0xBF8010C8) = 0x1000201;
425 *((vu16 *)0xBF900198) |= 0xC0u;
426 *((vu16 *)0xBF90076E) = 0x7FFF;
427 *((vu16 *)0xBF90076C) = 0x7FFF;
429 if ( (mode & (SPU_AUTODMA_BIT4 | SPU_AUTODMA_LOOP)) != 0 )
431 spu_do_set_DmaCoreIndex(1);
432 *((vu16 *)0xBF9007C0) |= 4u;
434 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90019A) &= ~0x30;
435 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001A8) = 0;
436 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001AA) = 0;
437 if ( g_DmaCoreIndex != 0 )
438 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0) = 2;
440 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0) = 1;
441 _spu_FsetDelayW(g_DmaCoreIndex);
442 *(u32 *)((1088 * g_DmaCoreIndex) + 0xBF8010C0) = (u32)addr;
443 *(u16 *)((1088 * g_DmaCoreIndex) + 0xBF8010C4) = 16;
444 *(u16 *)((1088 * g_DmaCoreIndex) + 0xBF8010C6) = 8 * ((int)size / 512);
445 if ( (mode & (SPU_AUTODMA_BIT4 | SPU_AUTODMA_LOOP)) != 0 )
447 *((vu16 *)0xBF9007C0) |= (mode & SPU_AUTODMA_BIT6) | (mode & SPU_AUTODMA_BIT7);
449 *(u32 *)((1088 * g_DmaCoreIndex) + 0xBF8010C8) = 0x1000201;
450 if ( (mode & SPU_AUTODMA_BIT4) == 0 )
452 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF900198) |= 0xC0u;
453 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076E) = 0x7FFF;
454 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076C) = 0x7FFF;
460unsigned int _spu_FwAutoDMAfrom(u8 *addr,
unsigned int size,
int mode, u8 *unk_a4)
473 gBufferSize48 = size;
475 v5 = size - (v4 - addr);
476 if ( (
unsigned int)(v4 - addr) >= size )
479 if ( mode != SPU_AUTODMA_LOOP )
481 if ( (mode & SPU_AUTODMA_LOOP) == 0 )
485 v5 = size - (v4 - addr - size);
489 v5 = (v5 / 1024 + 1) << 10;
490 v4 = &addr[gWhichBuff * size + size - v5];
493 *((vu16 *)0xBF90019A) &= ~0x30;
494 *((vu16 *)0xBF9001A8) = 0;
495 *((vu16 *)0xBF9001AA) = 0;
496 *((vu16 *)0xBF9001B0) = 1;
497 *((vu32 *)0xBF8010C0) = (u32)v4;
498 *((vu32 *)0xBF8010C4) = 16;
502 *((vu16 *)0xBF8010C6) = v7 + (v5 - (v7 << 6) > 0);
503 *((vu32 *)0xBF8010C8) = 0x1000201;
504 *((vu16 *)0xBF900198) |= 0xC0u;
505 *((vu16 *)0xBF90076E) = 0x7FFF;
506 *((vu16 *)0xBF90076C) = 0x7FFF;
508 if ( (mode & (SPU_AUTODMA_BIT4 | SPU_AUTODMA_LOOP)) != 0 )
510 spu_do_set_DmaCoreIndex(1);
511 *((vu16 *)0xBF9007C0) |= 4u;
513 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90019A) &= ~0x30;
514 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001A8) = 0;
515 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001AA) = 0;
516 if ( g_DmaCoreIndex != 0 )
517 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0) = 2;
519 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF9001B0) = 1;
520 *(u32 *)((1088 * g_DmaCoreIndex) + 0xBF8010C0) = (u32)v4;
521 *(u16 *)((1088 * g_DmaCoreIndex) + 0xBF8010C4) = 16;
522 *(u16 *)((1088 * g_DmaCoreIndex) + 0xBF8010C6) = v5 / 64 + (v5 % 64 > 0);
523 if ( (mode & (SPU_AUTODMA_BIT4 | SPU_AUTODMA_LOOP)) != 0 )
525 *((vu16 *)0xBF9007C0) |= (mode & SPU_AUTODMA_BIT6) | (mode & SPU_AUTODMA_BIT7);
527 *(u32 *)(1088 * g_DmaCoreIndex + 0xBF8010C8) = 0x1000201;
528 if ( (mode & SPU_AUTODMA_BIT4) == 0 )
530 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF900198) |= 0xC0u;
531 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076E) = 0x7FFF;
532 *(u16 *)((g_DmaCoreIndex << 10) + 0xBF90076C) = 0x7FFF;
538void _spu_Fr(
void *addr, u32 size)
540 _spu_t(2, _spu_tsa[1]);
542 _spu_t(3, addr, size);
545void _spu_MGFsetRXX2(
int offset,
int value)
551 v3 = &_spu_RXX[512 * _spu_core + offset];
552 *v3 = (v2 >> 16) & 0xFFFF;
556void _spu_FsetRXX(
int l, u32 addr,
int flag)
560 v3 = &_spu_RXX[512 * _spu_core + l];
573int _spu_FsetRXXa(
int l, u32 flag)
579 _spu_RXX[512 * _spu_core + l] = flag >> 1;
583int _spu_MGFgetRXX2(
int offset)
585 return 2 * (_spu_RXX[512 * _spu_core + 1 + offset] | (_spu_RXX[512 * _spu_core + offset] << 16));
588void _spu_FsetPCR(
int flag)
593static void _spu_FsetDelayW(
int flag)
595 ((vu32 *)0xBF801014)[256 * flag] = (((vu32 *)0xBF801014)[256 * flag] & ~0x2f000000) | 0x20000000;
598static void _spu_FsetDelayR(
int flag)
600 ((vu32 *)0xBF801014)[256 * flag] = (((vu32 *)0xBF801014)[256 * flag] & ~0x2f000000) | 0x22000000;
603void __attribute__((optimize(
"no-unroll-loops"))) _spu_Fw1ts(
void)
609 for ( i = 0; i < 60; i += 1 )
612 __asm__ __volatile__(
"" :
"+g"(v1) : :);
u32 count
start sector of fragmented bd/file