// DSP mailbox registers #define DSP_OUTMBOXH *(volatile u16 *)(0xCC005000) #define DSP_OUTMBOXL *(volatile u16 *)(0xCC005002) #define DSP_INMBOXH *(volatile u16 *)(0xCC005004) #define DSP_INMBOXL *(volatile u16 *)(0xCC005006) // known ARAM controller registers #define AR_SIZE (*(volatile u16 *)(0xCC005012)) // 16 bit regs #define AR_MODE (*(volatile u16 *)(0xCC005016)) #define AR_REFRESH (*(volatile u16 *)(0xCC00501A)) #define AR_DMA_MMADDR_H (*(volatile u16 *)(0xCC005020)) #define AR_DMA_MMADDR_L (*(volatile u16 *)(0xCC005022)) #define AR_DMA_ARADDR_H (*(volatile u16 *)(0xCC005024)) #define AR_DMA_ARADDR_L (*(volatile u16 *)(0xCC005026)) #define AR_DMA_CNT_H (*(volatile u16 *)(0xCC005028)) #define AR_DMA_CNT_L (*(volatile u16 *)(0xCC00502A)) #define AR_DMA_MMADDR (*(volatile u16 *)(0xCC005020)) // 32 bit regs #define AR_DMA_ARADDR (*(volatile u16 *)(0xCC005024)) #define AR_DMA_CNT (*(volatile u16 *)(0xCC005028)) // DSP interface main control register #define AIDCR (*(volatile u16 *)(0xCC00500A)) // AIDCR bits (bits 10 and 11 are unknown) #define AIDCR_DSPDMA (1 << 9) // dsp task dma in progress, if set #define AIDCR_DSPINTMSK (1 << 8) // * interrupt mask (RW) #define AIDCR_DSPINT (1 << 7) // * interrupt active (RWC) #define AIDCR_ARINTMSK (1 << 6) #define AIDCR_ARINT (1 << 5) #define AIDCR_AIINTMSK (1 << 4) #define AIDCR_AIINT (1 << 3) #define AIDCR_HALT (1 << 2) // halt DSP #define AIDCR_PIINT (1 << 1) // assert DSP PI interrupt #define AIDCR_RES (1 << 0) // reset DSP static u16 DSPInitCode[0x40] = { 0x029F, 0x0010, 0x029F, 0x0033, 0x029F, 0x0034, 0x029F, 0x0035, 0x029F, 0x0036, 0x029F, 0x0037, 0x029F, 0x0038, 0x029F, 0x0039, 0x1206, 0x1203, 0x1204, 0x1205, 0x0080, 0x8000, 0x0088, 0xFFFF, 0x0084, 0x1000, 0x0064, 0x001D, 0x0218, 0x0000, 0x8100, 0x1C1E, 0x0044, 0x1B1E, 0x0084, 0x0800, 0x0064, 0x0027, 0x191E, 0x0000, 0x00DE, 0xFFFC, 0x02A0, 0x8000, 0x029C, 0x0028, 0x16FC, 0x0054, 0x16FD, 0x4348, 0x0021, 0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x02FF }; // --------------------------------------------------------------------------- void __OSInitAudioSystem() { // copy DSP init ucode to 32B aligned memory area // save used region below of arenaHi memcpy(OSGetArenaHi() - 128, 0x81000000, sizeof(DSPInitCode)); memcpy(0x81000000, DSPInitCode, sizeof(DSPInitCode)); DCFlushRange(0x81000000, sizeof(DSPInitCode)); AR_SIZE = 0x0043; AIDCR = 0x0800 | AIDCR_DSPINT | AIDCR_ARINT | AIDCR_AIINT | AIDCR_HALT; // reset DSP and wait AIDCR |= AIDCR_RES; while(AIDCR & AIDCR_RES); // write 0 and wait mail delivery DSP_OUTMBOXH = 0; while(((DSP_INMBOXH << 16) | DSP_INMBOXL) & 0x80000000); // send DSP initialization ucode to ARAM at offset 0 AR_DMA_MMADDR = OSCachedToPhysical(0x81000000); AR_DMA_ARADDR = 0; AR_DMA_CNT = 32; // wait DMA complete u16 old = AIDCR; // keep AIDCR_DSPDMA while(AIDCR & AIDCR_DSPDMA); AIDCR = old; // clear DMA status // wait a little OSTick old = OSGetTick(); while((OSGetTick() - old) < 2194); // send DSP initialization ucode to ARAM at offset 0 (again) AR_DMA_MMADDR = OSCachedToPhysical(0x81000000); AR_DMA_ARADDR = 0; AR_DMA_CNT = 32; // wait DMA complete u16 old = AIDCR; // keep AIDCR_DSPDMA while(AIDCR & AIDCR_DSPDMA); AIDCR = old; // clear DMA status AIDCR &= ~0x0800 while(AIDCR & 0x0400); AIDCR &= ~AIDCR_HALT; while((DSP_INMBOXH & 0x8000) == 0); u16 dummy = DSP_INMBOXL; // read nowhere AIDCR |= AIDCR_HALT; AIDCR = 0x0800 | AIDCR_DSPINT | AIDCR_ARINT | AIDCR_AIINT | AIDCR_HALT; // reset DSP and wait AIDCR |= AIDCR_RES; while(AIDCR & AIDCR_RES); // restore saved region memcpy(0x81000000, OSGetArenaHi() - 128, sizeof(DSPInitCode)); }