diff --git a/tools/VuTest/MinMaxTest.cpp b/tools/VuTest/MinMaxTest.cpp index df6d53428..b9cc3c8f6 100644 --- a/tools/VuTest/MinMaxTest.cpp +++ b/tools/VuTest/MinMaxTest.cpp @@ -7,6 +7,7 @@ void CMinMaxTest::Execute(CTestVm& virtualMachine) auto resultReg2 = CVuAssembler::VF17; auto resultReg3 = CVuAssembler::VF18; auto resultReg4 = CVuAssembler::VF19; + auto resultReg5 = CVuAssembler::VF20; virtualMachine.Reset(); @@ -29,7 +30,7 @@ void CMinMaxTest::Execute(CTestVm& virtualMachine) CVuAssembler::Lower::NOP()); //Inspired by Gran Turismo 4 - //MINI/MAX needs to work properly with PS2's minimum & maximum float values + //MINI/MAX need to work properly with PS2's minimum & maximum float values assembler.Write( CVuAssembler::Upper::MINI(CVuAssembler::DEST_XYZW, resultReg3, CVuAssembler::VF1, CVuAssembler::VF4), @@ -39,6 +40,13 @@ void CMinMaxTest::Execute(CTestVm& virtualMachine) CVuAssembler::Upper::MAX(CVuAssembler::DEST_XYZW, resultReg4, CVuAssembler::VF5, CVuAssembler::VF1), CVuAssembler::Lower::NOP()); + //Inspired by Dragon Quest - Shounen Yangus to Fushigi no Dungeon + //MAX needs to compare denormal with 0 as bigger. + + assembler.Write( + CVuAssembler::Upper::MAXbc(CVuAssembler::DEST_XYZW, resultReg5, CVuAssembler::VF1, CVuAssembler::VF0, CVuAssembler::BC_X), + CVuAssembler::Lower::NOP()); + assembler.Write( CVuAssembler::Upper::NOP() | CVuAssembler::Upper::E_BIT, CVuAssembler::Lower::NOP()); @@ -93,4 +101,9 @@ void CMinMaxTest::Execute(CTestVm& virtualMachine) TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV1 == Float::_Minus8); TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV2 == Float::_64); TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV3 == 0x80); + + TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg5].nV0 == Float::_1); + TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg5].nV1 == 0); + TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg5].nV2 == Float::_64); + TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg5].nV3 == 0x80); } diff --git a/tools/VuTest/VuAssembler.cpp b/tools/VuTest/VuAssembler.cpp index 79edc61ea..4021830c6 100644 --- a/tools/VuTest/VuAssembler.cpp +++ b/tools/VuTest/VuAssembler.cpp @@ -196,6 +196,17 @@ uint32 CVuAssembler::Upper::MAX(DEST dest, VF_REGISTER fd, VF_REGISTER fs, VF_RE return result; } +uint32 CVuAssembler::Upper::MAXbc(DEST dest, VF_REGISTER fd, VF_REGISTER fs, VF_REGISTER ft, BROADCAST bc) +{ + uint32 result = 0x00000010; + result |= bc; + result |= (fd << 6); + result |= (fs << 11); + result |= (ft << 16); + result |= (dest << 21); + return result; +} + uint32 CVuAssembler::Upper::MINI(DEST dest, VF_REGISTER fd, VF_REGISTER fs, VF_REGISTER ft) { uint32 result = 0x0000002F; diff --git a/tools/VuTest/VuAssembler.h b/tools/VuTest/VuAssembler.h index e85b7e423..5a4c264ad 100644 --- a/tools/VuTest/VuAssembler.h +++ b/tools/VuTest/VuAssembler.h @@ -144,6 +144,7 @@ public: static uint32 MULq(DEST, VF_REGISTER, VF_REGISTER); static uint32 MULAbc(DEST, VF_REGISTER, VF_REGISTER, BROADCAST); static uint32 MAX(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER); + static uint32 MAXbc(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER, BROADCAST); static uint32 MINI(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER); static uint32 NOP(); static uint32 OPMULA(VF_REGISTER, VF_REGISTER);