summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/tx1.cpp
blob: 52bb4d0561b99fb355a95cd2a817c913777b57c9 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                   
                                                                            
 
                                           
 
                                                                            
 
                
                     
                        
                         
 
 
  
                    
  
                                                                               


                                                                                          
 
                                                    
 
                                   


                                           


 
  
                          
 


                                                
  
                                             


                                           
                                           


                                           

                                           
                                           
                                           

                                           



                                           

  
                                                              
 
                     
         


































                                                                      

         

                                                 
 
 
                                                            
 
                   
         



                                                                                                       

                       
 



                      
         













                                                                               

         
                                                               
                       

                            


                         
 
 
                                                                     
 
                                        
 
                       
         

                                  
         
                            
         

                                

         
 
                                                                                                 
 





                                                                 
 

                                                  

          

                                            
                      
         




                                
                 
















                                             
 




                                
 







                                             
                 



















                                                                        

                                       

                                                                                                                    
 




                                             
                 
                                 
                 











                                               
 






                                             
                 
                                  
                 

                                             
                 
                                  
                 
                                             
                 
                                  
                 

                                             
                 






























                                                                       
         




                                                             
 

                                           
 
 
 
                                                                            
 
      
 
             
 
                                                                            
 
                                        



                             
 

    
                             






                             
 
                                                                                                
 
                                                           
 
                                                                      
 

                                           
            
                                                 
 

                             
 
                                  
 


                                 
 
                                                                                       
 



                           
                                                                            
                               
                  




                                              
                                                                                                                                              
                               

                                          

                                                                 
 
                                                
                 
                                        
                 
                                                     




                                                                  
                       
                 
                                                      


                                         
                                                         
                         


                                                                                 
                                           
                                               

                                    






                                                                                                         
 
                                              
                                                               
                                                   
                                 

                                                                                                    
                                                             
                                 
                                                   
                                                                         
                                                   
                                                                                 
 
                                                          

                          








                                                                                                  
                                                                                  
                         
                                              
 
                                                          
 
                                                         
                                                                                     
                                 
                                                               
                                 
                                                                               
                                 
                                                             
                                                                   
                                         

                                                                                 
                                         
                                                            
                                                                        
                                         

                                                                                 



                                         
                                          






                                                                                                              


                                                                                         
                                                   

                                            





                                                                                                                 
                                                                   
                                         

                                                                                 



                                                                    

                                                                                         
                                                 
                                         
                                                                        
                                         

                                                                                 



                                                                    

                                                                                         
                                                 



                                         
                         
                                                                
                                 
                                                                            



                                                                     
                                                               
                                                                  




                                                                   
                                                   




                                      
 
                                             



                             
                           


                        
                                   
                 
                                                  







                                                
                                                   

                    
                                

                                         
                                       

                    
                                           
         


                                                                 
                           
 
                                                
                               

                    
                            




                                                                                         

                 

                                                      
                              
                                                        
                                    

                          
                                                             
                                                                                             
                          
                                                                                    

                                                                  
                 
                                   
                                                                  
                                   
                                                                          

                                                          
                                   

                                                        
                                                        
                         
                                                                        
                         
                                                             
                         
                                            
                                                                            
                                                               

                         
                                                        

                                              
                                                   

                                                    
                                                     




                         

                                                                

                                                                              
                                               

         
                               
         

                                                        
         
                                    
         
                              
                                   

         
                             
 
 
                                                        
 
                               

                     
                                                

                    
                           


                        
                                   
                 
                                                  






                                                
                                                     

                    
                                           

                                      
                                                          

                    
                                           
         
                                                                

                                  
                                                      
 
                                                     
                         
                                                                      








                                                    
                                                                     








                                                              
                                             


                    
                                           
         
                  



                              
                                                  

         
                               
         

                                                        
         
                                    
         
                              
                                   

         
 
                                                 
 
                                                                                                              
 
                                        
         
                                                                  
         
                                             
         
                                              

                                 
                                                     
         
                                             
         
                                                 
         
                                             
         
                                                                         

                                  
                                                      
 
                                                     
                         
                                                                      








                                                    
                                                                     








                                                              
                                                     


                 
                                        
         
                              
                                   

         
                               
 
 
 
                                                 
 
                                             


                     
                                        
         
                                                                  
         
                                             
         
                                              

                                 
                                                     
         
                                             
         

                                                 
         
                                             

                          
                                              
 
                                             
                 
                                                              








                                            
                                                             








                                                      
                                             

         
                                        
         
                              
                                   

         
                               
 
 
                        
                                                                               
 
                                                
                                          
 
 
 
                                                                            
 
           
 
                                                                            



                             
 








                            
                    
  
 
                                                                                           
 
                                                              
 
                                                                      
 

                                           
            
                                                 
 

                             
 
                                       
 


                                 
 
                                                                                       
 



                           
                                                                            
                               
                                                                                                                                              


                                          

                                                                 
 


                                                    

                                        

                                                                                     




                          
                                                      

                                        
 
                                                       
                         


                                                                                            
                         
                                                           
                         
                                                                    



                                                                  
                                                                                  
                         
                                              
 
                                                          
 
                                                                                     
                                 
                                                              
                                 
                                                                    
                                 
                                                                   
                                         

                                                                                
                                         
                                                                        
                                         

                                                                                



                                         
                                                                   
                                         

                                                                                
                                         
                                                                        
                                         

                                                                                



                                         
                         
                                                               
                                 
                                                                            



                                                                     
                                                               
                                                                  




                                     
                                                            
                 
                                                                  
                 
                                                                 
                 
                                                                  


                                                                   
                                                   




                                      
 
                                                  
 


                             
                           


                        
                                   
                 
                                                  







                                                
                                                   

                          

                                                   

                    
                                
         
                                               

                    
                                           
         
                                                                            
                                                             
 
                                              

                                       

                                                       
 
                                                            
                                   
                 
                                                       

                                              
                                                        




                         

                                                       

                                                                              
                                               

         
                              
         

                                                        
         
                                   
         
                              
                                        

         
                             
 
 
                                                             
 
                               



                     
                           


                        
                                   
                 
                                                  






                                                
                                                     

                    
                                           
         
                                                 

                    
                                           
         
                                                            

                                  
                                                      
 
                                                     
                         
                                                                      








                                                            
                                                                     








                                                              
                                             

                    
                 
                                                                               
                                                



                 
                                                                    
                                        

         
                              
         

                                                        
         
                                   
         
                              
                                        

         
 
  
                                       
  
                                                      
 
                                                                                                              
 
                                       
         
                                                                  
         
                                            
         
                                              

                                
                                                     
         
                                            
         
                                                 
         
                                            
         
                                                            

                                  
                                                      
 
                                                     
                         
                                                                      








                                                            
                                                                     








                                                              
                                             


                 
                                       
         
                              
                                        

         
                               
 
 
                                                                                    
 
                                          
 
 
                                                      
 
                                             


                     
                                       
         
                                                                  
         
                                            
         
                                              

                                
                                                     
         
                                            
         
                                                 
         
                                            
         
                                                            

                                  
                                                      
 
                                                     
                         
                                                                      








                                                            
                                                                     








                                                              
                                             


                 
                                       
         
                              
                                        

         
                               
 
 
 
 




                                       
 
                                        
 


                                                                 
                                           
 
 
                                   
 


                                                                 
                                           
 
// license:BSD-3-Clause
// copyright-holders:Philip Bennett
/***************************************************************************

    Tatsumi TX-1/Buggy Boy machine hardware

***************************************************************************/

#include "emu.h"
#include "debugger.h"
#include "cpu/i86/i86.h"
#include "includes/tx1.h"


/*
    Helper functions
*/
#define INC_PROM_ADDR       ( m_math.promaddr = (m_math.promaddr + 1) & 0x1ff )
#define ROR16(val, shift)   ( ((uint16_t)val >> shift) | ((uint16_t)val << (16 - shift)) )
#define ROL16(val, shift)   ( ((uint16_t)val << shift) | ((uint16_t)val >> (16 - shift)) )
#define SWAP16(val)         ( (((uint16_t)val << 8) & 0xff00) | ((uint16_t)val >> 8) )

static inline uint8_t reverse_nibble(uint8_t nibble)
{
	return  (nibble & 1) << 3 |
			(nibble & 2) << 1 |
			(nibble & 4) >> 1 |
			(nibble & 8) >> 3;
}


/*
    State transition table

    A little different to the real thing in that
    there are no states between final input and
    multiplication/division.
*/
static constexpr uint8_t state_table[16][8] =
{
	{  4,  4,  4,  4,  5,  1,  1,  0 },
	{  4,  4,  4,  4,  5,  5,  3,  0 },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{  4,  4,  4,  4,  5,  5, 11,  0 },
	{  8,  8,  8,  8,  8,  8,  8,  8 },
	{ 10, 10, 10, 10, 10, 10, 10, 10 },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{  4,  4,  4,  4,  5,  0,  1,  0 },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{  4,  4,  4,  4,  4,  5,  1,  0 },
	{  4,  4,  4,  4,  5,  5,  1,  0 },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
	{0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf },
};

void tx1_state::sn74s516_t::multiply(running_machine &machine)
{
	switch (code)
	{
	case 0:
		ZW.ZW32 = X * Y;
		break;
	case 2:
		ZW.ZW32 += X * Y;
		break;
	case 3:
		ZW.ZW32 += -X * Y;
		break;
	case 0x60:
		ZW.ZW32 = X * Y;
		break;
	case 0x61:
		ZW.ZW32 = -X * Y;
		break;
	case 0x62:
		ZW.ZW32 += X * Y;
		break;
	case 0x63:
		ZW.ZW32 += -X * Y;
		break;
	case 0x660:
		ZW.ZW32 = (X * Y) + (ZW.ZW32 & 0xffff0000);
		break;
	case 0x661:
		ZW.ZW32 = (-X * Y) + (ZW.ZW32 & 0xffff0000);
		break;
	case 0x662:
		ZW.ZW32 = (-X * Y) + (ZW.ZW32 & 0xffff0000);
		break;
	case 0x6660:
		ZW.ZW32 += (X * Y);
		break;
	default:
		osd_printf_debug("sn74s516 ??? multiply: %x\n", code);
	}

	// Seems a good enough place to clear it.
	ZWfl = 0;
}

void tx1_state::sn74s516_t::divide(running_machine &machine)
{
	if (X == 0)
	{
		machine.logerror("%s: SN74S516 tried to divide by zero\n", machine.describe_context());
		ZW.as16bit.Z = int16_t(0xffff);
		ZW.as16bit.W = 0xffff;
		ZWfl = 0;
		return;
	}

	int32_t Z = 0;
	int32_t W = 0;

	switch (code)
	{
	case 4:
		Z = ZW.ZW32 / X;
		W = ZW.ZW32 % X;
		break;
	case 0x664:
		Z = ZW.ZW32 / X;
		W = ZW.ZW32 % X;
		break;
	case 0x6664:
		Z = ZW.as16bit.W / X;
		W = ZW.as16bit.W % X;
		break;
	default:
		osd_printf_debug("SN74S516 unhandled divide type: %x\n", code);
	}

	// Divide overflow Only happens during chip test anyway
	if (Z > 0xffff)
		Z |= 0xff00;

	ZW.as16bit.Z = Z;
	ZW.as16bit.W = W;
	ZWfl = 0;
}

void tx1_state::sn74s516_t::update(running_machine &machine, int ins)
{
	state = state_table[state][ins];

	if (state == 4)
	{
		multiply(machine);
		state = 8;
	}
	else if (state == 5)
	{
		divide(machine);
		state = 10;
	}
}

void tx1_state::sn74s516_t::kick(running_machine &machine, math_t &math, uint16_t *data, int ins)
{
#define LOAD_X      (X = *data)
#define LOAD_Y      (Y = *data)
#define LOAD_Z      (ZW.as16bit.Z = *data)
#define LOAD_W      (ZW.as16bit.W = *data)
#define READ_ZW     *data = ZWfl ? ZW.as16bit.W : ZW.as16bit.Z; \
					ZWfl ^= 1;

#define UPDATE_SEQUENCE (code = (code << 4) | ins)
#define CLEAR_SEQUENCE  (code = 0)

	/*
	    Remember to change the Z/W flag.
	*/
	switch (state)
	{
	case 0:
		CLEAR_SEQUENCE;
		UPDATE_SEQUENCE;

		if (ins < 4)
		{
			LOAD_Y;
			update(machine, ins);
		}
		else if (ins == 4)
		{
			update(machine, ins);
		}
		else if (ins < 7)
		{
			LOAD_X;
			update(machine, ins);
		}
		else if (ins == 7)
		{
			READ_ZW;
			break;
		}

		break;
	case 8:
	case 10:
		CLEAR_SEQUENCE;
		UPDATE_SEQUENCE;

		if (ins < 4)
		{
			LOAD_Y;
			update(machine, ins);
		}
		else if (ins == 4)
		{
			update(machine, ins);
		}
		else if (ins == 5)
		{
			// Rounding
			// Operation
			update(machine, ins);
		}
		else if (ins == 6)
		{
			LOAD_X;
			update(machine, ins);
		}
		else if (ins == 7)
		{
			READ_ZW;
			update(machine, ins);
		}
		break;
	case 1:
		// TODO: 6666 represents an incomplete state - clear it.
		if (code == 0x6666)
		{
			CLEAR_SEQUENCE;
			machine.logerror("%s: Code 6666: PROMADDR:%x\n", machine.describe_context(), math.promaddr);
		}

		UPDATE_SEQUENCE;
		if (ins < 4)
		{
			LOAD_Y;
			update(machine, ins);
		}
		else if (ins < 6)
		{
			update(machine, ins);
		}
		else if (ins == 6)
		{
			LOAD_Z;
			update(machine, ins);
		}
		else if (ins == 7)
		{
			// Pointless operation.
			update(machine, ins);
		}

		break;
	case 3:
		UPDATE_SEQUENCE;
		if (ins < 4)
		{
			LOAD_Y;
			update(machine, ins);
		}
		else if (ins == 4)
		{
			LOAD_W;
			update(machine, ins);
		}
		else if (ins == 5)
		{
			update(machine, ins);
		}
		else if (ins == 6)
		{
			LOAD_W;
			update(machine, ins);
		}
		else if (ins == 7)
		{
			READ_ZW;
			update(machine, ins);
		}
		break;
	case 11:
		UPDATE_SEQUENCE;
		if (ins < 4)
		{
			LOAD_Y;
			update(machine, ins);
		}
		else if (ins < 6)
		{
			update(machine, ins);
		}
		else if (ins == 6)
		{
			// CHECK: Incomplete state
			update(machine, ins);
		}
		else if (ins == 7)
		{
			// 6667 = Load X, Load Z, Load W, Clear Z
			ZW.as16bit.Z = 0;
			update(machine, ins);
		}
		break;
	default:
		osd_printf_debug("Unknown SN74S516 state. %x\n", code);
	}
}

inline void tx1_state::kick_sn74s516(uint16_t *data, int ins)
{
	m_sn74s516.kick(machine(), m_math, data, ins);

	m_math.dbgaddr = m_math.promaddr;
	m_math.dbgpc = m_mathcpu->pcbase();
}


/***************************************************************************

  TX-1

  Preliminary

***************************************************************************/

/* Same mapping as Buggy Boy actually */
#define TX1_INSLD       0x100
#define TX1_CNTST       0x80
#define TX1_RADCHG      0x20
#define TX1_DSEL        0x03

enum
{
	TX1_SEL_MULEN = 0x00,
	TX1_SEL_PPSEN,
	TX1_SEL_PSSEN,
	TX1_SEL_LMSEL,
	TX1_SEL_DSELOE,
	TX1_SEL_INSCL = 0x06,
	TX1_SEL_ILDEN
};

#define TX1_SET_INS0_BIT    do { if (!(ins & 0x4) && m_math.i0ff) ins |= m_math.i0ff; } while(0)

inline uint16_t tx1_state::math_t::get_datarom_addr() const
{
	uint16_t addr = ((inslatch & 0x1c00) << 1) | (ppshift & 0xff);

	if ((inslatch >> 8) & TX1_RADCHG)
		addr |= (ppshift & 0x0700);
	else
		addr |= (promaddr << 3) & 0x0700;

	return addr & 0x3fff;
}

void tx1_state::tx1_update_state()
{
#define LHIEN(a)    !(a & 0x80)
#define LLOEN(a)    !(a & 0x40)
#define GO_EN(a)    !(a & 0x4000)

	const uint16_t *prom = (uint16_t*)memregion("au_data")->base() + (0x8000 >> 1);

	for (;;)
	{
		int go = 0;

		if (!GO_EN(m_math.inslatch) && GO_EN(prom[m_math.promaddr]))
			go = 1;
		/*
		    Example:
		    120 /GO /LHIEN
		    121 /GO        /LLOEN
		    Both 120 and 121 are used.
		*/
		else if ((GO_EN(m_math.inslatch) && GO_EN(prom[m_math.promaddr])) && (LHIEN(m_math.inslatch) && LLOEN(prom[m_math.promaddr])))
			go = 1;

		/* Now update the latch */
		m_math.inslatch = prom[m_math.promaddr] & 0x7fff;
		m_math.mux = (m_math.inslatch >> 3) & 7;

		if (m_math.mux == TX1_SEL_INSCL)
		{
			m_math.i0ff = 0;
		}
		else if (m_math.mux == TX1_SEL_PPSEN)
		{
			// NOTE: Doesn't do anything without SPCS.
		}

		/* TODO */
		if (go)
		{
			int ins = m_math.inslatch & 7;

			TX1_SET_INS0_BIT;

			if (m_math.mux == TX1_SEL_DSELOE)
			{
				int     dsel = (m_math.inslatch >> 8) & TX1_DSEL;
				int     tfad = (m_math.inslatch & 0x1c00) << 1;
				int     sd   = m_math.ppshift;
				int     o4;
				uint16_t  data;

				o4 =
					(!BIT(sd, 9) && !BIT(sd,10)) ||
					( BIT(sd, 7) &&  BIT(sd,10)) ||
					(!BIT(sd, 8) &&  BIT(sd, 9)) ||
					(!BIT(sd, 7) &&  BIT(sd, 8)) ||
					!BIT(dsel, 1) || BIT(tfad, 13) || BIT(tfad, 12) || BIT(tfad, 11);

				dsel = (dsel & 2) | ((dsel & o4) ^ 1);

				if (dsel == 0)
					data = m_math.muxlatch;
				else if (dsel == 1)
				{
					uint16_t *romdata = (uint16_t*)memregion("au_data")->base();
					uint16_t addr = m_math.get_datarom_addr();
					data = romdata[addr];
				}
				else if (dsel == 2)
					data = ROL16(m_math.muxlatch, 4);
				else if (dsel == 3)
					data = ROL16(SWAP16(m_math.muxlatch), 3);

				kick_sn74s516(&data, ins);
			}
			/*
			    TODO: Changed ppshift to muxlatch for TX-1

			    /TMPLD1: /LHIEN
			    /TMPLD2: /LLOEN.!O4 + (/LHIEN.O4)
			    /TMPLD3: /LLOEN
			         O4: !SD9.!SD10./LMSEL + SD7.SD10./LMSEL +
			             !SD8.SD9./LMSEL + !SD7.SD8./LMSEL +
			             /LMSEL./DSEL1 + /LMSEL.TFAD13 + /LMSEL.TFAD12 + /LMSEL.TFAD11
			*/
			else if (LHIEN(m_math.inslatch) || LLOEN(m_math.inslatch))
			{
				uint16_t data;

				kick_sn74s516(&data, ins);

				/* All latches enabled */
				if (LHIEN(m_math.inslatch) && LLOEN(m_math.inslatch))
				{
					m_math.muxlatch = data;
				}
				else if (m_math.mux == TX1_SEL_LMSEL) // O4 = 0
				{
					// TMPLD2/TMPLD3 15-5
					if (LLOEN(m_math.inslatch))
					{
						m_math.muxlatch &= 0x001f;
						m_math.muxlatch |= data & 0xffe0;
					}
					// TMLPD1 4-0???????
					else if (LHIEN(m_math.inslatch))
					{
						m_math.muxlatch &= 0xffe0;
						m_math.muxlatch |= data & 0x001f;
					}
				}
				else
				{
					/*
					    /TMPLD1: /LHIEN
					    /TMPLD2: /LLOEN.!O4 + /LHIEN.O4
					    /TMPLD3: /LLOEN
					     O4: !SD9.!SD10./LMSEL + SD7.SD10./LMSEL +
					         !SD8.SD9./LMSEL + !SD7.SD8./LMSEL +
					         /LMSEL./DSEL1 + /LMSEL.TFAD13 + /LMSEL.TFAD12 + /LMSEL.TFAD11
					*/
					int     dsel = (m_math.inslatch >> 8) & TX1_DSEL;
					int     tfad = (m_math.inslatch & 0x1c00) << 1;
					int     sd   = m_math.ppshift;
					int     o4;

					o4 =
						(!BIT(sd, 9) && !BIT(sd,10)) ||
						( BIT(sd, 7) &&  BIT(sd,10)) ||
						(!BIT(sd, 8) &&  BIT(sd, 9)) ||
						(!BIT(sd, 7) &&  BIT(sd, 8)) ||
						!BIT(dsel, 1) || BIT(tfad, 13) || BIT(tfad, 12) || BIT(tfad, 11);

					if (LLOEN(m_math.inslatch))
					{
						m_math.muxlatch &= 0x0fff;
						m_math.muxlatch |= data & 0xf000;

						if (!o4)
						{
							// TMPLD11-5
							m_math.muxlatch &= 0xf01f;
							m_math.muxlatch |= data & 0x0fe0;
						}
					}
					else if (LHIEN(m_math.inslatch))
					{
						m_math.muxlatch &= 0xffe0;
						m_math.muxlatch |= data & 0x001f;

						if (o4)
						{
							// TMPLD11-5
							m_math.muxlatch &= 0xf01f;
							m_math.muxlatch |= data & 0x0fe0;
						}
					}
				}
			}
			else
			{
				if (m_math.mux == TX1_SEL_PPSEN)
				{
					kick_sn74s516(&m_math.ppshift, ins);
				}
				else
				{
					/* Bus pullups give 0xffff */
					uint16_t data = 0xffff;
					kick_sn74s516(&data, ins);
				}
			}
		}

		/* Is there another instruction in the sequence? */
		if (prom[m_math.promaddr] & 0x8000)
			break;
		else
			INC_PROM_ADDR;
	}
}

uint16_t tx1_state::tx1_math_r(offs_t offset)
{
	offset = offset << 1;

	/* /MLPCS */
	if (offset < 0x400)
	{
		int ins;

		if (offset & 0x200)
		{
			ins = m_math.inslatch & 7;
			TX1_SET_INS0_BIT;
		}
		else
		{
			ins = (offset >> 1) & 7;
		}

		/* TODO What do we return? */
		kick_sn74s516(&m_math.retval, ins);
	}
	/* /PPSEN */
	else if (offset < 0x800)
	{
		// Unused - just pullups?
		m_math.retval = 0xffff;
	}
	/* /MUXCS */
	else if ((offset & 0xc00) == 0xc00)
	{
		int     dsel = (m_math.inslatch >> 8) & TX1_DSEL;
		int     tfad = (m_math.inslatch & 0x1c00) << 1;
		int     sd   = m_math.ppshift;
		int     o4;

		if (m_math.mux == TX1_SEL_LMSEL)
			o4 = 0;
		else
		{
			o4 =
			(!BIT(sd, 9) && !BIT(sd,10)) ||
			( BIT(sd, 7) &&  BIT(sd,10)) ||
			(!BIT(sd, 8) &&  BIT(sd, 9)) ||
			(!BIT(sd, 7) &&  BIT(sd, 8)) ||
			!BIT(dsel, 1) || BIT(tfad, 13) || BIT(tfad, 12) || BIT(tfad, 11);
		}

		dsel = (dsel & 2) | ((dsel & o4) ^ 1);

		if (dsel == 0)
			m_math.retval = m_math.muxlatch;
		else if (dsel == 1 )
		{
			/*
			    TODO make this constant somewhere
			    e.g. m_math.retval =  m_math.romptr[ m_math.get_datarom_addr() ];
			*/
			uint16_t *romdata = (uint16_t*)memregion("au_data")->base();
			uint16_t addr = m_math.get_datarom_addr();
			m_math.retval = romdata[addr];
		}
		else if (dsel == 2)
			m_math.retval = ROL16(m_math.muxlatch, 4);
		else if (dsel == 3)
			m_math.retval = ROL16(SWAP16(m_math.muxlatch), 3);

		/* TODO for TX-1: This is /SPCS region? */
		if (offset < 0xe00)
		{
			// Load the PP with retval??????
			if (m_math.mux == TX1_SEL_PPSEN)
			{
				m_math.ppshift = m_math.retval & 0x3fff;
			}
			else if (m_math.mux == TX1_SEL_PSSEN)
			{
				// WRONG!!!!
				osd_printf_debug("Math Read with PSSEN!\n");
				m_math.ppshift = m_math.retval;
			}

			if (m_math.mux != TX1_SEL_ILDEN)
			{
				INC_PROM_ADDR;
				tx1_update_state();

				// MUST RETURN HERE?
				return m_math.retval;
			}
		}
	}
	else
	{
		if (m_math.mux == TX1_SEL_PPSEN)
			m_math.retval = m_math.ppshift & 0x3fff;
		else
			/* Nothing is mapped - read from pull up resistors! */
			m_math.retval = 0xffff;
	}

	if (offset & TX1_INSLD)
	{
		m_math.promaddr = (offset << 2) & 0x1ff;
		tx1_update_state();
	}
	else if (offset & TX1_CNTST)
	{
		INC_PROM_ADDR;
		tx1_update_state();
	}

	return m_math.retval;
}

void tx1_state::tx1_math_w(offs_t offset, uint16_t data)
{
	m_math.cpulatch = data;
	offset <<= 1;

//  printf("W %x: %x\n", 0x3000 + offset, data);

	/* /MLPCS */
	if (offset < 0x400)
	{
		int ins;

		if (offset & 0x200)
		{
			ins = m_math.inslatch & 7;
			TX1_SET_INS0_BIT;
		}
		else
		{
			ins = (offset >> 1) & 7;
		}

		kick_sn74s516(&m_math.cpulatch, ins);
	}
	/* /PPSEN */
	else if ((offset & 0xc00) == 0x400)
	{
		/* Input is 14 bits */
		m_math.ppshift = m_math.cpulatch & 0x3fff;
	}
	/* /PSSEN */
	else if ((offset & 0xc00) == 0x800)
	{
		//if (((m_math.inslatch >> 8) & TX1_DSEL) == 3 )
		{
			int shift;
			uint16_t val = m_math.ppshift;

			if (m_math.cpulatch & 0x3800)
			{
				shift = (m_math.cpulatch >> 11) & 0x7;

				while (shift)
				{
					val >>= 1;
					shift >>= 1;
				}
			}
			else
			{
				shift = (m_math.cpulatch >> 7) & 0xf;
				shift = reverse_nibble(shift);
				shift >>= 1;

				while (shift)
				{
					val <<= 1;
					shift >>= 1;
				}
			}
			m_math.ppshift = val;
		}
	}
	/* /MUXCS */
	else if ((offset & 0xc00) == 0xc00)
	{
		/*
		    /TMPLD1: 0
		    /TMPLD2: 0
		    /TMPLD3: 0
		*/
		m_math.muxlatch = m_math.cpulatch;
	}

	if (offset & TX1_INSLD)
	{
		m_math.promaddr = (offset << 2) & 0x1ff;
		tx1_update_state();
	}
	else if (offset & TX1_CNTST)
	{
		INC_PROM_ADDR;
		tx1_update_state();
	}
}

uint16_t tx1_state::tx1_spcs_rom_r(offs_t offset)
{
	m_math.cpulatch = *(uint16_t*)((uint8_t*)memregion("math_cpu")->base() + 0x04000 + 0x1000 + offset*2);

	if (m_math.mux == TX1_SEL_ILDEN)
	{
		m_math.i0ff = m_math.cpulatch & (1 << 14) ? 1 : 0;
	}
	else if (m_math.mux == TX1_SEL_MULEN)
	{
		int ins = m_math.inslatch & 7;

		TX1_SET_INS0_BIT;
		kick_sn74s516(&m_math.cpulatch, ins);
	}
	else if (m_math.mux == TX1_SEL_PPSEN)
	{
		m_math.ppshift = m_math.cpulatch;
	}
	else if (m_math.mux == TX1_SEL_PSSEN)
	{
			//if ( ((m_math.inslatch >> 8) & TX1_DSEL) == 3 )
		{
			int shift;
			uint16_t val = m_math.ppshift;

			if (m_math.cpulatch & 0x3800)
			{
				shift = (m_math.cpulatch >> 11) & 0x7;

				while (shift)
				{
					val >>= 1;
					shift >>= 1;
				}
			}
			else
			{
				shift = (m_math.cpulatch >> 7) & 0xf;
				shift = reverse_nibble(shift);
				shift >>= 1;

				while (shift)
				{
					val <<= 1;
					shift >>= 1;
				}
			}
			m_math.ppshift = val & 0x7ff;
		}
	}

	if (m_math.mux != TX1_SEL_ILDEN)
	{
		INC_PROM_ADDR;
		tx1_update_state();
	}

	return m_math.cpulatch;

}

uint16_t tx1_state::tx1_spcs_ram_r(offs_t offset)
{
	m_math.cpulatch = m_math_ram[offset];

	offset <<= 1;

	if (m_math.mux == TX1_SEL_ILDEN)
	{
		m_math.i0ff = m_math.cpulatch & (1 << 14) ? 1 : 0;
	}
	else if (m_math.mux == TX1_SEL_MULEN)
	{
		int ins = m_math.inslatch & 7;

		TX1_SET_INS0_BIT;
		kick_sn74s516(&m_math.cpulatch, ins);
	}
	else if (m_math.mux == TX1_SEL_PPSEN)
	{
//      m_math.ppshift = m_math.retval & 0x3fff;
		m_math.ppshift = m_math.cpulatch;
	}
	else if (m_math.mux == TX1_SEL_PSSEN)
	{
		int shift;
		uint16_t val = m_math.ppshift;

		if (m_math.cpulatch & 0x3800)
		{
			shift = (m_math.cpulatch >> 11) & 0x7;

			while (shift)
			{
				val >>= 1;
				shift >>= 1;
			}
		}
		else
		{
			shift = (m_math.cpulatch >> 7) & 0xf;
			shift = reverse_nibble(shift);
			shift >>= 1;

			while (shift)
			{
				val <<= 1;
				shift >>= 1;
			}
		}
		m_math.ppshift = val & 0x7ff;
	}

	if (m_math.mux != TX1_SEL_ILDEN)
	{
		INC_PROM_ADDR;
		tx1_update_state();
	}

	return m_math.cpulatch;
}

/* Should never occur */
void tx1_state::tx1_spcs_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
	osd_printf_debug("Write to /SPCS RAM?");
	COMBINE_DATA(&m_math_ram[offset]);
}


/***************************************************************************

  Buggy Boy

***************************************************************************/
#define BB_INSLD        0x100
#define BB_CNTST        0x80
#define BB_RADCHG       0x20
#define BB_DSEL         0x03

enum
{
	BB_MUX_MULEN = 0x00,
	BB_MUX_PPSEN,
	BB_MUX_PSSEN,
	BB_MUX_LMSEL,
	BB_MUX_DPROE,
	BB_MUX_PPOE,
	BB_MUX_INSCL,
	BB_MUX_ILDEN
};

#define BB_SET_INS0_BIT do { if (!(ins & 0x4) && m_math.i0ff) ins |= m_math.i0ff;} while(0)

inline uint16_t tx1_state::math_t::get_bb_datarom_addr() const
{
	uint16_t addr = ((inslatch & 0x1c00) << 1) | (ppshift & 0xff);

	if ((inslatch >> 8) & BB_RADCHG)
		addr |= (ppshift & 0x0700);
	else
		addr |= (promaddr << 3) & 0x0700;

	return addr & 0x3fff;
}

void tx1_state::buggyboy_update_state()
{
#define LHIEN(a)    !(a & 0x80)
#define LLOEN(a)    !(a & 0x40)
#define GO_EN(a)    !(a & 0x4000)

	const uint16_t *prom = (uint16_t*)memregion("au_data")->base() + (0x8000 >> 1);

	for (;;)
	{
		int go = 0;

		if (!GO_EN(m_math.inslatch) && GO_EN(prom[m_math.promaddr]))
			go = 1;
		else if ((GO_EN(m_math.inslatch) && GO_EN(prom[m_math.promaddr])) && (LHIEN(m_math.inslatch) && LLOEN(prom[m_math.promaddr])))
			go = 1;

		/* Now update the latch */
		m_math.inslatch = prom[m_math.promaddr] & 0x7fff;
		m_math.mux = (m_math.inslatch >> 3) & 7;

		if (m_math.mux == BB_MUX_INSCL)
			m_math.i0ff = 0;
		else if (m_math.mux == BB_MUX_PPSEN)
		{
			// TODO: Needed?
			//osd_printf_debug("/PPSEN with INS: %x\n", m_math.promaddr);
			//m_math.ppshift = lastval;//m_math.cpulatch;
		}

		/* TODO */
		if (go)
		{
			int ins = m_math.inslatch & 7;

			BB_SET_INS0_BIT;

			if (m_math.mux == BB_MUX_DPROE)
			{
				uint16_t *romdata = (uint16_t*)memregion("au_data")->base();
				uint16_t addr = m_math.get_bb_datarom_addr();
				kick_sn74s516(&romdata[addr], ins);
			}
			else if (m_math.mux == BB_MUX_PPOE)
			{
				kick_sn74s516(&m_math.ppshift, ins);
			}
			/* This is quite tricky. */
			/* It can either be a read operation or */
			/* What if /LHIEN and /LLOEN? */
			else if (LHIEN(m_math.inslatch) || LLOEN(m_math.inslatch))
			{
				uint16_t data;

				kick_sn74s516(&data, ins);

				if (LHIEN(m_math.inslatch) && LLOEN(m_math.inslatch))
				{
					m_math.ppshift = data;
				}
				else if (m_math.mux == BB_MUX_LMSEL)
				{
					if (LLOEN(m_math.inslatch))
					{
						m_math.ppshift &= 0x000f;
						m_math.ppshift |= data & 0xfff0;
					}
					else if (LHIEN(m_math.inslatch))
					{
						m_math.ppshift &= 0xfff0;
						m_math.ppshift |= data & 0x000f;
					}
				}
				else
				{
					if (LLOEN(m_math.inslatch))
					{
						m_math.ppshift &= 0x0fff;
						m_math.ppshift |= data & 0xf000;
					}
					else if (LHIEN(m_math.inslatch))
					{
						m_math.ppshift &= 0xf000;
						m_math.ppshift |= data & 0x0fff;
					}
				}
			}
			else
			{
				if (m_math.mux == BB_MUX_PPSEN)
				{
					kick_sn74s516(&m_math.ppshift, ins);
				}
				else
				{
					/* Bus pullups give 0xffff */
					uint16_t data = 0xffff;
					kick_sn74s516(&data, ins);
				}
			}
		}

		/* Handle rotation */
		if (((m_math.inslatch >> 8) & BB_DSEL) == 1)
		{
			m_math.ppshift = ROR16(m_math.ppshift, 4);
		}
		else if (((m_math.inslatch >> 8) & BB_DSEL) == 2)
		{
			m_math.ppshift = ROL16(m_math.ppshift, 4);
		}

		/* Is there another instruction in the sequence? */
		if (prom[m_math.promaddr] & 0x8000)
			break;
		else
			INC_PROM_ADDR;
	}
}

uint16_t tx1_state::buggyboy_math_r(offs_t offset)
{
	offset = offset << 1;

	/* /MLPCS */
	if (offset < 0x400)
	{
		int ins;

		if (offset & 0x200)
		{
			ins = m_math.inslatch & 7;
			BB_SET_INS0_BIT;
		}
		else
		{
			ins = (offset >> 1) & 7;
		}

		/* TODO What do we return? */
		kick_sn74s516(&m_math.retval, ins);

		/* TODO */
		//if (m_math.mux == BB_MUX_PPSEN)
		//  m_math.ppshift = m_math.retval;
	}
	/* /PPSEN */
	else if (offset < 0x800)
	{
		m_math.retval = m_math.ppshift;
	}
	/* /DPROE */
	else if ((offset & 0xc00) == 0xc00)
	{
		uint16_t *romdata = (uint16_t*)memregion("au_data")->base();
		uint16_t addr = m_math.get_bb_datarom_addr();

		m_math.retval = romdata[addr];

		/* This is necessary */
		if (m_math.mux == BB_MUX_PPSEN)
			m_math.ppshift = romdata[addr];

		/* This is /SPCS region? Necessary anyway */
		if (offset < 0xe00)
		{
			if (m_math.mux != BB_MUX_ILDEN)
			{
				INC_PROM_ADDR;
				buggyboy_update_state();
			}
		}
	}
	else
	{
		if (m_math.mux == BB_MUX_PPSEN)
			m_math.retval = m_math.ppshift;
		else
			/* Nothing is mapped - read from pull up resistors! */
			m_math.retval = 0xffff;
	}

	if (offset & BB_INSLD)
	{
		m_math.promaddr = (offset << 2) & 0x1ff;
		buggyboy_update_state();
	}
	else if (offset & BB_CNTST)
	{
		INC_PROM_ADDR;
		buggyboy_update_state();
	}

	return m_math.retval;
}

void tx1_state::buggyboy_math_w(offs_t offset, uint16_t data)
{
	m_math.cpulatch = data;

	offset <<= 1;

	/* /MLPCS */
	if (offset < 0x400)
	{
		int ins;

		if (offset & 0x200)
		{
			ins = m_math.inslatch & 7;
			BB_SET_INS0_BIT;
		}
		else
		{
			ins = (offset >> 1) & 7;
		}

		kick_sn74s516(&m_math.cpulatch, ins);
	}
	/* /PPSEN */
	else if ((offset & 0xc00) == 0x400)
	{
		m_math.ppshift = m_math.cpulatch;
	}
	/* /PSSEN */
	else if ((offset & 0xc00) == 0x800)
	{
		if (((m_math.inslatch >> 8) & BB_DSEL) == 3)
		{
			int shift;
			uint16_t val = m_math.ppshift;

			if (m_math.cpulatch & 0x3800)
			{
				shift = (m_math.cpulatch >> 11) & 0x7;

				while (shift)
				{
					val = ROR16(val, 1);
					shift >>= 1;
				}
			}
			else
			{
				shift = (m_math.cpulatch >> 7) & 0xf;
				shift = reverse_nibble(shift);
				shift >>= 1;

				while (shift)
				{
					val = ROL16(val, 1);
					shift >>= 1;
				}
			}
			m_math.ppshift = val;
		}
		else
		{
			osd_printf_debug("BB_DSEL was not 3 for P->S load!\n");
			machine().debug_break();
		}
	}
	else
	{
		osd_printf_debug("Buggy Boy unknown math state!\n");
		machine().debug_break();
	}

	if (offset & BB_INSLD)
	{
		m_math.promaddr = (offset << 2) & 0x1ff;
		buggyboy_update_state();
	}
	else if (offset & BB_CNTST)
	{
		INC_PROM_ADDR;
		buggyboy_update_state();
	}
}

/*
    This is for ROM range 0x5000-0x7fff
*/
uint16_t tx1_state::buggyboy_spcs_rom_r(offs_t offset)
{
	m_math.cpulatch = *(uint16_t*)((uint8_t*)memregion("math_cpu")->base() + 0x04000 + 0x1000 + offset*2);

	if (m_math.mux == BB_MUX_ILDEN)
	{
		m_math.i0ff = m_math.cpulatch & (1 << 14) ? 1 : 0;
	}
	else if (m_math.mux == BB_MUX_MULEN)
	{
		int ins = m_math.inslatch & 7;

		BB_SET_INS0_BIT;
		kick_sn74s516(&m_math.cpulatch, ins);
	}
	else if (m_math.mux == BB_MUX_PPSEN)
	{
		m_math.ppshift = m_math.cpulatch;
	}
	else if (m_math.mux == BB_MUX_PSSEN)
	{
		if (((m_math.inslatch >> 8) & BB_DSEL) == 3)
		{
			int shift;
			uint16_t val = m_math.ppshift;

			if (m_math.cpulatch & 0x3800)
			{
				shift = (m_math.cpulatch >> 11) & 0x7;

				while (shift)
				{
					val = ROR16(val, 1);
					shift >>= 1;
				}
			}
			else
			{
				shift = (m_math.cpulatch >> 7) & 0xf;
				shift = reverse_nibble(shift);
				shift >>= 1;

				while (shift)
				{
					val = ROL16(val, 1);
					shift >>= 1;
				}
			}
			m_math.ppshift = val;
		}
	}

	if (m_math.mux != BB_MUX_ILDEN)
	{
		INC_PROM_ADDR;
		buggyboy_update_state();
	}

	return m_math.cpulatch;
}

void tx1_state::buggyboy_spcs_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
	COMBINE_DATA(&m_math_ram[offset]);
}

uint16_t tx1_state::buggyboy_spcs_ram_r(offs_t offset)
{
	m_math.cpulatch = m_math_ram[offset];

	offset <<= 1;

	if (m_math.mux == BB_MUX_ILDEN)
	{
		m_math.i0ff = m_math.cpulatch & (1 << 14) ? 1 : 0;
	}
	else if (m_math.mux == BB_MUX_MULEN)
	{
		int ins = m_math.inslatch & 7;

		BB_SET_INS0_BIT;
		kick_sn74s516(&m_math.cpulatch, ins);
	}
	else if (m_math.mux == BB_MUX_PPSEN)
	{
		m_math.ppshift = m_math.cpulatch;
	}
	else if (m_math.mux == BB_MUX_PSSEN)
	{
		if (((m_math.inslatch >> 8) & BB_DSEL) == 3)
		{
			int shift;
			uint16_t val = m_math.ppshift;

			if (m_math.cpulatch & 0x3800)
			{
				shift = (m_math.cpulatch >> 11) & 0x7;

				while (shift)
				{
					val = ROR16(val, 1);
					shift >>= 1;
				}
			}
			else
			{
				shift = (m_math.cpulatch >> 7) & 0xf;
				shift = reverse_nibble(shift);
				shift >>= 1;

				while (shift)
				{
					val = ROL16(val, 1);
					shift >>= 1;
				}
			}
			m_math.ppshift = val;
		}
	}

	if (m_math.mux != BB_MUX_ILDEN)
	{
		INC_PROM_ADDR;
		buggyboy_update_state();
	}

	return m_math.cpulatch;
}



/*************************************
 *
 *  Machine Reset
 *
 *************************************/

MACHINE_RESET_MEMBER(tx1_state,buggyboy)
{
	// TODO: This is connected to the /BUSACK line of the Z80
	m_maincpu->set_input_line(INPUT_LINE_TEST, ASSERT_LINE);

	memset(&m_math, 0, sizeof(m_math));
}

MACHINE_RESET_MEMBER(tx1_state,tx1)
{
	// TODO: This is connected to the /BUSACK line of the Z80
	m_maincpu->set_input_line(INPUT_LINE_TEST, ASSERT_LINE);

	memset(&m_math, 0, sizeof(m_math));
}