30u32 VoiceTransStatus[2];
31volatile u16 VoiceTransComplete[2];
32u32 VoiceTransIoMode[2];
36sceSdTransIntrHandler TransIntrHandlers[2];
37SdIntrCallback TransIntrCallbacks[2];
41sceSdSpu2IntrHandler Spu2IntrHandler;
42SdIntrCallback Spu2IrqCallback;
47volatile u16 *ParamRegList[] =
49 SD_VP_VOLL(0, 0), SD_VP_VOLR(0, 0), SD_VP_PITCH(0, 0), SD_VP_ADSR1(0, 0),
50 SD_VP_ADSR2(0, 0), SD_VP_ENVX(0, 0), SD_VP_VOLXL(0, 0), SD_VP_VOLXR(0, 0),
51 SD_P_MMIX(0), SD_P_MVOLL(0), SD_P_MVOLR(0), SD_P_EVOLL(0),
52 SD_P_EVOLR(0), SD_P_AVOLL(0), SD_P_AVOLR(0), SD_P_BVOLL(0),
53 SD_P_BVOLR(0), SD_P_MVOLXL(0), SD_P_MVOLXR(0), SD_S_PMON_HI(0),
54 SD_S_NON_HI(0), SD_A_KON_HI(0), SD_A_KON_HI(0), SD_S_ENDX_HI(0),
55 SD_S_VMIXL_HI(0), SD_S_VMIXEL_HI(0), SD_S_VMIXR_HI(0), SD_S_VMIXER_HI(0),
56 SD_A_ESA_HI(0), SD_A_EEA_HI(0), SD_A_TSA_HI(0), SD_CORE_IRQA(0),
57 SD_VA_SSA_HI(0, 0), SD_VA_LSAX(0, 0), SD_VA_NAX(0, 0), SD_CORE_ATTR(0),
58 SD_A_TSA_HI(0), SD_A_STD(0),
60 U16_REGISTER(0x1AE), U16_REGISTER(0x1B0),
66int TransInterrupt(
void *data)
72 dir = ((intr->mode & 0x200) < 1);
73 core = intr->mode & 0xFF;
76 if ((intr->mode & 0x100) == 0) {
80 volatile u16 *statx = U16_REGISTER(0x344 + (core * 1024));
82 while ((*statx & 0x80) == 0)
85 *SD_CORE_ATTR(core) &= ~SD_CORE_DMA;
87 while ((*SD_CORE_ATTR(core) & 0x30) != 0)
90 if (TransIntrHandlers[core])
92 if (TransIntrCallbacks[core])
95 VoiceTransComplete[core] = 1;
98 if (intr->mode & (SD_TRANS_LOOP << 8)) {
100 BlockTransBuff[core] = 1 - BlockTransBuff[core];
102 *SD_DMA_ADDR(core) = (BlockTransSize[core] * BlockTransBuff[core]) + BlockTransAddr[core];
103 *SD_DMA_SIZE(core) = (BlockTransSize[core] / 64) + ((BlockTransSize[core] & 63) > 0);
104 *SD_DMA_CHCR(core) = SD_DMA_START | SD_DMA_CS | dir;
107 *SD_CORE_ATTR(core) &= ~SD_CORE_DMA;
108 *SD_P_MMIX(core) &= 0xFF3F;
109 *U16_REGISTER(0x1B0 + (core * 1024)) = 0;
113 if (TransIntrHandlers[core]) {
117 TransIntrHandlers[core](core, intr->data);
119 if (TransIntrCallbacks[core]) {
123 TransIntrCallbacks[core](0);
128 if (dir == SD_DMA_DIR_SPU2IOP)
135int Spu2Interrupt(
void *data)
140 if (Spu2IntrHandler != NULL) {
141 volatile u16 *reg1 = U16_REGISTER(0x7C2);
143 Spu2IntrHandler((*reg1 & 0xC) >> 2, Spu2IntrData);
157 for (i = 0; i < 0x10000; i++)
158 asm volatile(
"nop\nnop\nnop\nnop\nnop");
164 *U32_REGISTER(0x1404) = 0xBF900000;
165 *U32_REGISTER(0x140C) = 0xBF900800;
166 *U32_REGISTER(0x10F0) |= 0x80000;
167 *U32_REGISTER(0x1570) |= 8;
168 *U32_REGISTER(0x1014) = 0x200B31E1;
169 *U32_REGISTER(0x1414) = 0x200B31E1;
173void RegisterInterrupts()
190 VoiceTransComplete[0] = 0;
191 VoiceTransComplete[1] = 0;
205 *SD_C_SPDIF_OUT = 0x8000;
208 *U32_REGISTER(0x10F0) |= 0xB0000;
210 for (core = 0; core < 2; core++) {
212 VoiceTransIoMode[core] = 0;
214 *U16_REGISTER(0x1B0) = 0;
215 *SD_CORE_ATTR(core) = 0;
217 *SD_CORE_ATTR(core) = SD_SPU2_ON;
219 *SD_P_MVOLL(core) = 0;
220 *SD_P_MVOLR(core) = 0;
222 statx = U16_REGISTER(0x344 + (core * 1024));
224 while (*statx & 0x7FF)
227 *SD_A_KOFF_HI(core) = 0xFFFF;
228 *SD_A_KOFF_LO(core) = 0xFFFF;
231 *SD_S_PMON_HI(1) = 0;
232 *SD_S_PMON_LO(1) = 0;
238u16 VoiceDataInit[16] = {0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707,
239 0, 0, 0, 0, 0, 0, 0, 0};
248 *SD_A_TSA_LO(0) = 0x5000 >> 1;
252 for (i = 0; i < 16; i++)
253 *SD_A_STD(0) = VoiceDataInit[i];
256 *SD_CORE_ATTR(0) = (*SD_CORE_ATTR(0) & ~SD_CORE_DMA) | SD_DMA_IO;
258 statx = U16_REGISTER(0x344);
261 while (*statx & SD_IO_IN_PROCESS)
265 *SD_CORE_ATTR(0) &= ~SD_CORE_DMA;
268 for (voice = 0; voice < 24; voice++) {
270 *SD_VP_VOLL(0, voice) = 0;
271 *SD_VP_VOLR(0, voice) = 0;
272 *SD_VP_PITCH(0, voice) = 0x3FFF;
273 *SD_VP_ADSR1(0, voice) = 0;
274 *SD_VP_ADSR2(0, voice) = 0;
277 *SD_VP_VOLL(1, voice) = 0;
278 *SD_VP_VOLR(1, voice) = 0;
279 *SD_VP_PITCH(1, voice) = 0x3FFF;
280 *SD_VP_ADSR1(1, voice) = 0;
281 *SD_VP_ADSR2(1, voice) = 0;
285 *SD_VA_SSA_HI(0, voice) = 0;
286 *SD_VA_SSA_LO(0, voice) = 0x5000 >> 1;
288 *SD_VA_SSA_HI(1, voice) = 0;
289 *SD_VA_SSA_LO(1, voice) = 0x5000 >> 1;
294 *SD_A_KON_HI(0) = 0xFFFF;
295 *SD_A_KON_LO(0) = 0xFF;
297 *SD_A_KON_HI(1) = 0xFFFF;
298 *SD_A_KON_LO(1) = 0xFF;
306 *SD_A_KOFF_HI(0) = 0xFFFF;
307 *SD_A_KOFF_LO(0) = 0xFF;
309 *SD_A_KOFF_HI(1) = 0xFFFF;
310 *SD_A_KOFF_LO(1) = 0xFF;
317 *SD_S_ENDX_HI(0) = 0;
318 *SD_S_ENDX_LO(0) = 0;
323void InitCoreVolume(s32 flag)
325 *SD_C_SPDIF_OUT = 0xC032;
328 *SD_CORE_ATTR(0) = SD_SPU2_ON | SD_ENABLE_EFFECTS | SD_MUTE;
329 *SD_CORE_ATTR(1) = SD_SPU2_ON | SD_ENABLE_EFFECTS | SD_MUTE | SD_ENABLE_EX_INPUT;
331 *SD_CORE_ATTR(0) = SD_SPU2_ON | SD_MUTE;
332 *SD_CORE_ATTR(1) = SD_SPU2_ON | SD_MUTE | SD_ENABLE_EX_INPUT;
337 *SD_S_VMIXL_HI(0) = 0xFFFF;
338 *SD_S_VMIXL_LO(0) = 0xFF;
339 *SD_S_VMIXR_HI(0) = 0xFFFF;
340 *SD_S_VMIXR_LO(0) = 0xFF;
341 *SD_S_VMIXEL_HI(0) = 0xFFFF;
342 *SD_S_VMIXEL_LO(0) = 0xFF;
343 *SD_S_VMIXER_HI(0) = 0xFFFF;
344 *SD_S_VMIXER_LO(0) = 0xFF;
347 *SD_S_VMIXL_HI(1) = 0xFFFF;
348 *SD_S_VMIXL_LO(1) = 0xFF;
349 *SD_S_VMIXR_HI(1) = 0xFFFF;
350 *SD_S_VMIXR_LO(1) = 0xFF;
351 *SD_S_VMIXEL_HI(1) = 0xFFFF;
352 *SD_S_VMIXEL_LO(1) = 0xFF;
353 *SD_S_VMIXER_HI(1) = 0xFFFF;
354 *SD_S_VMIXER_LO(1) = 0xFF;
357 *SD_P_MMIX(0) = 0xFF0;
358 *SD_P_MMIX(1) = 0xFFC;
381 *SD_A_EEA_HI(0) = 0xE;
383 *SD_A_EEA_HI(1) = 0xF;
391 *SD_P_AVOLL(1) = 0x7FFF;
392 *SD_P_AVOLR(1) = 0x7FFF;
404 *SD_C_SPDIF_MODE = 0x900;
405 *SD_C_SPDIF_MEDIA = 0x200;
406 *U16_REGISTER(0x7CA) = 8;
409int sceSdInit(
int flag)
418 RegisterInterrupts();
421 InitCoreVolume(flag);
433void SetSpdifMode(u16 val)
437 out = *SD_C_SPDIF_OUT;
438 mode = *SD_C_SPDIF_MODE;
443 out = (val & 0xFEF7) | 0x20;
447 out = (out & 0xFFD7) | 0x100;
453 out = (out & 0xFEDF) | 8;
464 switch (val & 0xF00) {
466 *SD_C_SPDIF_MEDIA = 0x200;
470 *SD_C_SPDIF_MEDIA = 0;
474 *SD_C_SPDIF_MEDIA = 0x200;
475 mode = (mode & 0xE7FF) | 0x800;
479 *SD_C_SPDIF_OUT = out;
480 *SD_C_SPDIF_MODE = mode;
488u8 CoreAttrShifts[4] = {7, 6, 14, 8};
490void sceSdSetCoreAttr(u16 entry, u16 val)
492 u16 core_attr = *SD_CORE_ATTR(entry & 1);
494 switch (entry & ~1) {
495 case SD_CORE_NOISE_CLK:
496 *SD_CORE_ATTR(entry & 1) = (core_attr - 0x3F01) | ((val & 0x3F) << 8);
500 case SD_CORE_SPDIF_MODE:
505 u32 core = entry & 1;
506 entry = (entry >> 1) - 1;
507 core_attr &= ~(1 << CoreAttrShifts[entry]);
508 core_attr |= (val & 1) << CoreAttrShifts[entry];
509 *SD_CORE_ATTR(core) = core_attr;
514void sceSdSetParam(u16 reg, u16 val)
528 offs = (40 * core) >> 1;
530 offs = (1024 * core) >> 1;
532 reg_index = (reg >> 8) & 0xFF;
533 voice = (reg & 0x3E) << 2;
534 reg_p = ParamRegList[reg_index] + offs + voice;
546 *SD_P_MVOLL(core) = val;
550 *SD_P_MVOLR(core) = val;
554 *SD_P_BVOLL(core) = val;
558 *SD_P_BVOLR(core) = val;
564SdIntrCallback sceSdSetTransCallback(s32 core, SdIntrCallback cb)
566 SdIntrCallback old_cb;
568 old_cb = TransIntrCallbacks[core & 1];
569 TransIntrCallbacks[core & 1] = cb;
582 if (*U16_REGISTER(0x1B0 + (core * 1024)) == 0)
585 retval = *SD_DMA_ADDR(core);
587 *SD_DMA_CHCR(core) &= ~SD_DMA_START;
588 *U16_REGISTER(0x1B0 + (core * 1024)) = 0;
590 retval = (BlockTransBuff[core] << 24) | (retval & 0xFFFFFF);
595void SetDmaWrite(s32 chan)
597 volatile u32 *reg = U32_REGISTER(0x1014 + (chan << 10));
598 *reg = (*reg & 0xF0FFFFFF) | 0x20000000;
601void SetDmaRead(s32 chan)
603 volatile u32 *reg = U32_REGISTER(0x1014 + (chan << 10));
604 *reg = (*reg & 0xF0FFFFFF) | 0x22000000;
609s32 BlockTransWriteFrom(u8 *iopaddr, u32 size, s32 chan, u16 mode, u8 *startaddr)
614 BlockTransBuff[core] = 0;
615 BlockTransSize[core] = size;
616 BlockTransAddr[core] = (u32)iopaddr;
621 offset = startaddr - iopaddr;
623 if ((u32)offset > size) {
624 if (mode & SD_TRANS_LOOP) {
626 BlockTransBuff[core] = 1;
635 iopaddr += (BlockTransSize[core] * BlockTransBuff[core]) + offset;
637 if (*SD_CORE_ATTR(core) & SD_DMA_IN_PROCESS)
639 if (*SD_DMA_CHCR(core) & SD_DMA_START)
643 *SD_CORE_ATTR(core) &= 0xFFCF;
645 *SD_A_TSA_HI(core) = 0;
646 *SD_A_TSA_LO(core) = 0;
648 *U16_REGISTER(0x1B0 + (core * 1024)) = 1 << core;
652 *SD_DMA_ADDR(core) = (u32)iopaddr;
653 *SD_DMA_MODE(core) = 0x10;
654 *SD_DMA_SIZE(core) = (size / 64) + ((size & 63) > 0);
655 *SD_DMA_CHCR(core) = SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_IOP2SPU;
661s32 BlockTransWrite(u8 *iopaddr, u32 size, s32 chan)
665 BlockTransBuff[core] = 0;
666 BlockTransSize[core] = size;
667 BlockTransAddr[core] = (u32)iopaddr;
669 if (*SD_CORE_ATTR(core) & SD_DMA_IN_PROCESS)
671 if (*SD_DMA_CHCR(core) & SD_DMA_START)
675 *SD_CORE_ATTR(core) &= 0xFFCF;
677 *SD_A_TSA_HI(core) = 0;
678 *SD_A_TSA_LO(core) = 0;
680 *U16_REGISTER(0x1B0 + (core * 1024)) = 1 << core;
684 *SD_DMA_ADDR(core) = (u32)iopaddr;
685 *SD_DMA_MODE(core) = 0x10;
686 *SD_DMA_SIZE(core) = (size / 64) + ((size & 63) > 0);
687 *SD_DMA_CHCR(core) = SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_IOP2SPU;
694s32 BlockTransRead(u8 *iopaddr, u32 size, s32 chan, s16 mode)
700 BlockTransBuff[core] = 0;
701 BlockTransSize[core] = size;
702 BlockTransAddr[core] = (u32)iopaddr;
704 if (*SD_CORE_ATTR(core) & SD_DMA_IN_PROCESS)
706 if (*SD_DMA_CHCR(core) & SD_DMA_START)
709 *SD_CORE_ATTR(core) &= 0xFFCF;
711 *SD_A_TSA_HI(core) = 0;
712 *SD_A_TSA_LO(core) = ((mode & 0xF00) << 1) + 0x400;
714 *U16_REGISTER(0x1AE + (core * 1024)) = (mode & 0xF000) >> 11;
721 *U16_REGISTER(0x1B0 + (core * 1024)) = 4;
725 *SD_DMA_ADDR(core) = (u32)iopaddr;
726 *SD_DMA_MODE(core) = 0x10;
727 *SD_DMA_SIZE(core) = (size / 64) + ((size & 63) > 0);
728 *SD_DMA_CHCR(core) = SD_DMA_CS | SD_DMA_START | SD_DMA_DIR_SPU2IOP;
736int sceSdBlockTrans(s16 chan, u16 mode, u8 *iopaddr, u32 size, ...)
739 int transfer_dir = mode & 3;
745 switch (transfer_dir) {
746 case SD_TRANS_WRITE: {
747 TransIntrData[core].mode = 0x100 | core;
749 if (mode & SD_TRANS_LOOP) {
750 TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
754 if (BlockTransWrite(iopaddr, _size, core) >= 0)
760 case SD_TRANS_READ: {
761 TransIntrData[core].mode = 0x300 | core;
763 if (mode & SD_TRANS_LOOP) {
764 TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
768 if (BlockTransRead(iopaddr, _size, chan, mode) >= 0)
773 case SD_TRANS_STOP: {
774 return DmaStop(core);
778 case SD_TRANS_WRITE_FROM: {
782 va_start(alist, size);
783 startaddr = va_arg(alist, u8 *);
786 TransIntrData[core].mode = 0x100 | core;
788 if (mode & SD_TRANS_LOOP) {
789 TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
793 if (BlockTransWriteFrom(iopaddr, _size, core, mode, startaddr) >= 0)
800 TransIntrData[core].mode = 0x100 | core;
801 TransIntrData[core].mode |= SD_TRANS_LOOP << 8;
804 if (BlockTransWrite(iopaddr, _size, core) >= 0)
811u32 sceSdBlockTransStatus(s16 chan, s16 flag)
819 if (*U16_REGISTER(0x1B0 + (chan * 1024)) == 0)
822 retval = *SD_DMA_ADDR(chan);
824 retval = (BlockTransBuff[chan] << 24) | (retval & 0xFFFFFF);
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
int ReleaseIntrHandler(int irq)
int DisableIntr(int irq, int *res)