mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
- RTI in analyzer - IROM mapped in DMEM - ARAM -> IRAM DMA size multiplied by 4 - OSInitAudioSystem stub reversing
108 lines
4.3 KiB
Text
108 lines
4.3 KiB
Text
// 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) // dsp interrupt mask (RW)
|
|
#define AIDCR_DSPINT (1 << 7) // dsp 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] = { // 128 bytes
|
|
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,
|
|
0x02FF, 0x02FF, 0x02FF, 0x02FF, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
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; // Actually 32 * 4 bytes
|
|
|
|
// 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; // Actually 32 * 4 bytes
|
|
|
|
// 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));
|
|
}
|