📄 processor.cc
字号:
case Instruction::JUMPVTS_TT: if (targetPosition.enterVTSTitle(instruction->operand2.getTTN())) { scheduler.addStartPGC(targetPosition); } else { scheduler.addFirstPlayPGC(); } break; case Instruction::JUMPVTS_PTT: if (targetPosition.enterVTSTitle(instruction->operand2.getTTN(), instruction->operand1.getPTTN())) { scheduler.addStartPGC(targetPosition); } else { scheduler.addFirstPlayPGC(); } break; case Instruction::JUMPSS: executeJumpSS(instruction); break; case Instruction::CALLSS: executeCallSS(instruction); break; default: Log::error("dvd::vm::Processor::executeJumpCall: invalid jump/call command: %u\n", (unsigned)instruction->getJumpCallCmd()); scheduler.addFirstPlayPGC(); break; case Instruction::NOP: --numberOfBranches; scheduler.addStep(); break; }}//------------------------------------------------------------------------------void Processor::executeJumpCallSS(const Instruction* instruction, bool isJump){ bool failed = false; TargetPosition targetPosition(state.getPosition()); switch(instruction->operand2.getJumpCallType()) { case Operand2::FP: scheduler.addFirstPlayPGC(); break; case Operand2::VMGM_MENU: if (targetPosition.enterVMGMenu(instruction->operand2.getMenu())) { scheduler.addStartPGC(targetPosition); } else { scheduler.addFirstPlayPGC(); } break; case Operand2::VTSM: if (isJump) { if (instruction->operand2.getVTS()>0) { if (!targetPosition.enterVTS(instruction->operand2.getVTS(), instruction->operand1.getTTN())) { failed = true; } } else { if (!targetPosition.enterVTSTitle(instruction->operand1.getTTN())) { failed = true; } } } if (!failed && targetPosition.enterMenu(instruction->operand2.getMenu())) { scheduler.addStartPGC(targetPosition); } else { scheduler.addFirstPlayPGC(); } break; case Operand2::VMGM_PGCN: if (targetPosition.enterVMGPGC(instruction->operand1.getPGCN())) { scheduler.addStartPGC(targetPosition); } else { scheduler.addFirstPlayPGC(); } break; default: Log::error("dvd::vm::Processor::executeJumpCallSS: invalid jump/call type: %u!\n", (unsigned)instruction->operand2.getJumpCallType()); scheduler.addFirstPlayPGC(); break; }}//------------------------------------------------------------------------------void Processor::executeJumpSS(const Instruction* instruction){ executeJumpCallSS(instruction, true);}//------------------------------------------------------------------------------void Processor::executeCallSS(const Instruction* instruction){ state.save(instruction->operand2.getRSMCell()); executeJumpCallSS(instruction, false);}//------------------------------------------------------------------------------void Processor::executeSetSysReg(const Instruction* instruction){ if (!evaluateSetSysRegCondition(instruction)) { scheduler.addStep(); return; } // FIXME: check if these register settings should appear somehow // (e.g. when setting the highlighted button number, shall we // change it on screen)? switch(instruction->getSetType()) { case Instruction::STN: if (instruction->operand1.isAF()) { unsigned value = instruction->isDirect() ? instruction->operand1.getAVAL() : state.getGPRValue(instruction->operand1.getSR1()); state.setSPRValue(SPRM::audioStreamNumber, value); } if (instruction->operand2.isSF()) { unsigned value = instruction->isDirect() ? instruction->operand2.getSVAL() : state.getGPRValue(instruction->operand2.getSR2()); state.setSPRValue(SPRM::subPictureStreamNumber, value); } if (instruction->operand2.isNF()) { unsigned value = instruction->isDirect() ? instruction->operand2.getNVAL() : state.getGPRValue(instruction->operand2.getSR3()); state.setSPRValue(SPRM::angleNumber, value); } break; case Instruction::NVTMR: state.setSPRValue(SPRM::navigationTimer, instruction->isDirect() ? instruction->operand1.getSVAL() : state.getValue(instruction->operand1.getSRS())); state.setSPRValue(SPRM::pgcForNavTimer, instruction->operand2.getPGCN()); break; case Instruction::GPRMMD: { GPR& gpr = state.getGPRM().getRegister(instruction->operand2.getSRD()); gpr.setValue(instruction->isDirect() ? instruction->operand1.getSVAL() : state.getValue(instruction->operand1.getSRS())); if (instruction->operand2.isMF()) { gpr.setCounter(); } else { gpr.clearCounter(); } } break; case Instruction::AMXMD: state.setSPRValue(SPRM::audioMixingMode, instruction->isDirect() ? instruction->operand2.getValue() : state.getGPRValue(instruction->operand2.getSRS())); break; case Instruction::HL_BTNN: state.setSPRValue(SPRM::highlightedButtonNumber, instruction->isDirect() ? instruction->operand2.getValue() : state.getGPRValue(instruction->operand2.getSRS())); break; default: scheduler.addFirstPlayPGC(); Log::error("dvd::vm::Processor::executeSetSysReg: Invalid set type: %u\n", (unsigned)instruction->getSetType()); return; } executeLinkUnconditionally(instruction);}//------------------------------------------------------------------------------void Processor::executeSet(const Instruction* instruction){ if (!evaluateSetCondition(instruction)) { scheduler.addStep(); return; } GPR& destRegister = state.getGPRM().getRegister(instruction->operand1.getSRD()); unsigned sourceValue = 0; Register* sourceRegister = 0; if (instruction->isDirect()) { sourceValue = instruction->operand2.getValue(); } else { sourceRegister = &(state.getRegister(instruction->operand2.getSRS())); sourceValue = sourceRegister->getValue(); } if (executeSet(instruction, destRegister, sourceValue, sourceRegister)) { executeLinkUnconditionally(instruction); }}//------------------------------------------------------------------------------bool Processor::executeSet(const Instruction* instruction, GPR& destRegister, unsigned sourceValue, Register* sourceRegister){ unsigned destValue = destRegister.getValue(); switch(instruction->getSetOp()) { case Instruction::MOV: destValue = sourceValue; break; case Instruction::SWP: if (sourceRegister!=0) { sourceRegister->setValue(destValue); destValue = sourceValue; } else { Log::error("dvd::vm::Processor::executeSet: SWAP instruction with no source register!\n"); scheduler.addFirstPlayPGC(); return false; } break; case Instruction::ADD: destValue += sourceValue; if (destValue>Register::maxValue) destValue=Register::maxValue; break; case Instruction::SUB: destValue -= sourceValue; if (destValue>Register::maxValue) destValue=0; break; case Instruction::MUL: destValue *= sourceValue; if (destValue>Register::maxValue) destValue=Register::maxValue; break; case Instruction::DIV: if (sourceValue>0) destValue /= sourceValue; else destValue = 0; break; case Instruction::MOD: if (sourceValue>0) destValue %= sourceValue; else destValue = 0; break; case Instruction::RND: // FIXME: add a srand somewhere! destValue = (unsigned)((double)sourceValue * rand() / (1.0 + RAND_MAX)); break; case Instruction::AND: destValue &= sourceValue; break; case Instruction::OR: destValue |= sourceValue; break; case Instruction::XOR: destValue ^= sourceValue; break; default: Log::error("dvd::vm::Processor::executeSet: invalid set operation: %u!\n", (unsigned)instruction->getSetOp()); scheduler.addFirstPlayPGC(); return false; case Instruction::SET_NONE: break; } destRegister.setValue(destValue); return true;}//------------------------------------------------------------------------------void Processor::executeSetCLnk(const Instruction* instruction){ if (!executeSetWithLink(instruction)) return; if (!evaluateSetCLnkCondition(instruction)) { scheduler.addStep(); return; } executeLinkSubset(instruction);}//------------------------------------------------------------------------------bool Processor::executeSetWithLink(const Instruction* instruction){ if (instruction->getSetOp()==Instruction::SET_NONE) return true; GPR& destRegister = state.getGPRM().getRegister(instruction->getSRD()); unsigned sourceValue = 0; Register* sourceRegister = 0; if (instruction->isDirect()) { sourceValue = instruction->operand1.getSVAL(); } else { sourceRegister = &(state.getRegister(instruction->operand1.getSRS())); sourceValue = sourceRegister->getValue(); } return executeSet(instruction, destRegister, sourceValue, sourceRegister);}//------------------------------------------------------------------------------void Processor::executeCSetCLnk(const Instruction* instruction){ if (!evaluateCSetCLnkCondition(instruction)) { scheduler.addStep(); return; } if (!executeSetWithLink(instruction)) return; executeLinkSubset(instruction);}//------------------------------------------------------------------------------void Processor::executeCmpSetLnk(const Instruction* instruction){ if (evaluateCmpSetLnkCondition(instruction)) { if (!executeSetWithLink(instruction)) return; } executeLinkSubset(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateConditionV1(const Instruction* instruction) const{ Instruction::cmpOp_t cmpOp = instruction->getCmpOp(); if (cmpOp==Instruction::CMP_NONE) return true; unsigned value1 = state.getValue(instruction->operand1.getCR1()); unsigned value2 = instruction->isCmpDirect() ? instruction->operand2.getValue() : state.getValue(instruction->operand2.getCR2()); return evaluateComparison(cmpOp, value1, value2);}//------------------------------------------------------------------------------bool Processor::evaluateConditionV2(const Instruction* instruction) const{ Instruction::cmpOp_t cmpOp = instruction->getCmpOp(); if (cmpOp==Instruction::CMP_NONE) return true; unsigned value1 = state.getValue(instruction->operand3.getCR1()); unsigned value2 = state.getValue(instruction->operand3.getCR2()); return evaluateComparison(cmpOp, value1, value2);}//------------------------------------------------------------------------------bool Processor::evaluateConditionV3(const Instruction* instruction) const{ Instruction::cmpOp_t cmpOp = instruction->getCmpOp(); if (cmpOp==Instruction::CMP_NONE) return true; unsigned value1 = state.getValue(instruction->operand1.getSetCR1()); unsigned value2 = instruction->isCmpDirect() ? instruction->operand3.getCVAL() : state.getValue(instruction->operand3.getCR2()); return evaluateComparison(cmpOp, value1, value2);}//------------------------------------------------------------------------------bool Processor::evaluateConditionV4(const Instruction* instruction) const{ Instruction::cmpOp_t cmpOp = instruction->getCmpOp(); if (cmpOp==Instruction::CMP_NONE) return true; unsigned value1 = state.getValue(instruction->getCR1()); unsigned value2 = instruction->isCmpDirect() ? instruction->operand2.getCVAL() : state.getValue(instruction->operand2.getCR2()); return evaluateComparison(cmpOp, value1, value2);}//------------------------------------------------------------------------------bool Processor::evaluateSpecialCondition(const Instruction* instruction) const{ return evaluateConditionV1(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateLinkCondition(const Instruction* instruction) const{ return evaluateConditionV1(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateJumpCallCondition(const Instruction* instruction) const{ return evaluateConditionV2(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateSetSysRegCondition(const Instruction* instruction) const{ return evaluateConditionV2(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateSetCondition(const Instruction* instruction) const{ return evaluateConditionV3(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateSetCLnkCondition(const Instruction* instruction) const{ return evaluateConditionV4(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateCSetCLnkCondition(const Instruction* instruction) const{ return evaluateConditionV4(instruction);}//------------------------------------------------------------------------------bool Processor::evaluateCmpSetLnkCondition(const Instruction* instruction) const{ return evaluateConditionV4(instruction);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -