Esempio n. 1
0
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 */
Esempio n. 2
0
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 */