VIF: Implement DIRECT* instructions

This commit is contained in:
hch12907 2018-11-23 13:37:31 +08:00
parent bbf79d0a3a
commit c15fd1fba1
3 changed files with 32 additions and 13 deletions

View file

@ -81,15 +81,11 @@ int CVif::time_step(const int ticks_available)
unit->inst = std::make_unique<VifcodeInstruction>(data);
unit->stat.insert_field(VifUnitRegister_Stat::VPS, 0b10);
unit->subpackets_left = obtain_required_words(*unit->inst);
BOOST_LOG(Core::get_logger()) << "VIF: Fetched instruction " << unit->inst->get_info()->mnemonic;
continue;
}
else
{
unit->subpackets_left--;
(this->*INSTRUCTION_TABLE[unit->inst->get_info()->impl_index])(unit, *unit->inst);
// If there are no packets left, set the VIF status to idle
if (!unit->subpackets_left)
{
@ -104,6 +100,10 @@ int CVif::time_step(const int ticks_available)
continue;
}
unit->subpackets_left--;
(this->*INSTRUCTION_TABLE[unit->inst->get_info()->impl_index])(unit, *unit->inst);
}
}
@ -121,10 +121,10 @@ int CVif::obtain_required_words(const VifcodeInstruction instruction) const
switch (instruction.get_info()->cpi)
{
case SpecialVifcodePacketUsage::Num:
return 1 + instruction.num() * 2;
return 1 + (instruction.num() ? instruction.num() : 256) * 2;
case SpecialVifcodePacketUsage::Immediate:
return 1 + instruction.imm() * 4;
return 1 + (instruction.imm() ? instruction.imm() : 65536) * 4;
default:
return instruction.get_info()->cpi;

View file

@ -94,20 +94,20 @@ void CVif::STMASK(VifUnit_Base* unit, const VifcodeInstruction inst)
void CVif::STROW(VifUnit_Base* unit, const VifcodeInstruction inst)
{
if (unit->subpackets_left >= 4)
if (unit->subpackets_left >= obtain_required_words(inst))
return;
SizedWordRegister *const row_regs[4] = { &unit->r3, &unit->r2, &unit->r1, &unit->r0 };
row_regs[unit->subpackets_left]->write_uword(unit->processing_data);
row_regs[unit->subpackets_left - 1]->write_uword(unit->processing_data);
}
void CVif::STCOL(VifUnit_Base* unit, const VifcodeInstruction inst)
{
if (unit->subpackets_left >= 4)
if (unit->subpackets_left >= obtain_required_words(inst))
return;
SizedWordRegister *const col_regs[4] = { &unit->c3, &unit->c2, &unit->c1, &unit->c0 };
col_regs[unit->subpackets_left]->write_uword(unit->processing_data);
col_regs[unit->subpackets_left - 1]->write_uword(unit->processing_data);
}

View file

@ -46,7 +46,16 @@ void CVif::DIRECT(VifUnit_Base* unit, const VifcodeInstruction inst)
return;
}
// TODO: Implement this
// Do nothing in the first pass
if (unit->subpackets_left >= obtain_required_words(inst))
{
return;
}
RResources& r = core->get_resources();
unit->stat.insert_field(VifUnitRegister_Stat::VFS, 0b11);
r.fifo_gif_path2.write(reinterpret_cast<const ubyte*>(&unit->processing_data), NUMBER_BYTES_IN_WORD);
}
void CVif::DIRECTHL(VifUnit_Base* unit, const VifcodeInstruction inst)
@ -58,5 +67,15 @@ void CVif::DIRECTHL(VifUnit_Base* unit, const VifcodeInstruction inst)
return;
}
// TODO: Implement this
// Do nothing in the first pass
if (unit->subpackets_left >= obtain_required_words(inst))
{
return;
}
RResources& r = core->get_resources();
unit->stat.insert_field(VifUnitRegister_Stat::VFS, 0b11);
// TODO: We are supposed to stall until the PATH3 IMAGE transfer is finished...
r.fifo_gif_path2.write(reinterpret_cast<const ubyte*>(&unit->processing_data), NUMBER_BYTES_IN_WORD);
}