mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
229 lines
4.2 KiB
Text
229 lines
4.2 KiB
Text
// dsp.c
|
|
|
|
//
|
|
// low-level DSP mail delivery
|
|
//
|
|
|
|
u32 DSPCheckMailToDSP(void)
|
|
{
|
|
return ( *(u16 *)0xCC005000 & 0x8000 );
|
|
}
|
|
|
|
u32 DSPCheckMailFromDSP(void)
|
|
{
|
|
return ( *(u16 *)0xCC005004 & 0x8000 );
|
|
}
|
|
|
|
u32 DSPReadCPUToDSPMbox(void)
|
|
{
|
|
return ( (*(u16 *)0xCC005000 << 16) | *(u16 *)0xCC005002 );
|
|
}
|
|
|
|
u32 DSPReadMailFromDSP(void)
|
|
{
|
|
return ( (*(u16 *)0xCC005004 << 16) | *(u16 *)0xCC005006 );
|
|
}
|
|
|
|
void DSPSendMailToDSP(u32 mail)
|
|
{
|
|
*(u16 *)0xCC005000 = mail >> 16;
|
|
*(u16 *)0xCC005002 = (u16)mail;
|
|
}
|
|
|
|
//
|
|
// assert DSP interrupt
|
|
//
|
|
|
|
void DSPAssertInt(void)
|
|
{
|
|
u16 old, tmp;
|
|
BOOL lvl = OSDisableInterrupts();
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00A8;
|
|
tmp |= 0x0002;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
}
|
|
|
|
//
|
|
// DSP management
|
|
//
|
|
|
|
BOOL __DSP_init_flag;
|
|
|
|
void DSPInit(void)
|
|
{
|
|
__DSP_debug_printf("DSPInit(): Build Date: %s %s\n", __DATE__, __TIME__);
|
|
|
|
if(__DSP_init_flag == FALSE)
|
|
{
|
|
u16 old, tmp;
|
|
BOOL lvl = OSDisableInterrupts();
|
|
|
|
__OSSetInterruptHandler(__OS_INTERRUPT_DSP_DSP, __DSPHandler);
|
|
__OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP);
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00A8;
|
|
tmp |= 0x0800;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00AC;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
__DSP_tmp_task =
|
|
__DSP_curr_task =
|
|
__DSP_last_task =
|
|
__DSP_first_task = NULL;
|
|
|
|
__DSP_init_flag = TRUE;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
}
|
|
}
|
|
|
|
BOOL DSPCheckInit(void)
|
|
{
|
|
return __DSP_init_flag;
|
|
}
|
|
|
|
void DSPReset(void)
|
|
{
|
|
u16 old, tmp;
|
|
BOOL lvl = OSDisableInterrupts();
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00A8;
|
|
tmp |= 0x0800;
|
|
tmp |= 0x0001;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
__DSP_init_flag = FALSE;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
}
|
|
|
|
void DSPHalt(void)
|
|
{
|
|
u16 old, tmp;
|
|
BOOL lvl = OSDisableInterrupts();
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00A8;
|
|
tmp |= 0x0004;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
}
|
|
|
|
void DSPUnhalt(void)
|
|
{
|
|
u16 old, tmp;
|
|
BOOL lvl = OSDisableInterrupts();
|
|
|
|
old = *(u16 *)0xCC00500A;
|
|
tmp = old & ~0x00AC;
|
|
*(u16 *)0xCC00500A = tmp;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
}
|
|
|
|
u32 DSPGetDMAStatus(void)
|
|
{
|
|
return ( *(u16 *)0xCC00500A & 0x0200 );
|
|
}
|
|
|
|
//
|
|
// DSP task control
|
|
//
|
|
|
|
DSPTaskInfo *DSPAddTask(DSPTaskInfo *task)
|
|
{
|
|
BOOL lvl;
|
|
|
|
if(__DSP_init_flag == FALSE)
|
|
{
|
|
OSHalt("DSPAddTask(): DSP driver not initialized!\n");
|
|
}
|
|
|
|
lvl = OSDisableInterrupts();
|
|
|
|
__DSP_insert_task(task);
|
|
|
|
state->state = DSP_TASK_STATE_INIT;
|
|
state->flags = DSP_TASK_FLAG_ATTACHED;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
|
|
if(task == __DSP_first_task)
|
|
{
|
|
__DSP_boot_task(task);
|
|
}
|
|
|
|
return task;
|
|
}
|
|
|
|
DSPTaskInfo *DSPCancelTask(DSPTaskInfo *task)
|
|
{
|
|
BOOL lvl;
|
|
|
|
if(__DSP_init_flag == FALSE)
|
|
{
|
|
OSHalt("DSPCancelTask(): DSP driver not initialized!\n");
|
|
}
|
|
|
|
lvl = OSDisableInterrupts();
|
|
|
|
task->flags |= DSP_TASK_FLAG_CANCEL;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
return task;
|
|
}
|
|
|
|
DSPTaskInfo *DSPAssertTask(DSPTaskInfo *task)
|
|
{
|
|
BOOL lvl;
|
|
|
|
if(__DSP_init_flag == FALSE)
|
|
{
|
|
OSHalt("DSPAssertTask(): DSP driver not initialized!\n");
|
|
}
|
|
|
|
if((task->flags & DSP_TASK_FLAG_ATTACHED) == 0)
|
|
{
|
|
OSHalt("DSPAssertTask(): Specified task not in active task list!\n");
|
|
}
|
|
|
|
lvl = OSDisableInterrupts();
|
|
|
|
if(task == __DSP_curr_task)
|
|
{
|
|
__DSP_rude_task = task;
|
|
__DSP_rude_task_pending = TRUE;
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
return task;
|
|
}
|
|
else
|
|
{
|
|
if(DSPGetTaskPriority(task) < DSPGetTaskPriority(__DSP_curr_task))
|
|
{
|
|
__DSP_rude_task = task;
|
|
__DSP_rude_task_pending = TRUE;
|
|
|
|
if(DSPGetTaskState(__DSP_curr_task) == DSP_TASK_STATE_RUN)
|
|
{
|
|
DSPAssertInt();
|
|
}
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
return task
|
|
}
|
|
}
|
|
|
|
OSRestoreInterrupts(lvl);
|
|
return NULL;
|
|
}
|