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

                                              
                
                              
 



                          




                                       
 
                                    
 
                              
 

                                
 
                                                

                                                          

                                                                              

                                     



                              
 
                                        

 
                                    
 

                               
                                                                              


                                                                                
                                                       
 

                                                                                                                                                                                       
 
                              

                                                
 
                                                               
                             
                                                                            

 
                                                    
 
                                                                              


                                                                                
                                                       

                           
                                                     
 

                                                                                                                                                                                        






                                       
 
                                                      
 
                                      

 
                                         

          




                                                              
                             

 
                                               
 
                              

 
                                              
 
                                 

 
                                               



                                                     
                                               
 
                                  

 
                                           
 
                              

 
                                              
 
                  
                               

 
                                              
 
                              



                 
                                         
 
                          







                                       
 
                                         



                                                               
                            
         

                                                                         



                    
                                          

                                                               
                            
         


                                                             








                                       
 
                                         

                                                                  
                     


                                 

                                                

                                             
                         

                                               
                                          


         
                                        
 
                                         

                   
                               







                                                                                               
                                        
 
                                         

                   
                               

                              
                                  
         


                                                   




                                                       
                                                   

                                                                                     

                                                                         




                                                        
                                  
                 
                                                  








                                                                                               





                                       
                                        

                                            
                                                 

 
                                       

                                            
                                                 
 
 
                                         

                                
                                      
         
                                                            


         
                                        

                                
                                                    

 
                                                       



                            
                                                                                                   

                             
                                                                                                           

                             



                                                        

                             



                                                        


                             



                                                        











                      
                                                                                       









                                                                                         
 
                                         



                                                     
 

                                   

                                                                                       


         
                                                                                  










                                                                                         
 

                                   
                                                   
                                                                                                            

         





                                       
 
                                    
 
                         
 
                                           
                                  

                               
                                      









                                                                                    
                                  

                         
                        
 
                                                                                           
                         
 
                                  
                                  




                          
                                  

                         
                        

                             
                                      



                                         
 
                                                



                                                   
                                 

                          
                        
         
                                                        








                                             
                                  
         


                                                   


                                   
                                   

                                 
                                      

                                             
                            
                 
                                                               


                                                       


                                                                           
 
                                                                    



















                                                                                     
                                                                       


                                 
                                                                           
                                           
                                                                                                            
                                    
                                                                                                                 


                                                                          
                                           
                                 
                                                   
                                                                                                                    
                                            
                                                                                                          
                                 

                              
                                                     
                                 
                                                                                                
                                                                                 
 
                                                     

                                                                
                                                                                                     



                                                                
                                                              

                                                                 
                                                                                                             



                                                                  
                                                                                                             








                                                                                    

                                            
                                                   
 
                                                    

 
                                    

                                                               
                                                                                                                                             

                         
                        

                                    
                                      

                                                                                           
                         


                                                                                    

                                                           
                                                  
 
                                                         
                                                 
 
                                                        

 
                                    
 
                                                 
 

                                                                  
                                                     

                                               
                                                                                                                                            

                         
                        
 
                           
                                                     
 
                                    
                                      
                          
                                      


                                                                                    

                                 
                                                   
 
                                                           

 
                                    

                                                
                                                                                                                                             
 
                                                                                           
                         
 
                         
                        


                                                                                    

                               
                                    
 
                                                 
 

                                                                  
                                                     
 
                               

                                                 
                                                                                                                                          
 
 
                         
                        
                           
                                                     
                          
                                      



                                            
                                      

                                      
                                                                 

                         
                        

                           
                                                     
                          
                                      


                                                                                    


                                                             
                                                  
 
                                                                       
         

                                                                
         
                                                                            
         

                                                                
         
                                                                            
         

                                                                
         
                                                                            
         

                                                                


         
                                                  

                                              
                                


                                                      
                                                                                  
                                                                         
                                                                                



                                                  

                                                         
                                                                      


                                                  

                                                         
                                                                      


                                                  

                                                         
                                                                      


                                                  

                                                         
                                                                      


                                            
                                                                                     




                      
                                    
 
                                                 

                                                                                           
                         
 

                                                                  
                                                     

                                           
                                                                                                                                            

                                
                                                                                                   

                                  
                                                                 

                         
                        


                                                                                    

                                                 
                                    
 

                                                  

                                                                                           
                         
 

                                                                  
                                                     
 
                                                         

                                                 
                                                                                                                                          

                         
                        



                                                   
                                      

                                      
                                                                 
 
                         
 
                         
                        


                                                                                    

                                         
 
                                                                                
 
                                                               
         


                                                        
                    
                                      
 
                                                                                                                                                                                                                     
                 
                                                                



                 
                                                  

                                                   
 
                                

                            
                                                
 
                                                                

                                         
                                                                         

                                                     
                                                            

                                                       
                                                                                    
 

                                                                                     



                                                      
                                                                                    
 

                                                                                     


                                              
                                                                            
                                                                          
 
                                                                 




                            
                                                                      
                                                                          

                                         
                                            
                                 
                                                                  

                                                                  
                                                                   
                                                                                         






                                                                  
                                                                                         


                                                                     
                                         
                                                                                         
                                                                            

                                                                       

                                                                                                      
 

                                                                                                     



                                                                      

                                                                                                      
 

                                                                                                     
                                                 
                                         




                                                                      
                                                                                                 

                                                                                                    
 
                                                                                                  






                                                 
                                              
                         
                                                
                                                                            
                                    
                                                                                                           







                                                           
                                                 


                                                 
                                        


                                               
                                         


                                              
                                         



                      
                                    
 
                                                 
                         
 

                                                                  

                                                     

                                                  
                                                                                                                                            

                                      
                                                                 
 






                                            

                         
                        
 
                                                                                                                       

 
                                          
 
                         
                         
                        

                                    
                             


                                                                                    

                                                    
                                                  

                            
                                                 
 
                        
                                                    
            
                                                   
 
                                                                     

 
                                    
 
                                                 
 

                                                                  
                                                     

                                               
                                                                                                                                            

                         
                        

                           
                                                     
                          
                                      


                                                                                    

                            
                                                  
 
                                


                            
                                                                      
                                                                          
 
                                            
                                 
                                                                  

                                                                  

                                                                   
                                                 
                                                                                            


                                                    
                                                                                                 







                                                                  
                                                                
                                                 
                                                                                            


                                                    
                                                                                                 




                                                 
                                               
 

 
                                    
 
                                                 

                                                     

                                               
                                                                                                                                            

                                      
                                                                 
 





                                      

                         
                        
 
                                                                                                                       


                                                                                    

                                     
                                    
 
                                                 
 

                                                                  
                                                     
 
                               

                                      
                                                                 

                                               
                                                                                                                                          

                         
                        

                           
                                                     
                          
                                      
 
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi,Brad Oliver
#include "emu.h"
#include "includes/playch10.h"

#include "machine/nvram.h"
#include "video/ppu2c0x.h"


/*************************************
 *
 *  Init machine
 *
 *************************************/

void playch10_state::machine_reset()
{
	m_pc10_int_detect = 0;

	m_pc10_game_mode = 0;
	m_pc10_dispmask_old = 0;

	m_input_latch[0] = m_input_latch[1] = 0;

	/* variables used only in MMC2 game (mapper 9)  */
	m_MMC2_bank[0] = m_MMC2_bank[1] = m_MMC2_bank[2] = m_MMC2_bank[3] = 0;
	m_MMC2_bank_latch[0] = m_MMC2_bank_latch[1] = 0xfe;

	/* reset the security chip */
	m_rp5h01->enable_w(1);
	m_rp5h01->enable_w(0);
	m_rp5h01->reset_w(0);
	m_rp5h01->reset_w(1);

	pc10_set_mirroring(m_mirroring);
}

void playch10_state::machine_start()
{
	m_timedigits.resolve();

	m_vrom = (m_vrom_region != nullptr) ? m_vrom_region->base() : nullptr;

	/* allocate 4K of nametable ram here */
	/* move to individual boards as documentation of actual boards allows */
	m_nt_ram = std::make_unique<uint8_t[]>(0x1000);

	m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(playch10_state::pc10_chr_r),this), write8_delegate(FUNC(playch10_state::pc10_chr_w),this));
	m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(playch10_state::pc10_nt_r),this),write8_delegate(FUNC(playch10_state::pc10_nt_w),this));

	if (nullptr != m_vram)
		set_videoram_bank(0, 8, 0, 8);
	else pc10_set_videorom_bank(0, 8, 0, 8);

	nvram_device *nvram = subdevice<nvram_device>("nvram");
	if (nvram != nullptr)
		nvram->set_base(memregion("cart")->base() + 0x6000, 0x1000);
}

MACHINE_START_MEMBER(playch10_state,playch10_hboard)
{
	m_vrom = (m_vrom_region != nullptr) ? m_vrom_region->base() : nullptr;

	/* allocate 4K of nametable ram here */
	/* move to individual boards as documentation of actual boards allows */
	m_nt_ram = std::make_unique<uint8_t[]>(0x1000);
	/* allocate vram */

	m_vram = std::make_unique<uint8_t[]>(0x2000);

	m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(playch10_state::pc10_chr_r),this), write8_delegate(FUNC(playch10_state::pc10_chr_w),this));
	m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(playch10_state::pc10_nt_r),this), write8_delegate(FUNC(playch10_state::pc10_nt_w),this));
}

/*************************************
 *
 *  BIOS ports handling
 *
 *************************************/

CUSTOM_INPUT_MEMBER(playch10_state::pc10_int_detect_r)
{
	return ~m_pc10_int_detect & 1;
}

WRITE_LINE_MEMBER(playch10_state::sdcs_w)
{
	/*
	    Hooked to CLR on LS194A - Sheet 2, bottom left.
	    Drives character and color code to 0.
	    It's used to keep the screen black during redraws.
	    Also hooked to the video sram. Prevent writes.
	*/
	m_pc10_sdcs = !state;
}

WRITE_LINE_MEMBER(playch10_state::cntrl_mask_w)
{
	m_cntrl_mask = !state;
}

WRITE_LINE_MEMBER(playch10_state::disp_mask_w)
{
	m_pc10_dispmask = !state;
}

WRITE_LINE_MEMBER(playch10_state::sound_mask_w)
{
	/* should mute the APU - unimplemented yet */
}

WRITE_LINE_MEMBER(playch10_state::nmi_enable_w)
{
	m_pc10_nmi_enable = state;
}

WRITE_LINE_MEMBER(playch10_state::dog_di_w)
{
	m_pc10_dog_di = state;
}

WRITE_LINE_MEMBER(playch10_state::ppu_reset_w)
{
	if (state)
		m_ppu->reset();
}

READ8_MEMBER(playch10_state::pc10_detectclr_r)
{
	m_pc10_int_detect = 0;

	return 0;
}

WRITE8_MEMBER(playch10_state::cart_sel_w)
{
	m_cart_sel = data;
}


/*************************************
 *
 *  RP5H01 handling
 *
 *************************************/

READ8_MEMBER(playch10_state::pc10_prot_r)
{
	int data = 0xe7;

	/* we only support a single cart connected at slot 0 */
	if (m_cart_sel == 0)
	{
		data |= ((~m_rp5h01->counter_r()) << 4) & 0x10;  /* D4 */
		data |= (m_rp5h01->data_r() << 3) & 0x08;        /* D3 */
	}
	return data;
}

WRITE8_MEMBER(playch10_state::pc10_prot_w)
{
	/* we only support a single cart connected at slot 0 */
	if (m_cart_sel == 0)
	{
		m_rp5h01->test_w(data & 0x10);       /* D4 */
		m_rp5h01->clock_w(data & 0x08);      /* D3 */
		m_rp5h01->reset_w(~data & 0x01);     /* D0 */
	}
}


/*************************************
 *
 *  Input Ports
 *
 *************************************/

WRITE8_MEMBER(playch10_state::pc10_in0_w)
{
	/* Toggling bit 0 high then low resets both controllers */
	if (data & 1)
		return;

	/* load up the latches */
	m_input_latch[0] = ioport("P1")->read();
	m_input_latch[1] = ioport("P2")->read();

	/* apply any masking from the BIOS */
	if (m_cntrl_mask)
	{
		/* mask out select and start */
		m_input_latch[0] &= ~0x0c;
	}
}

READ8_MEMBER(playch10_state::pc10_in0_r)
{
	int ret = (m_input_latch[0]) & 1;

	/* shift */
	m_input_latch[0] >>= 1;

	/* some games expect bit 6 to be set because the last entry on the data bus shows up */
	/* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */
	ret |= 0x40;

	return ret;
}

READ8_MEMBER(playch10_state::pc10_in1_r)
{
	int ret = (m_input_latch[1]) & 1;

	/* shift */
	m_input_latch[1] >>= 1;

	/* do the gun thing */
	if (m_pc10_gun_controller)
	{
		int trigger = ioport("P1")->read();
		int x = ioport("GUNX")->read();
		int y = ioport("GUNY")->read();

		/* no sprite hit (yet) */
		ret |= 0x08;

		/* get the pixel at the gun position */
		rgb_t pix = m_ppu->get_pixel(x, y);

		/* look at the screen and see if the cursor is over a bright pixel */
		// FIXME: still a gross hack
		if (pix.r() == 0xff && pix.b() == 0xff && pix.g() > 0x90)
		{
			ret &= ~0x08; /* sprite hit */
		}

		/* now, add the trigger if not masked */
		if (!m_cntrl_mask)
		{
			ret |= (trigger & 2) << 3;
		}
	}

	/* some games expect bit 6 to be set because the last entry on the data bus shows up */
	/* in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. */
	ret |= 0x40;

	return ret;
}
/*************************************
 *
 *  PPU External bus handlers
 *
 *************************************/

WRITE8_MEMBER(playch10_state::pc10_nt_w)
{
	int page = ((offset & 0xc00) >> 10);
	m_nametable[page][offset & 0x3ff] = data;
}

READ8_MEMBER(playch10_state::pc10_nt_r)
{
	int page = ((offset & 0xc00) >> 10);
	return m_nametable[page][offset & 0x3ff];
}

WRITE8_MEMBER(playch10_state::pc10_chr_w)
{
	int bank = offset >> 10;
	if (m_chr_page[bank].writable)
	{
		m_chr_page[bank].chr[offset & 0x3ff] = data;
	}
}

READ8_MEMBER(playch10_state::pc10_chr_r)
{
	int bank = offset >> 10;
	return m_chr_page[bank].chr[offset & 0x3ff];
}

void playch10_state::pc10_set_mirroring(int mirroring )
{
	switch (mirroring)
	{
	case PPU_MIRROR_LOW:
		m_nametable[0] = m_nametable[1] = m_nametable[2] = m_nametable[3] = m_nt_ram.get();
		break;
	case PPU_MIRROR_HIGH:
		m_nametable[0] = m_nametable[1] = m_nametable[2] = m_nametable[3] = m_nt_ram.get() + 0x400;
		break;
	case PPU_MIRROR_HORZ:
		m_nametable[0] = m_nt_ram.get();
		m_nametable[1] = m_nt_ram.get();
		m_nametable[2] = m_nt_ram.get() + 0x400;
		m_nametable[3] = m_nt_ram.get() + 0x400;
		break;
	case PPU_MIRROR_VERT:
		m_nametable[0] = m_nt_ram.get();
		m_nametable[1] = m_nt_ram.get() + 0x400;
		m_nametable[2] = m_nt_ram.get();
		m_nametable[3] = m_nt_ram.get()+ 0x400;
		break;
	case PPU_MIRROR_NONE:
	default:
		m_nametable[0] = m_nt_ram.get();
		m_nametable[1] = m_nt_ram.get() + 0x400;
		m_nametable[2] = m_nt_ram.get() + 0x800;
		m_nametable[3] = m_nt_ram.get() + 0xc00;
		break;
	}
}

/* SIZE MAPPINGS *\
 * old       new *
 * 512         8 *
 * 256         4 *
 * 128         2 *
 *  64         1 *
\*****************/

void playch10_state::pc10_set_videorom_bank( int first, int count, int bank, int size )
{
	int i, len;
	/* first = first bank to map */
	/* count = number of 1K banks to map */
	/* bank = index of the bank */
	/* size = size of indexed banks (in KB) */
	/* note that this follows the original PPU banking and might be overly complex */

	/* yeah, this is probably a horrible assumption to make.*/
	/* but the driver is 100% consistant */

	len = memregion("gfx2")->bytes();
	len /= 0x400;   // convert to KB
	len /= size;    // convert to bank resolution
	len--;          // convert to mask
	bank &= len;    // should be the right mask

	for (i = 0; i < count; i++)
	{
		m_chr_page[i + first].writable = 0;
		m_chr_page[i + first].chr=m_vrom + (i * 0x400) + (bank * size * 0x400);
	}
}

void playch10_state::set_videoram_bank( int first, int count, int bank, int size )
{
	int i;
	/* first = first bank to map */
	/* count = number of 1K banks to map */
	/* bank = index of the bank */
	/* size = size of indexed banks (in KB) */
	/* note that this follows the original PPU banking and might be overly complex */

	/* assumes 8K of vram */
	/* need 8K to fill address space */
	/* only pinbot (8k) banks at all */

	for (i = 0; i < count; i++)
	{
		m_chr_page[i + first].writable = 1;
		m_chr_page[i + first].chr = m_vram.get() + (((i * 0x400) + (bank * size * 0x400)) & 0x1fff);
	}
}

/*************************************
 *
 *  Common init for all games
 *
 *************************************/

void playch10_state::init_playch10()
{
	m_vram = nullptr;

	/* set the controller to default */
	m_pc10_gun_controller = 0;

	/* default mirroring */
	m_mirroring = PPU_MIRROR_NONE;
}

/**********************************************************************************
 *
 *  Game and Board-specific initialization
 *
 **********************************************************************************/

/* Gun games */

void playch10_state::init_pc_gun()
{
	/* common init */
	init_playch10();

	/* we have no vram, make sure switching games doesn't point to an old allocation */
	m_vram = nullptr;

	/* set the control type */
	m_pc10_gun_controller = 1;
}


/* Horizontal mirroring */

void playch10_state::init_pc_hrz()
{
	/* common init */
	init_playch10();

	/* setup mirroring */
	m_mirroring = PPU_MIRROR_HORZ;
}

/* MMC1 mapper, used by D and F boards */


WRITE8_MEMBER(playch10_state::mmc1_rom_switch_w)
{
	/* basically, a MMC1 mapper from the nes */
	static int size16k, switchlow, vrom4k;

	int reg = (offset >> 13);

	/* reset mapper */
	if (data & 0x80)
	{
		m_mmc1_shiftreg = m_mmc1_shiftcount = 0;

		size16k = 1;
		switchlow = 1;
		vrom4k = 0;

		return;
	}

	/* see if we need to clock in data */
	if (m_mmc1_shiftcount < 5)
	{
		m_mmc1_shiftreg >>= 1;
		m_mmc1_shiftreg |= (data & 1) << 4;
		m_mmc1_shiftcount++;
	}

	/* are we done shifting? */
	if (m_mmc1_shiftcount == 5)
	{
		/* reset count */
		m_mmc1_shiftcount = 0;

		/* apply data to registers */
		switch (reg)
		{
			case 0:     /* mirroring and options */
				{
					int _mirroring;

					vrom4k = m_mmc1_shiftreg & 0x10;
					size16k = m_mmc1_shiftreg & 0x08;
					switchlow = m_mmc1_shiftreg & 0x04;

					switch (m_mmc1_shiftreg & 3)
					{
						case 0:
							_mirroring = PPU_MIRROR_LOW;
						break;

						case 1:
							_mirroring = PPU_MIRROR_HIGH;
						break;

						case 2:
							_mirroring = PPU_MIRROR_VERT;
						break;

						default:
						case 3:
							_mirroring = PPU_MIRROR_HORZ;
						break;
					}

					/* apply mirroring */
					pc10_set_mirroring(_mirroring);
				}
			break;

			case 1: /* video rom banking - bank 0 - 4k or 8k */
				if (m_vram)
					set_videoram_bank(0, (vrom4k) ? 4 : 8, (m_mmc1_shiftreg & 0x1f), 4);
				else
					pc10_set_videorom_bank(0, (vrom4k) ? 4 : 8, (m_mmc1_shiftreg & 0x1f), 4);
			break;

			case 2: /* video rom banking - bank 1 - 4k only */
				if (vrom4k)
				{
					if (m_vram)
						set_videoram_bank(0, (vrom4k) ? 4 : 8, (m_mmc1_shiftreg & 0x1f), 4);
					else
						pc10_set_videorom_bank(4, 4, (m_mmc1_shiftreg & 0x1f), 4);
				}
			break;

			case 3: /* program banking */
				{
					int bank = (m_mmc1_shiftreg & m_mmc1_rom_mask) * 0x4000;
					uint8_t *prg = memregion("cart")->base();

					if (!size16k)
					{
						/* switch 32k */
						memcpy(&prg[0x08000], &prg[0x010000 + bank], 0x8000);
					}
					else
					{
						/* switch 16k */
						if (switchlow)
						{
							/* low */
							memcpy(&prg[0x08000], &prg[0x010000 + bank], 0x4000);
						}
						else
						{
							/* high */
							memcpy(&prg[0x0c000], &prg[0x010000 + bank], 0x4000);
						}
					}
				}
			break;
		}
	}
}

/**********************************************************************************/
/* A Board games (Track & Field, Gradius) */

WRITE8_MEMBER(playch10_state::aboard_vrom_switch_w)
{
	pc10_set_videorom_bank(0, 8, (data & 3), 8);
}

void playch10_state::init_pcaboard()
{
	/* switches vrom with writes to the $803e-$8041 area */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0x8fff, write8_delegate(FUNC(playch10_state::aboard_vrom_switch_w),this));

	/* common init */
	init_playch10();

	/* set the mirroring here */
	m_mirroring = PPU_MIRROR_VERT;

	/* we have no vram, make sure switching games doesn't point to an old allocation */
	m_vram = nullptr;
}

/**********************************************************************************/
/* B Board games (Contra, Rush N' Attach, Pro Wrestling) */

WRITE8_MEMBER(playch10_state::bboard_rom_switch_w)
{
	int bankoffset = 0x10000 + ((data & 7) * 0x4000);
	uint8_t *prg = memregion("cart")->base();

	memcpy(&prg[0x08000], &prg[bankoffset], 0x4000);
}

void playch10_state::init_pcbboard()
{
	uint8_t *prg = memregion("cart")->base();

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x28000], 0x8000);

	/* Roms are banked at $8000 to $bfff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::bboard_rom_switch_w),this));

	/* common init */
	init_playch10();

	/* allocate vram */
	m_vram = std::make_unique<uint8_t[]>(0x2000);

	/* set the mirroring here */
	m_mirroring = PPU_MIRROR_VERT;
	/* special init */
	set_videoram_bank(0, 8, 0, 8);
}

/**********************************************************************************/
/* C Board games (The Goonies) */

WRITE8_MEMBER(playch10_state::cboard_vrom_switch_w)
{
	pc10_set_videorom_bank(0, 8, ((data >> 1) & 1), 8);
}

void playch10_state::init_pccboard()
{
	/* switches vrom with writes to $6000 */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x6000, 0x6000, write8_delegate(FUNC(playch10_state::cboard_vrom_switch_w),this));

	/* we have no vram, make sure switching games doesn't point to an old allocation */
	m_vram = nullptr;

	/* common init */
	init_playch10();
}

/**********************************************************************************/
/* D Board games (Rad Racer) */

void playch10_state::init_pcdboard()
{
	uint8_t *prg = memregion("cart")->base();

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x28000], 0x8000);

	m_mmc1_rom_mask = 0x07;

	/* MMC mapper at writes to $8000-$ffff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::mmc1_rom_switch_w),this));


	/* common init */
	init_playch10();
	/* allocate vram */
	m_vram = std::make_unique<uint8_t[]>(0x2000);
	/* special init */
	set_videoram_bank(0, 8, 0, 8);
}

/* D Board games with extra ram (Metroid) */

void playch10_state::init_pcdboard_2()
{
	/* extra ram at $6000-$7fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff);

	/* common init */
	init_pcdboard();

	/* allocate vram */
	m_vram = std::make_unique<uint8_t[]>(0x2000);
	/* special init */
	set_videoram_bank(0, 8, 0, 8);
}

/**********************************************************************************/
/* E Board games (Mike Tyson's Punchout) - BROKEN - FIX ME */

/* callback for the ppu_latch */
void playch10_state::mapper9_latch(offs_t offset )
{
	if((offset & 0x1ff0) == 0x0fd0 && m_MMC2_bank_latch[0] != 0xfd)
	{
		m_MMC2_bank_latch[0] = 0xfd;
		pc10_set_videorom_bank(0, 4, m_MMC2_bank[0], 4);
	}
	else if((offset & 0x1ff0) == 0x0fe0 && m_MMC2_bank_latch[0] != 0xfe)
	{
		m_MMC2_bank_latch[0] = 0xfe;
		pc10_set_videorom_bank(0, 4, m_MMC2_bank[1], 4);
	}
	else if((offset & 0x1ff0) == 0x1fd0 && m_MMC2_bank_latch[1] != 0xfd)
	{
		m_MMC2_bank_latch[1] = 0xfd;
		pc10_set_videorom_bank(4, 4, m_MMC2_bank[2], 4);
	}
	else if((offset & 0x1ff0) == 0x1fe0 && m_MMC2_bank_latch[1] != 0xfe)
	{
		m_MMC2_bank_latch[1] = 0xfe;
		pc10_set_videorom_bank(4, 4, m_MMC2_bank[3], 4);
	}
}

WRITE8_MEMBER(playch10_state::eboard_rom_switch_w)
{
	/* a variation of mapper 9 on a nes */
	switch (offset & 0x7000)
	{
		case 0x2000: /* code bank switching */
			{
				int bankoffset = 0x10000 + (data & 0x0f) * 0x2000;
				uint8_t *prg = memregion("cart")->base();
				memcpy(&prg[0x08000], &prg[bankoffset], 0x2000);
			}
		break;

		case 0x3000: /* gfx bank 0 - 4k */
			m_MMC2_bank[0] = data;
			if (m_MMC2_bank_latch[0] == 0xfd)
				pc10_set_videorom_bank(0, 4, data, 4);
		break;

		case 0x4000: /* gfx bank 0 - 4k */
			m_MMC2_bank[1] = data;
			if (m_MMC2_bank_latch[0] == 0xfe)
				pc10_set_videorom_bank(0, 4, data, 4);
		break;

		case 0x5000: /* gfx bank 1 - 4k */
			m_MMC2_bank[2] = data;
			if (m_MMC2_bank_latch[1] == 0xfd)
				pc10_set_videorom_bank(4, 4, data, 4);
		break;

		case 0x6000: /* gfx bank 1 - 4k */
			m_MMC2_bank[3] = data;
			if (m_MMC2_bank_latch[1] == 0xfe)
				pc10_set_videorom_bank(4, 4, data, 4);
		break;

		case 0x7000: /* mirroring */
			pc10_set_mirroring(data ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);

		break;
	}
}

void playch10_state::init_pceboard()
{
	uint8_t *prg = memregion("cart")->base();

	/* we have no vram, make sure switching games doesn't point to an old allocation */
	m_vram = nullptr;

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x28000], 0x8000);

	/* basically a mapper 9 on a nes */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::eboard_rom_switch_w),this));

	/* ppu_latch callback */
	m_ppu->set_latch(ppu2c0x_device::latch_delegate(FUNC(playch10_state::mapper9_latch),this));

	/* nvram at $6000-$6fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x6fff);

	/* common init */
	init_playch10();
}

/**********************************************************************************/
/* F Board games (Ninja Gaiden, Double Dragon) */

void playch10_state::init_pcfboard()
{
	uint8_t *prg = memregion("cart")->base();
	uint32_t len = memregion("cart")->bytes();

	/* we have no vram, make sure switching games doesn't point to an old allocation */
	m_vram = nullptr;

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x28000], 0x8000);

	m_mmc1_rom_mask = ((len - 0x10000) / 0x4000) - 1;

	/* MMC mapper at writes to $8000-$ffff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::mmc1_rom_switch_w),this));

	/* common init */
	init_playch10();
}

/* F Board games with extra ram (Baseball Stars) */

void playch10_state::init_pcfboard_2()
{
	/* extra ram at $6000-$6fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x6fff);

	m_vram = nullptr;

	/* common init */
	init_pcfboard();
}

/**********************************************************************************/
/* G Board games (Super Mario Bros. 3) */


void playch10_state::gboard_scanline_cb( int scanline, int vblank, int blanked )
{
	if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE)
	{
		int priorCount = m_IRQ_count;
		if (m_IRQ_count == 0)
			m_IRQ_count = m_IRQ_count_latch;
		else
			m_IRQ_count--;

		if (m_IRQ_enable && !blanked && (m_IRQ_count == 0) && priorCount) // according to blargg the latter should be present as well, but it breaks Rampart and Joe & Mac US: they probably use the alt irq!
		{
			m_cartcpu->set_input_line(0, HOLD_LINE);
		}
	}
}

WRITE8_MEMBER(playch10_state::gboard_rom_switch_w)
{
	/* basically, a MMC3 mapper from the nes */

	switch (offset & 0x6001)
	{
		case 0x0000:
			m_gboard_command = data;

			if (m_gboard_last_bank != (data & 0xc0))
			{
				int bank;
				uint8_t *prg = memregion("cart")->base();

				/* reset the banks */
				if (m_gboard_command & 0x40)
				{
					/* high bank */
					bank = m_gboard_banks[0] * 0x2000 + 0x10000;

					memcpy(&prg[0x0c000], &prg[bank], 0x2000);
					memcpy(&prg[0x08000], &prg[0x4c000], 0x2000);
				}
				else
				{
					/* low bank */
					bank = m_gboard_banks[0] * 0x2000 + 0x10000;

					memcpy(&prg[0x08000], &prg[bank], 0x2000);
					memcpy(&prg[0x0c000], &prg[0x4c000], 0x2000);
				}

				/* mid bank */
				bank = m_gboard_banks[1] * 0x2000 + 0x10000;
				memcpy(&prg[0x0a000], &prg[bank], 0x2000);

				m_gboard_last_bank = data & 0xc0;
			}
		break;

		case 0x0001:
			{
				uint8_t cmd = m_gboard_command & 0x07;
				int page = (m_gboard_command & 0x80) >> 5;
				int bank;

				switch (cmd)
				{
					case 0: /* char banking */
					case 1: /* char banking */
						data &= 0xfe;
						page ^= (cmd << 1);
						pc10_set_videorom_bank(page, 2, data, 1);
					break;

					case 2: /* char banking */
					case 3: /* char banking */
					case 4: /* char banking */
					case 5: /* char banking */
						page ^= cmd + 2;
						pc10_set_videorom_bank(page, 1, data, 1);
					break;

					case 6: /* program banking */
					{
						uint8_t *prg = memregion("cart")->base();
						if (m_gboard_command & 0x40)
						{
							/* high bank */
							m_gboard_banks[0] = data & 0x1f;
							bank = (m_gboard_banks[0]) * 0x2000 + 0x10000;

							memcpy(&prg[0x0c000], &prg[bank], 0x2000);
							memcpy(&prg[0x08000], &prg[0x4c000], 0x2000);
						}
						else
						{
							/* low bank */
							m_gboard_banks[0] = data & 0x1f;
							bank = (m_gboard_banks[0]) * 0x2000 + 0x10000;

							memcpy(&prg[0x08000], &prg[bank], 0x2000);
							memcpy(&prg[0x0c000], &prg[0x4c000], 0x2000);
						}
					}
					break;

					case 7: /* program banking */
						{
							/* mid bank */
							uint8_t *prg = memregion("cart")->base();
							m_gboard_banks[1] = data & 0x1f;
							bank = m_gboard_banks[1] * 0x2000 + 0x10000;

							memcpy(&prg[0x0a000], &prg[bank], 0x2000);
						}
					break;
				}
			}
		break;

		case 0x2000: /* mirroring */
			if (!m_gboard_4screen)
			{
				if (data & 0x40)
					pc10_set_mirroring(PPU_MIRROR_HIGH);
				else
					pc10_set_mirroring((data & 1) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
			}
		break;

		case 0x2001: /* enable ram at $6000 */
			/* ignored - we always enable it */
		break;

		case 0x4000: /* scanline counter */
			m_IRQ_count_latch = data;
		break;

		case 0x4001: /* scanline latch */
			m_IRQ_count = 0;
		break;

		case 0x6000: /* disable irqs */
			m_IRQ_enable = 0;
		break;

		case 0x6001: /* enable irqs */
			m_IRQ_enable = 1;
		break;
	}
}

void playch10_state::init_pcgboard()
{
	uint8_t *prg = memregion("cart")->base();
	m_vram = nullptr;

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x4c000], 0x4000);
	memcpy(&prg[0x0c000], &prg[0x4c000], 0x4000);

	/* MMC3 mapper at writes to $8000-$ffff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::gboard_rom_switch_w),this));

	/* extra ram at $6000-$7fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff);

	m_gboard_banks[0] = 0x1e;
	m_gboard_banks[1] = 0x1f;
	m_gboard_scanline_counter = 0;
	m_gboard_scanline_latch = 0;
	m_gboard_4screen = 0;
	m_IRQ_enable = 0;
	m_IRQ_count = m_IRQ_count_latch = 0;

	/* common init */
	init_playch10();

	m_ppu->set_scanline_callback(ppu2c0x_device::scanline_delegate(FUNC(playch10_state::gboard_scanline_cb),this));
}

void playch10_state::init_pcgboard_type2()
{
	m_vram = nullptr;
	/* common init */
	init_pcgboard();

	/* enable 4 screen mirror */
	m_gboard_4screen = 1;
}

/**********************************************************************************/
/* i Board games (Captain Sky Hawk, Solar Jetman) */

WRITE8_MEMBER(playch10_state::iboard_rom_switch_w)
{
	int bank = data & 7;
	uint8_t *prg = memregion("cart")->base();

	if (data & 0x10)
		pc10_set_mirroring(PPU_MIRROR_HIGH);
	else
		pc10_set_mirroring(PPU_MIRROR_LOW);

	memcpy(&prg[0x08000], &prg[bank * 0x8000 + 0x10000], 0x8000);
}

void playch10_state::init_pciboard()
{
	uint8_t *prg = memregion("cart")->base();

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x10000], 0x8000);

	/* Roms are banked at $8000 to $bfff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::iboard_rom_switch_w),this));

	/* common init */
	init_playch10();

	/* allocate vram */
	m_vram = std::make_unique<uint8_t[]>(0x2000);
	/* special init */
	set_videoram_bank(0, 8, 0, 8);
}

/**********************************************************************************/
/* H Board games (PinBot) */

WRITE8_MEMBER(playch10_state::hboard_rom_switch_w)
{
	switch (offset & 0x7001)
	{
		case 0x0001:
			{
				uint8_t cmd = m_gboard_command & 0x07;
				int page = (m_gboard_command & 0x80) >> 5;

				switch (cmd)
				{
					case 0: /* char banking */
					case 1: /* char banking */
						data &= 0xfe;
						page ^= (cmd << 1);
						if (data & 0x40)
						{
							set_videoram_bank(page, 2, data, 1);
						}
						else
						{
							pc10_set_videorom_bank(page, 2, data, 1);
						}
					return;

					case 2: /* char banking */
					case 3: /* char banking */
					case 4: /* char banking */
					case 5: /* char banking */
						page ^= cmd + 2;
						if (data & 0x40)
						{
							set_videoram_bank(page, 1, data, 1);
						}
						else
						{
							pc10_set_videorom_bank(page, 1, data, 1);
						}
					return;
				}
			}
	};
	gboard_rom_switch_w(space,offset,data);
}


void playch10_state::init_pchboard()
{
	uint8_t *prg = memregion("cart")->base();
	memcpy(&prg[0x08000], &prg[0x4c000], 0x4000);
	memcpy(&prg[0x0c000], &prg[0x4c000], 0x4000);

	/* Roms are banked at $8000 to $bfff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::hboard_rom_switch_w),this));

	/* extra ram at $6000-$7fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff);

	m_gboard_banks[0] = 0x1e;
	m_gboard_banks[1] = 0x1f;
	m_gboard_scanline_counter = 0;
	m_gboard_scanline_latch = 0;
	m_gboard_last_bank = 0xff;
	m_gboard_command = 0;

	/* common init */
	init_playch10();

	m_ppu->set_scanline_callback(ppu2c0x_device::scanline_delegate(FUNC(playch10_state::gboard_scanline_cb),this));
}

/**********************************************************************************/
/* K Board games (Mario Open Golf) */

void playch10_state::init_pckboard()
{
	uint8_t *prg = memregion("cart")->base();

	/* We do manual banking, in case the code falls through */
	/* Copy the initial banks */
	memcpy(&prg[0x08000], &prg[0x48000], 0x8000);

	m_mmc1_rom_mask = 0x0f;

	/* extra ram at $6000-$7fff */
	m_cartcpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff);

	/* Roms are banked at $8000 to $bfff */
	m_cartcpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(playch10_state::mmc1_rom_switch_w),this));

	/* common init */
	init_playch10();

	/* allocate vram */
	m_vram = std::make_unique<uint8_t[]>(0x2000);
	/* special init */
	set_videoram_bank(0, 8, 0, 8);
}