void CVif1::ExecuteCommand(StreamType& stream, CODE nCommand) { #ifdef _DEBUG DisassembleCommand(nCommand); #endif switch(nCommand.nCMD) { case 0x02: //OFFSET m_OFST = nCommand.nIMM; m_STAT.nDBF = 0; m_TOPS = m_BASE; break; case 0x03: //BASE m_BASE = nCommand.nIMM; break; case 0x06: //MSKPATH3 m_gif.SetPath3Masked((nCommand.nIMM & 0x8000) != 0); break; case 0x11: //FLUSH if(m_vpu.IsVuRunning()) { m_STAT.nVEW = 1; } else { m_STAT.nVEW = 0; } #ifdef DELAYED_MSCAL if(ResumeDelayedMicroProgram()) { m_STAT.nVEW = 1; return; } #endif break; case 0x13: //FLUSHA if(m_vpu.IsVuRunning()) { m_STAT.nVEW = 1; } else { m_STAT.nVEW = 0; } break; case 0x50: case 0x51: //DIRECT/DIRECTHL Cmd_DIRECT(stream, nCommand); break; default: CVif::ExecuteCommand(stream, nCommand); break; } }
void CVPU1::ExecuteCommand(StreamType& stream, CODE nCommand) { #ifdef _DEBUG DisassembleCommand(nCommand); #endif switch(nCommand.nCMD) { case 0x02: //OFFSET m_OFST = nCommand.nIMM; m_STAT.nDBF = 0; m_TOPS = m_BASE; break; case 0x03: //BASE m_BASE = nCommand.nIMM; break; case 0x06: //MSKPATH3 //Should mask bit somewhere... break; case 0x11: //FLUSH if(m_vif.IsVu1Running()) { m_STAT.nVEW = 1; } else { m_STAT.nVEW = 0; } #ifdef DELAYED_MSCAL if(ResumeDelayedMicroProgram()) { m_STAT.nVEW = 1; return; } #endif break; case 0x13: //FLUSHA if(m_vif.IsVu1Running()) { m_STAT.nVEW = 1; } else { m_STAT.nVEW = 0; } break; case 0x50: case 0x51: //DIRECT/DIRECTHL Cmd_DIRECT(stream, nCommand); break; default: CVPU::ExecuteCommand(stream, nCommand); break; } }
void CVPU::ProcessPacket(StreamType& stream) { while(stream.GetAvailableReadBytes()) { if(m_STAT.nVPS == 1) { //Command is waiting for more data... ExecuteCommand(stream, m_CODE); if((m_STAT.nVPS == 1) && (stream.GetAvailableReadBytes() != 0)) { //We have data in our FIFO but we still need more than what's available break; } else { continue; } } if(m_STAT.nVEW == 1) { if(IsRunning()) break; m_STAT.nVEW = 0; //Command is waiting for micro-program to end. ExecuteCommand(stream, m_CODE); continue; } #ifdef DELAYED_MSCAL m_previousCODE = m_CODE; #endif stream.Read(&m_CODE, sizeof(CODE)); assert(m_CODE.nI == 0); m_NUM = m_CODE.nNUM; ExecuteCommand(stream, m_CODE); } #ifdef DELAYED_MSCAL if(stream.GetAvailableReadBytes() == 0) { ResumeDelayedMicroProgram(); } #endif }
void CVPU::ExecuteCommand(StreamType& stream, CODE nCommand) { #ifdef _DEBUG if(m_vpuNumber == 0) { DisassembleCommand(nCommand); } #endif if(nCommand.nCMD >= 0x60) { #ifdef DELAYED_MSCAL //Check if previous cmd was MSCAL and if we have a pending MSCAL if(m_previousCODE.nCMD == 0x14) { uint32 prevImm = m_pendingMicroProgram / 8; if(ResumeDelayedMicroProgram()) { assert(m_previousCODE.nIMM == prevImm); m_previousCODE.nCMD = 0; //Set waiting for microprogram bit to make sure we come back here and execute UNPACK m_STAT.nVEW = 1; return; } } #endif Cmd_UNPACK(stream, nCommand, (nCommand.nIMM & 0x03FF)); return; } switch(nCommand.nCMD) { case 0: //NOP break; case 0x01: //STCYCL m_CYCLE <<= nCommand.nIMM; break; case 0x04: #ifdef DELAYED_MSCAL if(ResumeDelayedMicroProgram()) { m_STAT.nVEW = 1; return; } #endif m_ITOPS = nCommand.nIMM & 0x3FF; break; case 0x05: //STMOD m_MODE = nCommand.nIMM & 0x03; break; case 0x07: //MARK m_MARK = nCommand.nIMM; break; case 0x10: //FLUSHE if(IsVuRunning()) { m_STAT.nVEW = 1; } else { m_STAT.nVEW = 0; } break; case 0x14: //MSCAL #ifdef DELAYED_MSCAL if(ResumeDelayedMicroProgram()) { m_STAT.nVEW = 1; return; } StartDelayedMicroProgram(nCommand.nIMM * 8); #else StartMicroProgram(nCommand.nIMM * 8); #endif break; case 0x15: //MSCALF //TODO: Wait for GIF PATH 1 and 2 transfers to be over StartMicroProgram(nCommand.nIMM * 8); break; case 0x17: //MSCNT StartMicroProgram(m_ctx->m_State.nPC); break; case 0x20: //STMASK Cmd_STMASK(stream, nCommand); break; case 0x30: //STROW Cmd_STROW(stream, nCommand); break; case 0x31: //STCOL Cmd_STCOL(stream, nCommand); break; case 0x4A: //MPG Cmd_MPG(stream, nCommand); break; default: assert(0); break; } }