EXPORT void CALL DllConfig(p_void hParent) { system("sp_cfgui"); update_conf(CFG_FILE); if (DMEM == IMEM || GET_RCP_REG(SP_PC_REG) % 4096 == 0x00000000) return; export_SP_memory(); hParent = NULL; if (hParent == NULL) return; /* -Wunused-but-set-parameter */ return; }
EXPORT unsigned int CALL DoRspCycles(unsigned int cycles) { static char task_debug[] = "unknown task type: 0x????????"; char* task_debug_type; OSTask_type task_type; register unsigned int i; if (GET_RCP_REG(SP_STATUS_REG) & 0x00000003) { message("SP_STATUS_HALT"); return 0x00000000; } task_debug_type = &task_debug[strlen("unknown task type: 0x")]; #ifdef USE_CLIENT_ENDIAN memcpy(&task_type, DMEM + 0xFC0, 4); #else task_type = 0x00000000 | (u32)(DMEM[0xFC0 ^ 0] & 0xFFu) << 24 | (u32)(DMEM[0xFC1 ^ 0] & 0xFFu) << 16 | (u32)(DMEM[0xFC2 ^ 0] & 0xFFu) << 8 | (u32)(DMEM[0xFC3 ^ 0] & 0xFFu) << 0 ; #endif switch (task_type) { case M_GFXTASK: if (CFG_HLE_GFX == 0) break; if (*(pi32)(DMEM + 0xFF0) == 0x00000000) break; /* Resident Evil 2, null task pointers */ GET_RCP_REG(SP_STATUS_REG) |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT ; #if defined(M64P_PLUGIN_API) if (GET_RSP_INFO(ProcessDlistList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessDlistList)(); #else if (GET_RSP_INFO(ProcessDList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessDList)(); #endif if ((GET_RCP_REG(SP_STATUS_REG) & SP_STATUS_INTR_BREAK) && (GET_RCP_REG(SP_STATUS_REG) & (SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT))) { GET_RCP_REG(MI_INTR_REG) |= 0x00000001; GET_RSP_INFO(CheckInterrupts)(); } GET_RCP_REG(DPC_STATUS_REG) &= ~0x00000002ul; /* DPC_STATUS_FREEZE */ return 0; case M_AUDTASK: if (CFG_HLE_AUD == 0) break; #if defined(M64P_PLUGIN_API) if (GET_RSP_INFO(ProcessAlistList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessAlistList)(); #else if (GET_RSP_INFO(ProcessAList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessAList)(); #endif GET_RCP_REG(SP_STATUS_REG) |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT ; if (GET_RCP_REG(SP_STATUS_REG) & SP_STATUS_INTR_BREAK) { GET_RCP_REG(MI_INTR_REG) |= 0x00000001; GET_RSP_INFO(CheckInterrupts)(); } return 0; case M_VIDTASK: message("M_VIDTASK"); break; case M_NJPEGTASK: break; /* Zelda, Pokemon, others */ case M_NULTASK: message("M_NULTASK"); break; case M_HVQTASK: message("M_HVQTASK"); break; case M_HVQMTASK: if (GET_RSP_INFO(ShowCFB) == NULL) /* Gfx #1.2 or older specs */ break; GET_RSP_INFO(ShowCFB)(); /* forced FB refresh in case gfx plugin skip */ break; default: if (task_type == 0x8BC43B5D) break; /* CIC boot code sent to the RSP */ sprintf(task_debug_type, "%08lX", (unsigned long)task_type); message(task_debug); } #ifdef WAIT_FOR_CPU_HOST for (i = 0; i < NUMBER_OF_SCALAR_REGISTERS; i++) MFC0_count[i] = 0; #endif run_task(); /* * An optional EMMS when compiling with Intel SIMD or MMX support. * * Whether or not MMX has been executed in this emulator, here is a good time * to finally empty the MM state, at the end of a long interpreter loop. */ #ifdef ARCH_MIN_SSE2 _mm_empty(); #endif if (*CR[0x4] & SP_STATUS_BROKE) /* normal exit, from executing BREAK */ return (cycles); else if (GET_RCP_REG(MI_INTR_REG) & 1) /* interrupt set by MTC0 to break */ GET_RSP_INFO(CheckInterrupts)(); else if (*CR[0x7] != 0x00000000) /* semaphore lock fixes */ {} #ifdef WAIT_FOR_CPU_HOST else MF_SP_STATUS_TIMEOUT = 16; /* From now on, wait 16 times, not 32767. */ #else else { /* ??? unknown, possibly external intervention from CPU memory map */
EXPORT unsigned int CALL DoRspCycles(unsigned int cycles) { OSTask_type task_type; register unsigned int i; if (GET_RCP_REG(SP_STATUS_REG) & 0x00000003) { message("SP_STATUS_HALT"); return 0x00000000; } task_type = 0x00000000 #ifdef USE_CLIENT_ENDIAN | *((pi32)(DMEM + 0x000FC0U)) #else | (u32)DMEM[0xFC0] << 24 | (u32)DMEM[0xFC1] << 16 | (u32)DMEM[0xFC2] << 8 | (u32)DMEM[0xFC3] << 0 #endif ; switch (task_type) { #ifdef EXTERN_COMMAND_LIST_GBI case M_GFXTASK: if (CFG_HLE_GFX == 0) break; if (*(pi32)(DMEM + 0xFF0) == 0x00000000) break; /* Resident Evil 2, null task pointers */ GET_RCP_REG(SP_STATUS_REG) |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT ; if (GET_RSP_INFO(ProcessDlistList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessDlistList)(); if ((GET_RCP_REG(SP_STATUS_REG) & SP_STATUS_INTR_BREAK) && (GET_RCP_REG(SP_STATUS_REG) & (SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT))) { GET_RCP_REG(MI_INTR_REG) |= 0x00000001; GET_RSP_INFO(CheckInterrupts)(); } GET_RCP_REG(DPC_STATUS_REG) &= ~0x00000002ul; /* DPC_STATUS_FREEZE */ return 0; #endif #ifdef EXTERN_COMMAND_LIST_ABI case M_AUDTASK: if (CFG_HLE_AUD == 0) break; if (GET_RSP_INFO(ProcessAlistList) == NULL) { /* branch */ } else GET_RSP_INFO(ProcessAlistList)(); GET_RCP_REG(SP_STATUS_REG) |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT ; if (GET_RCP_REG(SP_STATUS_REG) & SP_STATUS_INTR_BREAK) { GET_RCP_REG(MI_INTR_REG) |= 0x00000001; GET_RSP_INFO(CheckInterrupts)(); } return 0; #endif case M_VIDTASK: message("M_VIDTASK"); break; case M_NJPEGTASK: break; /* Zelda, Pokemon, others */ case M_NULTASK: message("M_NULTASK"); break; case M_HVQTASK: message("M_HVQTASK"); break; case M_HVQMTASK: if (GET_RSP_INFO(ShowCFB) == NULL) /* Gfx #1.2 or older specs */ break; GET_RSP_INFO(ShowCFB)(); /* forced FB refresh in case gfx plugin skip */ break; } #ifdef WAIT_FOR_CPU_HOST for (i = 0; i < 32; i++) MFC0_count[i] = 0; #endif run_task(); /* * An optional EMMS when compiling with Intel SIMD or MMX support. * * Whether or not MMX has been executed in this emulator, here is a good time * to finally empty the MM state, at the end of a long interpreter loop. */ #ifdef ARCH_MIN_SSE2 _mm_empty(); #endif if (*CR[0x4] & SP_STATUS_BROKE) /* normal exit, from executing BREAK */ return (cycles); else if (GET_RCP_REG(MI_INTR_REG) & 1) /* interrupt set by MTC0 to break */ GET_RSP_INFO(CheckInterrupts)(); else if (*CR[0x7] != 0x00000000) /* semaphore lock fixes */ {} #ifdef WAIT_FOR_CPU_HOST else MF_SP_STATUS_TIMEOUT = 16; /* From now on, wait 16 times, not 32767. */ #else else { /* ??? unknown, possibly external intervention from CPU memory map */