summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/cpu/v60/op2.hxx
blob: 8d7be235dcecfd907ba09deb207f7ae7c73913f2 (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                                           
 

                                             
 


                                                             
                                                                 
                                                                       
 


                                                             
                                                                 
                                                                       
 
                                                                      
 





                                           

 
                                                                       
 





                                           

 
                                                   
 



                                        

 
                              


                  
                                                     

                           
                                    
                                  
 



                                                  
 

                                

 
                              


                  
                                                     
 
                              
                         
                                       
 



                                                  
 

                                

 
                              
 



                                                     

 
                              


                   

                                                             
 
                           
 



                                             
 

                          

 
                              


                   

                                                             
 
                          



                             



                                             
 

                          

 
                              
 
                      

                   

                                                             
 
                         
 
                           

                         


                                        
 

                          

 
                              
 
                      

                   

                                                             
 
                         
 
                           

                         


                                        
 

                          

 
                              
 
                      

                   

                                                             
 
                         
 
                           

                         


                                        
 

                          

 
                              
 
                      

                   

                                                             
 
                         
 
                           

                         


                                        
 

                          

 
                              
 
                      

                   

                                                             
 
                         
 

                                             
            
                                   

                         


                                        
 

                          

 
                             


                   

                                                      
 
                                       
 



                         
 
                

 
                                    
 
                                                        


                                                              
                                    
 
                                                        


                                                              
                                                       
 































                                   

  
                                                       
 
































                                   


  
                           
 

                                                          


 
                           
 

                                                          
 
// 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])();
}