summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/namco51.cpp
blob: 2cd77ab69b5bc902ad061e0a87209e128955bb5b (plain) (tree)
1
2
3
4

                                

                                                                            


















































                                                                                    


                                                                            
                
                    





                                                        

                                                            
 
                                         
 

                     
                                                                                
 
                            
         
                                          
                 



                                                                  





                             
                                      

                                      
                                              
                                                    
                                                                                      
                                              


                                                                                  
                                                                                                


                                                                                                   
                                                                                       
                                         
                                                                                          








                                                                                                            

                                                                    



                                         
                                                                                

                                               

                                      
                                                             
                                                

                                      
                                                            
                                                

                                      
                                                      

                                               


























                                                                                         
                                                                                      

 
                                       
 
                                                                     
 
                                          
         
                                           

                                

                                                                          
                                                       

                 
                                  
         
                                           

                                
                                                                  


                                                      


                                                                                   
 
                                                                    
                                         
                                                                    
                                                 
                                                                                         


                                                    
                                                                                         


                                                                                               



                                                                                                      
                                                                 

                                                                                                          



                                                                               



                                                                                                      
                                                                 

                                                                                                          



                                                                               
                                                                            


                                                         
                                                                             
 
                                                        
                                         
                                                                                                                
 



                                                                                              
                                                    
                                                                                          



                                                                                     
                                                                           
                                                         


                                                                                                  




                                                                                      
                                                                           
                                                         


                                                                                                  




                                                         
                                                                                          

                                                    
                                                                              


                                 
                                                                      

                                                      


                                                                                       

                                                            
                                                                            









                                                                             
                                                                      

                                                      


                                                                                       

                                                            
                                                                            


















                                                                             
                                                                          



                                                               


               
                                            
                                                                                                       

                                          
                  


                       
                                     


                                                                                                                


                                                                                                                   






                                                                                              





                           
 

 
                                                   




                                                   



















                                          







                                                   








                                      




















                                                                              
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    Namco 51XX

    This custom chip is a Fujitsu MB8843 MCU programmed to act as an I/O
    device with built-in coin management. It is also apparently used as a
    protection device. It keeps track of the players scores, and checks
    if a high score has been obtained or bonus lives should be awarded.
    The main CPU has a range of commands to increment/decrement the score
    by various fixed amounts.

    The device is used to its full potential only by Bosconian; Xevious
    uses it too, but only to do a protection check on startup.

    CMD = command from main CPU
    ANS = answer to main CPU

    The chip reads/writes the I/O ports when the /IRQ is pulled down.
    Pin 21 determines whether a read or write should happen (1=R, 0=W).

               +------+
             EX|1   42|Vcc
              X|2   41|K3
         /RESET|3   40|K2
           /IRQ|4   39|K1
             SO|5   38|K0
             SI|6   37|R15
        /SC /TO|7   36|R14
            /TC|8   35|R13
             P0|9   34|R12
             P1|10  33|R11
             P2|11  32|R10
             P3|12  31|R9
             O0|13  30|R8
             O1|14  29|R7
             O2|15  28|R6
             O3|16  27|R5
             O4|17  26|R4
             O5|18  25|R3
             O6|19  24|R2
             O7|20  23|R1
            GND|21  22|R0
               +------+

    commands:
    00: nop
    01 + 4 arguments: set coinage (xevious, possibly because of a bug, is different)
    02: go in "credit" mode and enable start buttons
    03: disable joystick remapping
    04: enable joystick remapping
    05: go in "switch" mode
    06: nop
    07: nop

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

#include "emu.h"
#include "namco51.h"


#define VERBOSE 0
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)


#define READ_PORT(num)           m_in_##num(space, 0)
#define WRITE_PORT(num,data)     m_out_##num(space, 0, data)

WRITE8_MEMBER( namco_51xx_device::write )
{
	data &= 0x07;

	LOG(("%s: custom 51XX write %02x\n",machine().describe_context(),data));

	if (m_coincred_mode)
	{
		switch (m_coincred_mode--)
		{
			case 4: m_coins_per_cred[0] = data; break;
			case 3: m_creds_per_coin[0] = data; break;
			case 2: m_coins_per_cred[1] = data; break;
			case 1: m_creds_per_coin[1] = data; break;
		}
	}
	else
	{
		switch (data)
		{
			case 0: // nop
				break;

			case 1: // set coinage
				m_coincred_mode = 4;
				/* this is a good time to reset the credits counter */
				m_credits = 0;

				{
					/* kludge for a possible bug in Xevious */
					static const game_driver *namcoio_51XX_driver = nullptr;
					static int namcoio_51XX_kludge = 0;

					/* Only compute namcoio_51XX_kludge when gamedrv changes */
					if (namcoio_51XX_driver != &machine().system())
					{
						namcoio_51XX_driver = &machine().system();
						if (strcmp(namcoio_51XX_driver->name, "xevious") == 0 ||
							strcmp(namcoio_51XX_driver->parent, "xevious") == 0)
							namcoio_51XX_kludge = 1;
						else
							namcoio_51XX_kludge = 0;
					}

					if (namcoio_51XX_kludge)
					{
						m_coincred_mode = 6;
						m_remap_joy = 1;
					}
				}
				break;

			case 2: // go in "credits" mode and enable start buttons
				m_mode = 1;
				m_in_count = 0;
				break;

			case 3: // disable joystick remapping
				m_remap_joy = 0;
				break;

			case 4: // enable joystick remapping
				m_remap_joy = 1;
				break;

			case 5: // go in "switch" mode
				m_mode = 0;
				m_in_count = 0;
				break;

			default:
				logerror("unknown 51XX command %02x\n",data);
				break;
		}
	}
}


/* joystick input mapping

  The joystick is parsed and a number corresponding to the direction is returned,
  according to the following table:

          0
        7   1
      6   8   2
        5   3
          4

  The values for directions impossible to obtain on a joystick have not been
  verified on Namco original hardware, but they are the same in all the bootlegs,
  so we can assume they are right.
*/
static const int joy_map[16] =
/*  LDRU, LDR, LDU,  LD, LRU, LR,  LU,    L, DRU,  DR,  DU,   D,  RU,   R,   U, center */
{    0xf, 0xe, 0xd, 0x5, 0xc, 0x9, 0x7, 0x6, 0xb, 0x3, 0xa, 0x4, 0x1, 0x2, 0x0, 0x8 };


READ8_MEMBER( namco_51xx_device::read )
{
	LOG(("%s: custom 51XX read\n",machine().describe_context()));

	if (m_mode == 0) /* switch mode */
	{
		switch ((m_in_count++) % 3)
		{
			default:
			case 0: return READ_PORT(0) | (READ_PORT(1) << 4);
			case 1: return READ_PORT(2) | (READ_PORT(3) << 4);
			case 2: return 0;   // nothing?
		}
	}
	else    /* credits mode */
	{
		switch ((m_in_count++) % 3)
		{
			default:
			case 0: // number of credits in BCD format
				{
					int in,toggle;

					in = ~(READ_PORT(0) | (READ_PORT(1) << 4));
					toggle = in ^ m_lastcoins;
					m_lastcoins = in;

					if (m_coins_per_cred[0] > 0)
					{
						if (m_credits >= 99)
						{
							WRITE_PORT(1,1);  // coin lockout
						}
						else
						{
							WRITE_PORT(1,0);  // coin lockout
							/* check if the user inserted a coin */
							if (toggle & in & 0x10)
							{
								m_coins[0]++;
								WRITE_PORT(0,0x04);   // coin counter
								WRITE_PORT(0,0x0c);
								if (m_coins[0] >= m_coins_per_cred[0])
								{
									m_credits += m_creds_per_coin[0];
									m_coins[0] -= m_coins_per_cred[0];
								}
							}
							if (toggle & in & 0x20)
							{
								m_coins[1]++;
								WRITE_PORT(0,0x08);   // coin counter
								WRITE_PORT(0,0x0c);
								if (m_coins[1] >= m_coins_per_cred[1])
								{
									m_credits += m_creds_per_coin[1];
									m_coins[1] -= m_coins_per_cred[1];
								}
							}
							if (toggle & in & 0x40)
							{
								m_credits++;
							}
						}
					}
					else m_credits = 100;    // free play

					if (m_mode == 1)
					{
						int on = (machine().first_screen()->frame_number() & 0x10) >> 4;

						if (m_credits >= 2)
							WRITE_PORT(0,0x0c | 3*on);    // lamps
						else if (m_credits >= 1)
							WRITE_PORT(0,0x0c | 2*on);    // lamps
						else
							WRITE_PORT(0,0x0c);   // lamps off

						/* check for 1 player start button */
						if (toggle & in & 0x04)
						{
							if (m_credits >= 1)
							{
								m_credits--;
								m_mode = 2;
								WRITE_PORT(0,0x0c);   // lamps off
							}
						}
						/* check for 2 players start button */
						else if (toggle & in & 0x08)
						{
							if (m_credits >= 2)
							{
								m_credits -= 2;
								m_mode = 2;
								WRITE_PORT( 0,0x0c);  // lamps off
							}
						}
					}
				}

				if (~READ_PORT( 1) & 0x08)    /* check test mode switch */
					return 0xbb;

				return (m_credits / 10) * 16 + m_credits % 10;

			case 1:
				{
					int joy = READ_PORT(2) & 0x0f;
					int in,toggle;

					in = ~READ_PORT(0);
					toggle = in ^ m_lastbuttons;
					m_lastbuttons = (m_lastbuttons & 2) | (in & 1);

					/* remap joystick */
					if (m_remap_joy) joy = joy_map[joy];

					/* fire */
					joy |= ((toggle & in & 0x01)^1) << 4;
					joy |= ((in & 0x01)^1) << 5;

					return joy;
				}

			case 2:
				{
					int joy = READ_PORT(3) & 0x0f;
					int in,toggle;

					in = ~READ_PORT(0);
					toggle = in ^ m_lastbuttons;
					m_lastbuttons = (m_lastbuttons & 1) | (in & 2);

					/* remap joystick */
					if (m_remap_joy) joy = joy_map[joy];

					/* fire */
					joy |= ((toggle & in & 0x02)^2) << 3;
					joy |= ((in & 0x02)^2) << 4;

					return joy;
				}
		}
	}
}





/***************************************************************************
    DEVICE INTERFACE
***************************************************************************/

static ADDRESS_MAP_START( namco_51xx_map_io, AS_IO, 8, namco_51xx_device )
//  AM_RANGE(MB88_PORTK,  MB88_PORTK)  AM_READ(namco_51xx_K_r)
//  AM_RANGE(MB88_PORTO,  MB88_PORTO)  AM_WRITE(namco_51xx_O_w)
//  AM_RANGE(MB88_PORTR0, MB88_PORTR0) AM_READ(namco_51xx_R0_r)
//  AM_RANGE(MB88_PORTR2, MB88_PORTR2) AM_READ(namco_51xx_R2_r)
ADDRESS_MAP_END


static MACHINE_CONFIG_FRAGMENT( namco_51xx )
	MCFG_CPU_ADD("mcu", MB8843, DERIVED_CLOCK(1,1))     /* parent clock, internally divided by 6 */
	MCFG_CPU_IO_MAP(namco_51xx_map_io)
	MCFG_DEVICE_DISABLE()
MACHINE_CONFIG_END


ROM_START( namco_51xx )
	ROM_REGION( 0x400, "mcu", 0 )
	ROM_LOAD( "51xx.bin",     0x0000, 0x0400, CRC(c2f57ef8) SHA1(50de79e0d6a76bda95ffb02fcce369a79e6abfec) )
ROM_END

const device_type NAMCO_51XX = &device_creator<namco_51xx_device>;

namco_51xx_device::namco_51xx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
	: device_t(mconfig, NAMCO_51XX, "Namco 51xx", tag, owner, clock, "namco51", __FILE__),
	m_cpu(*this, "mcu"),
	m_in_0(*this),
	m_in_1(*this),
	m_in_2(*this),
	m_in_3(*this),
	m_out_0(*this),
	m_out_1(*this),
	m_lastcoins(0),
	m_lastbuttons(0),
	m_mode(0),
	m_coincred_mode(0),
	m_remap_joy(0)
{
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void namco_51xx_device::device_start()
{
	/* resolve our read callbacks */
	m_in_0.resolve_safe(0);
	m_in_1.resolve_safe(0);
	m_in_2.resolve_safe(0);
	m_in_3.resolve_safe(0);

	/* resolve our write callbacks */
	m_out_0.resolve_safe();
	m_out_1.resolve_safe();

	save_item(NAME(m_lastcoins));
	save_item(NAME(m_lastbuttons));
	save_item(NAME(m_credits));
	save_item(NAME(m_coins));
	save_item(NAME(m_coins_per_cred));
	save_item(NAME(m_creds_per_coin));
	save_item(NAME(m_in_count));
	save_item(NAME(m_mode));
	save_item(NAME(m_coincred_mode));
	save_item(NAME(m_remap_joy));
}

//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void namco_51xx_device::device_reset()
{
	/* reset internal registers */
	m_credits = 0;
	m_coins[0] = 0;
	m_coins_per_cred[0] = 1;
	m_creds_per_coin[0] = 1;
	m_coins[1] = 0;
	m_coins_per_cred[1] = 1;
	m_creds_per_coin[1] = 1;
	m_in_count = 0;
}

//-------------------------------------------------
//  device_mconfig_additions - return a pointer to
//  the device's machine fragment
//-------------------------------------------------

machine_config_constructor namco_51xx_device::device_mconfig_additions() const
{
	return MACHINE_CONFIG_NAME( namco_51xx  );
}

//-------------------------------------------------
//  device_rom_region - return a pointer to the
//  the device's ROM definitions
//-------------------------------------------------

const rom_entry *namco_51xx_device::device_rom_region() const
{
	return ROM_NAME(namco_51xx );
}