// license:BSD-3-Clause // copyright-holders:Farfetch'd, R. Belmont #define F2END() \ return 2 + m_amlength1 + m_amlength2; #define F2LOADOPFLOAT(num) \ if (m_flag##num) \ appf = u2f(m_reg[m_op##num]); \ else \ appf = u2f(m_program->read_dword_unaligned(m_op##num)); #define F2STOREOPFLOAT(num) \ if (m_flag##num) \ m_reg[m_op##num] = f2u(appf); \ else \ m_program->write_dword_unaligned(m_op##num, f2u(appf)); void v60_device::F2DecodeFirstOperand(am_func DecodeOp1, uint8_t dim1) { m_moddim = dim1; m_modm = m_instflags & 0x40; m_modadd = PC + 2; m_amlength1 = (this->*DecodeOp1)(); m_op1 = m_amout; m_flag1 = m_amflag; } void v60_device::F2DecodeSecondOperand(am_func DecodeOp2, uint8_t dim2) { m_moddim = dim2; m_modm = m_instflags & 0x20; m_modadd = PC + 2 + m_amlength1; m_amlength2 = (this->*DecodeOp2)(); m_op2 = m_amout; m_flag2 = m_amflag; } void v60_device::F2WriteSecondOperand(uint8_t dim2) { m_moddim = dim2; m_modm = m_instflags & 0x20; m_modadd = PC + 2 + m_amlength1; m_amlength2 = WriteAM(); } uint32_t v60_device::opCVTWS() { float val; F2DecodeFirstOperand(&v60_device::ReadAM, 2); // Convert to float val = (float)(int32_t)m_op1; m_modwritevalw = f2u(val); _OV = 0; _CY = (val < 0.0f); _S = ((m_modwritevalw & 0x80000000) != 0); _Z = (val == 0.0f); F2WriteSecondOperand(2); F2END(); } uint32_t v60_device::opCVTSW() { float val; F2DecodeFirstOperand(&v60_device::ReadAM, 2); // Convert to uint32_t val = u2f(m_op1); m_modwritevalw = (uint32_t)val; _OV = 0; _CY =(val < 0.0f); _S = ((m_modwritevalw & 0x80000000) != 0); _Z = (val == 0.0f); F2WriteSecondOperand(2); F2END(); } uint32_t v60_device::opMOVFS() { F2DecodeFirstOperand(&v60_device::ReadAM, 2); m_modwritevalw = m_op1; F2WriteSecondOperand(2); F2END(); } uint32_t v60_device::opNEGFS() { float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); appf = -u2f(m_op1); _OV = 0; _CY = (appf < 0.0f); _S = ((f2u(appf) & 0x80000000) != 0); _Z = (appf == 0.0f); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opABSFS() { float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); appf = u2f(m_op1); if(appf < 0) appf = -appf; _OV = 0; _CY = 0; _S = ((f2u(appf) & 0x80000000) != 0); _Z = (appf == 0.0f); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opADDFS() { uint32_t appw; float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); F2LOADOPFLOAT(2); appf += u2f(m_op1); appw = f2u(appf); _OV = _CY = 0; _S = ((appw & 0x80000000) != 0); _Z = (appw == 0); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opSUBFS() { uint32_t appw; float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); F2LOADOPFLOAT(2); appf -= u2f(m_op1); appw = f2u(appf); _OV = _CY = 0; _S = ((appw & 0x80000000) != 0); _Z = (appw == 0); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opMULFS() { uint32_t appw; float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); F2LOADOPFLOAT(2); appf *= u2f(m_op1); appw = f2u(appf); _OV = _CY = 0; _S = ((appw & 0x80000000) != 0); _Z = (appw == 0); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opDIVFS() { uint32_t appw; float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); F2LOADOPFLOAT(2); appf /= u2f(m_op1); appw = f2u(appf); _OV = _CY = 0; _S = ((appw & 0x80000000) != 0); _Z = (appw == 0); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opSCLFS() { uint32_t appw; float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 1); F2DecodeSecondOperand(&v60_device::ReadAMAddress, 2); F2LOADOPFLOAT(2); if ((int16_t)m_op1 < 0) appf /= 1 << -(int16_t)m_op1; else appf *= 1 << m_op1; appw = f2u(appf); _OV = _CY = 0; _S = ((appw & 0x80000000) != 0); _Z = (appw == 0); F2STOREOPFLOAT(2); F2END() } uint32_t v60_device::opCMPF() { float appf; F2DecodeFirstOperand(&v60_device::ReadAM, 2); F2DecodeSecondOperand(&v60_device::ReadAM, 2); appf = u2f(m_op2) - u2f(m_op1); _Z = (appf == 0); _S = (appf < 0); _OV = 0; _CY = 0; F2END(); } uint32_t v60_device::op5FUNHANDLED() { fatalerror("Unhandled 5F opcode at %08x\n", PC); return 0; /* never reached, fatalerror won't return */ } uint32_t v60_device::op5CUNHANDLED() { fatalerror("Unhandled 5C opcode at %08x\n", PC); return 0; /* never reached, fatalerror won't return */ } const v60_device::am_func v60_device::s_Op5FTable[32] = { &v60_device::opCVTWS, &v60_device::opCVTSW, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED, &v60_device::op5FUNHANDLED }; const v60_device::am_func v60_device::s_Op5CTable[32] = { &v60_device::opCMPF, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::opMOVFS, &v60_device::opNEGFS, &v60_device::opABSFS, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::opSCLFS, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::opADDFS, &v60_device::opSUBFS, &v60_device::opMULFS, &v60_device::opDIVFS, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED, &v60_device::op5CUNHANDLED }; uint32_t v60_device::op5F() { m_instflags = OpRead8(PC + 1); return (this->*s_Op5FTable[m_instflags & 0x1F])(); } uint32_t v60_device::op5C() { m_instflags = OpRead8(PC + 1); return (this->*s_Op5CTable[m_instflags & 0x1F])(); }