static bool try_fast_task_dispatching(struct hle_t* hle) { /* identify task ucode by its type */ switch (*dmem_u32(hle, TASK_TYPE)) { case 1: if (FORWARD_GFX) { forward_gfx_task(hle); return true; } break; case 2: if (FORWARD_AUDIO) { if (rsp_info.ProcessAlistList) rsp_info.ProcessAlistList(); return true; } if (try_fast_audio_dispatching(hle)) return true; break; case 7: if (rsp_info.ShowCFB) rsp_info.ShowCFB(); return true; } return false; }
static void show_cfb() { if (rspInfo.ShowCFB != NULL) { rspInfo.ShowCFB(); } }
static void forward_gfx_task(void) { if (rsp.ProcessDlistList != NULL) { rsp.ProcessDlistList(); *rsp.DPC_STATUS_REG &= ~DP_STATUS_FREEZE; } }
static void rsp_break(unsigned int setbits) { *rsp.SP_STATUS_REG |= setbits | RSP_STATUS_BROKE | RSP_STATUS_HALT; if ((*rsp.SP_STATUS_REG & RSP_STATUS_INTR_ON_BREAK)) { *rsp.MI_INTR_REG |= MI_INTR_SP; rsp.CheckInterrupts(); } }
static void rsp_break(struct hle_t* hle, unsigned int setbits) { *hle->sp_status |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT; if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK)) { *hle->mi_intr |= MI_INTR_SP; if (rsp_info.CheckInterrupts) rsp_info.CheckInterrupts(); } }
static void forward_audio_task() { if (rspInfo.ProcessAlistList != NULL) { printf("Fink\n"); rspInfo.ProcessAlistList(); } else printf("FANK\n"); }
__declspec(dllexport) DWORD DoRspCycles ( DWORD Cycles ) { OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0); unsigned int i, sum=0; #ifdef __WIN32__ if(firstTime) { firstTime=FALSE; if (SpecificHle) loadPlugin(); } #endif if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) { if (rsp.ProcessDlistList != NULL) { rsp.ProcessDlistList(); } *rsp.SP_STATUS_REG |= 0x0203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } *rsp.DPC_STATUS_REG &= ~0x0002; return Cycles; } else if (task->type == 2 && AudioHle) { #ifdef __WIN32__ if (SpecificHle) processAList(); else #endif if (rsp.ProcessAlistList != NULL) { rsp.ProcessAlistList(); } *rsp.SP_STATUS_REG |= 0x0203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } return Cycles; } else if (task->type == 7) { rsp.ShowCFB(); } *rsp.SP_STATUS_REG |= 0x203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } if (task->ucode_size <= 0x1000) for (i=0; i<(task->ucode_size/2); i++) sum += *(rsp.RDRAM + task->ucode + i); else for (i=0; i<(0x1000/2); i++) sum += *(rsp.IMEM + i); if (task->ucode_size > 0x1000) { switch(sum) { case 0x9E2: // banjo tooie (U) boot code { int i,j; memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); for (j=0; j<0xfc; j++) for (i=0; i<8; i++) *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); } return Cycles; break; case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code { int i,j; memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); for (j=0; j<0xfc; j++) for (i=0; i<8; i++) *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); } return Cycles; break; } } else { switch(task->type) { case 2: // audio if (audio_ucode(task) == 0) return Cycles; break; case 4: // jpeg switch(sum) { case 0x278: // used by zelda during boot *rsp.SP_STATUS_REG |= 0x200; return Cycles; break; case 0x2e4fc: // uncompress jpg_uncompress(task); return Cycles; break; default: { char s[1024]; sprintf(s, "unknown jpeg:\n\tsum:%x", sum); #ifdef __WIN32__ MessageBox(NULL, s, "unknown task", MB_OK); #else printf("%s\n", s); #endif } } break; } } { char s[1024]; FILE *f; sprintf(s, "unknown task:\n\ttype:%d\n\tsum:%x\n\tPC:%x", (int)task->type, sum, (int)rsp.SP_PC_REG); #ifdef __WIN32__ MessageBox(NULL, s, "unknown task", MB_OK); #else printf("%s\n", s); #endif if (task->ucode_size <= 0x1000) { f = fopen("imem.dat", "wb"); fwrite(rsp.RDRAM + task->ucode, task->ucode_size, 1, f); fclose(f); f = fopen("dmem.dat", "wb"); fwrite(rsp.RDRAM + task->ucode_data, task->ucode_data_size, 1, f); fclose(f); f = fopen("disasm.txt", "wb"); memcpy(rsp.DMEM, rsp.RDRAM+task->ucode_data, task->ucode_data_size); memcpy(rsp.IMEM+0x80, rsp.RDRAM+task->ucode, 0xF7F); disasm(f, (unsigned int*)(rsp.IMEM)); fclose(f); } else { f = fopen("imem.dat", "wb"); fwrite(rsp.IMEM, 0x1000, 1, f); fclose(f); f = fopen("dmem.dat", "wb"); fwrite(rsp.DMEM, 0x1000, 1, f); fclose(f); f = fopen("disasm.txt", "wb"); disasm(f, (unsigned int*)(rsp.IMEM)); fclose(f); } } return Cycles; }
static void forward_gfx_task(struct hle_t* hle) { if (rsp_info.ProcessDlistList) rsp_info.ProcessDlistList(); }
static void show_cfb(void) { if (rspInfo.ShowCFB) rspInfo.ShowCFB(); }
static void forward_audio_task(void) { if (rspInfo.ProcessAlistList) rspInfo.ProcessAlistList(); }
static void forward_gfx_task(struct hle_t* hle) { if (rsp_info.ProcessDlistList) rsp_info.ProcessDlistList(); *hle->dpc_status &= ~DP_STATUS_FREEZE; }
EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles) { OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0); unsigned int i, sum=0; if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) { if (rsp.ProcessDlistList != NULL) { rsp.ProcessDlistList(); } *rsp.SP_STATUS_REG |= 0x0203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } *rsp.DPC_STATUS_REG &= ~0x0002; return Cycles; } else if (task->type == 2 && AudioHle) { if (rsp.ProcessAlistList != NULL) { rsp.ProcessAlistList(); } *rsp.SP_STATUS_REG |= 0x0203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } return Cycles; } else if (task->type == 7) { rsp.ShowCFB(); } *rsp.SP_STATUS_REG |= 0x203; if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) { *rsp.MI_INTR_REG |= 0x1; rsp.CheckInterrupts(); } if (task->ucode_size <= 0x1000) for (i=0; i<(task->ucode_size/2); i++) sum += *(rsp.RDRAM + task->ucode + i); else for (i=0; i<(0x1000/2); i++) sum += *(rsp.IMEM + i); if (task->ucode_size > 0x1000) { switch(sum) { case 0x9E2: // banjo tooie (U) boot code { int i,j; memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); for (j=0; j<0xfc; j++) for (i=0; i<8; i++) *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); } return Cycles; break; case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code { int i,j; memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8); for (j=0; j<0xfc; j++) for (i=0; i<8; i++) *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8)); } return Cycles; break; } } else { switch(task->type) { case 2: // audio if (audio_ucode(task) == 0) return Cycles; break; case 4: // jpeg switch(sum) { case 0x278: // used by zelda during boot *rsp.SP_STATUS_REG |= 0x200; return Cycles; break; case 0x2e4fc: // uncompress jpg_uncompress(task); return Cycles; break; default: { DebugMessage(M64MSG_WARNING, "unknown jpeg task: sum:%x", sum); } } break; } } { FILE *f; DebugMessage(M64MSG_WARNING, "unknown task: type:%d sum:%x PC:%lx", (int)task->type, sum, (unsigned long) rsp.SP_PC_REG); if (task->ucode_size <= 0x1000) { f = fopen("imem.dat", "wb"); if (f == NULL || fwrite(rsp.RDRAM + task->ucode, 1, task->ucode_size, f) != task->ucode_size) DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); fclose(f); f = fopen("dmem.dat", "wb"); if (f == NULL || fwrite(rsp.RDRAM + task->ucode_data, 1, task->ucode_data_size, f) != task->ucode_data_size) DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); fclose(f); } else { f = fopen("imem.dat", "wb"); if (f == NULL || fwrite(rsp.IMEM, 1, 0x1000, f) != 0x1000) DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file imem.dat"); fclose(f); f = fopen("dmem.dat", "wb"); if (f == NULL || fwrite(rsp.DMEM, 1, 0x1000, f) != 0x1000) DebugMessage(M64MSG_WARNING, "couldn't write to RSP debugging file dmem.dat"); fclose(f); } } return Cycles; }
static void show_cfb(void) { if (rsp.ShowCFB != NULL) rsp.ShowCFB(); }
static void forward_audio_task(void) { if (rsp.ProcessAlistList != NULL) rsp.ProcessAlistList(); }