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







                                                                            
                
                            


                         








                                                     







                             


 
                       

 








                                       
                                                           
 
                                                           
                                                         
 
                                          















                               
                                                            
 
                                          










                                       
                                             
 
                                             
                                                                    



                                                                                
                                             
 
                                             
                                                                    










                                                                                
 
                                                     


                                                                                         
                                         
                                           
            
                                              



                                                                                      
                                  
         


                                       










                                       
                                      
 

                                             

                                                 





                                              





                                                         
 

                                    


 
                                             
 
                            
                                  


 
                                             
 
                            
                                  


 
                                                 
 
                            
                                                                         









                                       
                                                                                                 
 
                                             
 
                                          



                                                      
                                             
 
                                          



                                                      
                                             
 
                                                            


 
                                             
 
                                                            









                                       
                                             
 
                                                            


 
                                             
 
                                                            


 
                                             
 
                                                            









                                       
                                            
 
                                                                               
 
                                                                              









                                       
                                           
 
                                                                        
 
                                                                              


 
                                            






                                 
                                               











                                                                               
                                             
 
                                                                        
 


                       
                                                                           

















                                                                                             
                                  
 
                                             
                                                                                                                                           














                                              


 
                                  
 
                                                                   

                           
                             
                                               
                                            
















                                                                  

                                         
                                        

                                        

                                                                   


 
                                 
 
                                                                                                                                         
                                    
                                                                          

                                             
                                                                                                                                          
 







                                                                      


 
                                 
 
                                                                                                                                         
                                                             
                                                                   

                                 

                         

                           
                          
 


                                                                  
 
                          

                                         
                           

                                        

                                                                   









                                       
                                                              

                             


                                                                   
                                               




                                          
                                                                                 


 
                                                             

                             

                                                                              
                                               

                                          
                                                                                 


 
                                                           

                                  
                                                   
                                                                             









                                       
                                                           


                                      
                                                     
                                                                                              
                                     
                                        

                                          

                                                                     



                                
                                        





                                                                                        
                                      
 
                         
 
                                                                 
 
                                                                                                    
                                                
 
                                                                          
                                                



                                   
                                       
 
                         
 
                                                                
 
                                                                                                
                                                
 
                                                                          
                                                



                                                                               
                                        
 
                         
 
                                                         
 

                                                                                                            
            
                                                                                                           
                                                
 
                                                                          
                                                



                                      
                                       
 

                                                                                   
 
                                                             
 
                                                                  
                                                
 
                                                                                
                                                



                                                                                       
                                     
 

                                                                                   
 
                                                                
 
                                                                  
                                                                      
         

                                                                                                                    
         
                                                
 
                                                                                
                                                



                                                                            
                                       
 

                                                                                                                       
 
                                                             
 
                                                                  
                                                                      
         

                                                                                                                    
         
                                                
 
                                                                                
                                                



                                                              
                                    
 
                                           



                                                                                       
                         
 
                                                                
 
                                                                
                                                                    
         

                                                                                                                  
         
                                                
 



                                                                     
            
                                                 
                                                
 
                                                         









                                       
                                                                                                                            
 


                                                                                                                      
 
          
























                                                                                   














                                                                   


                                               


















































                                                                                                                     









                                       
                                                          
 



                                   
 
          



                                                                                  
 













                                                                   


                                 
































                                                              










                                       
                                         
 
                                         
                                                                               
                    


 
                                          
 
                                                                                      
                                                                           


                                                                      









                                       
                                                 
 
                                 
         
                                                                                                         
                                             

            
                                                                                    


 
                                               
 
                                 
         
                                                                                                         
                                             
         
                                                



                                                                                   
            
                                                                                    


 





































                                                                      
                                                









                                                                      
                             


                       
                                                                                            

                                                                                   
                                   

                                       
                                       
                 

                                                                                                      


                                      
                                                                                




                                                                      
                                      



                                    
                                                                                                       

                                    
                                          
         
                                                                                       



                                                                                             
                                               
         
                                                                                       



                                                                       
                                              

                                              
                                                  
                 

                                                                


                                          
                                                                          


                                                                             
                                                 
                                                                 
                                                        

                                                                
                                               
                         




                                                                                                                                 










                                                                                                

                                                                                                                                        

         

                                    









                                       
                                                      




                       
                                                       
                                                 

                              
                                                         



                                                                                     
                                                               
                                             









                                                                                     
                                                       
 
                                                                                            
 

                       
                                                          

                              
                                                                    
                                                                               


                                                                     
                                                                     
                                                                                                              
                                                       
                                                        

                              
                                                         
                                        











                                       
                                                 




                          
                                       
                                                       

                              
                                       
                                                       
                                                         


                                               
                                       
                          
                                                                             

                              
                                       
                          




                                                                     

                              
                                       
                                                       

                              
                                       
                                                       
                                                                                               









                                                                          
                                                   


                       
                                        
                                                                                                            
                                                      

                                                                                                          
 
                                                                                                      
                                                                                           


                                                                                      

                              

                                       




                                                                                     

                              



                                       
                                                                    








                                                                                      
                                               




                          
                                       
                                                       

                              
                                         
                                                       
                                                         










                                                                          
                                                 


                       



                                       
                                                             

                              
                                       
                                                
                                                                  
                                                                                                           
                                             
                                           

                              
                                       


                                                                                                            

                              
                                  
                                                                                                 















                                                                                      
                                                      
 
                          
                                                       


 
                                                     
 
                          
                                                          



                    
                                                       
 
                          
                                                       
                                                    
                                                                        

                                 
                                                                         
                                                                                                                                


                                 
                                                                                
                                                                                                                                 


                                 
                                                                         
                                                                                                                                


                                 
                                                                                
                                                                                                                                 

            
                                            


 
                                                      
 
                          
                                                          

                                                    
                                                                                        
                                                                                                                                         



                                                    
                                                                                        
                                                                                                                                         


                              
                                            









                                       
                                               
 
                             


 
                                                
 
                                         
                                          

                               

                                 
 
                                            
                                


                                                                                                           
                                        









                                       
                                                        


                                                        
                                                 
         
                                                                                        

                                      
                                                               
 
                                                                                                                   


 
                                                        


                                                         
                                                 
         
                                                                                         

                                      
                                                               
 
                                                                                                                    


 
                                                 







                                                                          
                                                     


                                                                    
                                                 
         
                                                                                           

                                     
                                                               
 
                                                                                                               









                                       
                                           
 
                                










                                       
                                                            

                                
                                                                       

                                                  









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

    Cinemat/Leland driver

    driver by Aaron Giles and Paul Leaman

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

#include "emu.h"
#include "includes/leland.h"
#include "audio/leland.h"

#include "cpu/z80/z80.h"


/*************************************
 *
 *  Debugging
 *
 *************************************/

/* define these to 0 to disable, or to 1 to enable */
#define LOG_KEYCARDS        0
#define LOG_KEYCARDS_FULL   0
#define LOG_BANKSWITCHING_M 0
#define LOG_BANKSWITCHING_S 0
#define LOG_SOUNDPORT       0
#define LOG_EEPROM          0
#define LOG_BATTERY_RAM     0
#define LOG_XROM            0



/* Internal routines */





/*************************************
 *
 *  Generic dial encoding
 *
 *************************************/

int leland_state::dial_compute_value(int new_val, int indx)
{
	int delta = new_val - (int)m_dial_last_input[indx];
	uint8_t result = m_dial_last_result[indx] & 0x80;

	m_dial_last_input[indx] = new_val;

	if (delta > 0x80)
		delta -= 0x100;
	else if (delta < -0x80)
		delta += 0x100;

	if (delta < 0)
	{
		result = 0x80;
		delta = -delta;
	}
	else if (delta > 0)
		result = 0x00;

	if (delta > 0x1f)
		delta = 0x1f;
	result |= (m_dial_last_result[indx] + delta) & 0x1f;

	m_dial_last_result[indx] = result;
	return result;
}



/*************************************
 *
 *  Cerberus inputs
 *
 *************************************/

READ8_MEMBER(leland_state::cerberus_dial_1_r)
{
	int original = ioport("IN0")->read();
	int modified = dial_compute_value(ioport("AN0")->read(), 0);
	return (original & 0xc0) | ((modified & 0x80) >> 2) | (modified & 0x1f);
}


READ8_MEMBER(leland_state::cerberus_dial_2_r)
{
	int original = ioport("IN2")->read();
	int modified = dial_compute_value(ioport("AN1")->read(), 1);
	return (original & 0xc0) | ((modified & 0x80) >> 2) | (modified & 0x1f);
}



/*************************************
 *
 *  Alley Master inputs
 *
 *************************************/


WRITE8_MEMBER(leland_state::alleymas_joystick_kludge)
{
	/* catch the case where they clear this memory location at PC $1827 and change */
	/* the value written to be a 1 */
	if (m_master->pcbase() == 0x1827)
		*m_alleymas_kludge_mem = 1;
	else
		*m_alleymas_kludge_mem = data;

	/* while we're here, make sure the first 3 characters in battery RAM are a */
	/* valid name; otherwise, it will crash if you start a game and don't enter */
	/* your name */
	if (m_battery_ram[0] == 0)
	{
		m_battery_ram[0] = 'C';
		m_battery_ram[1] = 'I';
		m_battery_ram[2] = 'N';
	}
}



/*************************************
 *
 *  Danger Zone inputs
 *
 *************************************/

void leland_state::update_dangerz_xy()
{
	uint8_t newy = ioport("AN0")->read();
	uint8_t newx = ioport("AN1")->read();
	int deltay = newy - m_dial_last_input[0];
	int deltax = newx - m_dial_last_input[1];

	if (deltay <= -128) deltay += 256;
	else if (deltay >= 128) deltay -= 256;
	if (deltax <= -128) deltax += 256;
	else if (deltax >= 128) deltax -= 256;

	m_dangerz_y += deltay;
	m_dangerz_x += deltax;
	if (m_dangerz_y < 0) m_dangerz_y = 0;
	else if (m_dangerz_y >= 1024) m_dangerz_y = 1023;
	if (m_dangerz_x < 0) m_dangerz_x = 0;
	else if (m_dangerz_x >= 1024) m_dangerz_x = 1023;

	m_dial_last_input[0] = newy;
	m_dial_last_input[1] = newx;
}


READ8_MEMBER(leland_state::dangerz_input_y_r)
{
	update_dangerz_xy();
	return m_dangerz_y & 0xff;
}


READ8_MEMBER(leland_state::dangerz_input_x_r)
{
	update_dangerz_xy();
	return m_dangerz_x & 0xff;
}


READ8_MEMBER(leland_state::dangerz_input_upper_r)
{
	update_dangerz_xy();
	return ((m_dangerz_y >> 2) & 0xc0) | ((m_dangerz_x >> 8) & 0x03);
}



/*************************************
 *
 *  Red Line Racer inputs
 *
 *************************************/

static const uint8_t redline_pedal_value[8] = { 0xf0, 0xe0, 0xc0, 0xd0, 0x90, 0xb0, 0x30, 0x70 };

READ8_MEMBER(leland_state::redline_pedal_1_r)
{
	int pedal = ioport("IN0")->read();
	return redline_pedal_value[pedal >> 5] | 0x0f;
}


READ8_MEMBER(leland_state::redline_pedal_2_r)
{
	int pedal = ioport("IN2")->read();
	return redline_pedal_value[pedal >> 5] | 0x0f;
}


READ8_MEMBER(leland_state::redline_wheel_1_r)
{
	return dial_compute_value(ioport("AN0")->read(), 0);
}


READ8_MEMBER(leland_state::redline_wheel_2_r)
{
	return dial_compute_value(ioport("AN1")->read(), 1);
}



/*************************************
 *
 *  Super Offroad inputs
 *
 *************************************/

READ8_MEMBER(leland_state::offroad_wheel_1_r)
{
	return dial_compute_value(ioport("AN3")->read(), 0);
}


READ8_MEMBER(leland_state::offroad_wheel_2_r)
{
	return dial_compute_value(ioport("AN4")->read(), 1);
}


READ8_MEMBER(leland_state::offroad_wheel_3_r)
{
	return dial_compute_value(ioport("AN5")->read(), 2);
}



/*************************************
 *
 *  Ataxx inputs
 *
 *************************************/

READ8_MEMBER(ataxx_state::ataxx_trackball_r)
{
	static const char *const tracknames[] = { "AN0", "AN1", "AN2", "AN3" };

	return dial_compute_value(ioport(tracknames[offset])->read(), offset);
}



/*************************************
 *
 *  Indy Heat inputs
 *
 *************************************/

READ8_MEMBER(ataxx_state::indyheat_wheel_r)
{
	static const char *const tracknames[] = { "AN0", "AN1", "AN2" };

	return dial_compute_value(ioport(tracknames[offset])->read(), offset);
}


READ8_MEMBER(ataxx_state::indyheat_analog_r)
{
	switch (offset)
	{
		case 0:
			return 0;

		case 1:
			return m_analog_result;

		case 2:
			return 0;

		case 3:
			logerror("Unexpected analog read(%02X)\n", 8 + offset);
			break;
	}
	return 0xff;
}


WRITE8_MEMBER(ataxx_state::indyheat_analog_w)
{
	static const char *const tracknames[] = { "AN3", "AN4", "AN5" };

	switch (offset)
	{
		case 3:
			m_analog_result = ioport(tracknames[data])->read();
			break;

		case 0:
		case 1:
		case 2:
			logerror("Unexpected analog write(%02X) = %02X\n", 8 + offset, data);
			break;
	}
}



/*************************************
 *
 *  Machine initialization
 *
 *************************************/

void leland_state::machine_start()
{
	/* start scanline interrupts going */
	m_master_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(leland_state::leland_interrupt_callback),this));

	save_item(NAME(m_dac_control));
	save_item(NAME(m_wcol_enable));
	save_item(NAME(m_analog_result));
	save_item(NAME(m_dial_last_input));
	save_item(NAME(m_dial_last_result));
	save_item(NAME(m_keycard_shift));
	save_item(NAME(m_keycard_bit));
	save_item(NAME(m_keycard_state));
	save_item(NAME(m_keycard_clock));
	save_item(NAME(m_keycard_command));
	save_item(NAME(m_top_board_bank));
	save_item(NAME(m_sound_port_bank));
	save_item(NAME(m_alternate_bank));
	save_item(NAME(m_battery_ram_enable));
}


void leland_state::machine_reset()
{
	m_master_int_timer->adjust(m_screen->time_until_pos(8), 8);

	/* reset globals */
	m_gfx_control = 0x00;
	address_space &space = generic_space();
	leland_sound_port_w(space, 0, 0xff);
	m_wcol_enable = 0;

	m_dangerz_x = 512;
	m_dangerz_y = 512;
	m_analog_result = 0xff;
	memset(m_dial_last_input, 0, sizeof(m_dial_last_input));
	memset(m_dial_last_result, 0, sizeof(m_dial_last_result));

	m_keycard_shift = 0;
	m_keycard_bit = 0;
	m_keycard_state = 0;
	m_keycard_clock = 0;
	memset(m_keycard_command, 0, sizeof(m_keycard_command));

	m_top_board_bank = 0;
	m_sound_port_bank = 0;
	m_alternate_bank = 0;

	/* initialize the master banks */
	(this->*m_update_master_bank)();

	/* initialize the slave banks */
	if (m_slave_base.length() > 0x10000)
		m_slave_bankslot->set_base(&m_slave_base[0x10000]);
}


void ataxx_state::machine_start()
{
	// TODO: further untangle driver so the base class doesn't have stuff that isn't common and this can call the base implementation
	/* set the odd data banks */
	m_extra_tram = std::make_unique<uint8_t[]>(ATAXX_EXTRA_TRAM_SIZE);

	/* start scanline interrupts going */
	m_master_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(leland_state::ataxx_interrupt_callback),this));

	save_item(NAME(m_wcol_enable));
	save_item(NAME(m_dial_last_input));
	save_item(NAME(m_dial_last_result));
	save_item(NAME(m_master_bank));
	save_item(NAME(m_xrom1_addr));
	save_item(NAME(m_xrom2_addr));
	save_item(NAME(m_battery_ram_enable));
	save_pointer(NAME(m_extra_tram.get()), ATAXX_EXTRA_TRAM_SIZE);
}


void ataxx_state::machine_reset()
{
	// TODO: further untangle driver so the base class doesn't have stuff that isn't common and this can call the base implementation
	memset(m_extra_tram.get(), 0, ATAXX_EXTRA_TRAM_SIZE);
	m_master_int_timer->adjust(m_screen->time_until_pos(8), 8);

	/* initialize the XROM */
	m_xrom1_addr = 0;
	m_xrom2_addr = 0;

	/* reset globals */
	m_wcol_enable = 0;

	m_analog_result = 0xff;
	memset(m_dial_last_input, 0, sizeof(m_dial_last_input));
	memset(m_dial_last_result, 0, sizeof(m_dial_last_result));

	m_master_bank = 0;

	/* initialize the master banks */
	ataxx_bankswitch();

	/* initialize the slave banks */
	if (m_slave_base.length() > 0x10000)
		m_slave_bankslot->set_base(&m_slave_base[0x10000]);
}



/*************************************
 *
 *  Master CPU interrupt handling
 *
 *************************************/

TIMER_CALLBACK_MEMBER(leland_state::leland_interrupt_callback)
{
	int scanline = param;

	/* interrupts generated on the VA10 line, which is every */
	/* 16 scanlines starting with scanline #8 */
	m_master->set_input_line(0, HOLD_LINE);

	/* set a timer for the next one */
	scanline += 16;
	if (scanline > 248)
		scanline = 8;
	m_master_int_timer->adjust(m_screen->time_until_pos(scanline), scanline);
}


TIMER_CALLBACK_MEMBER(leland_state::ataxx_interrupt_callback)
{
	int scanline = param;

	/* interrupts generated according to the interrupt control register */
	m_master->set_input_line(0, HOLD_LINE);

	/* set a timer for the next one */
	m_master_int_timer->adjust(m_screen->time_until_pos(scanline), scanline);
}


INTERRUPT_GEN_MEMBER(leland_state::leland_master_interrupt)
{
	/* check for coins here */
	if ((ioport("IN1")->read() & 0x0e) != 0x0e)
		device.execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
}



/*************************************
 *
 *  Master CPU bankswitch handlers
 *
 *************************************/

WRITE8_MEMBER(leland_state::leland_master_alt_bankswitch_w)
{
	/* update any bankswitching */
	if (LOG_BANKSWITCHING_M)
		if ((m_alternate_bank ^ data) & 0x0f)
			logerror("%04X:alternate_bank = %02X\n", m_master->pc(), data & 0x0f);
	m_alternate_bank = data & 15;
	(this->*m_update_master_bank)();

	/* sound control is in the rest */
	if (m_sound)
		m_sound->leland_80186_control_w(space, offset, data);
}


/* bankswitching for Cerberus */
void leland_state::cerberus_bankswitch()
{
	/* no bankswitching */
}


/* bankswitching for Mayhem 2002, Power Play, World Series Baseball, and Alley Master */
void leland_state::mayhem_bankswitch()
{
	uint8_t *address;

	m_battery_ram_enable = ((m_sound_port_bank & 0x24) == 0);

	address = (!(m_sound_port_bank & 0x04)) ? &m_master_base[0x10000] : &m_master_base[0x1c000];
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &address[0x8000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Danger Zone */
void leland_state::dangerz_bankswitch()
{
	uint8_t *address;

	m_battery_ram_enable = ((m_top_board_bank & 0x80) != 0);

	address = (!(m_alternate_bank & 1)) ? &m_master_base[0x02000] : &m_master_base[0x12000];
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &address[0x8000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Baseball the Season II, Super Baseball, and Strike Zone */
void leland_state::basebal2_bankswitch()
{
	uint8_t *address;

	m_battery_ram_enable = (m_top_board_bank & 0x80);

	if (!m_battery_ram_enable)
		address = (!(m_sound_port_bank & 0x04)) ? &m_master_base[0x10000] : &m_master_base[0x1c000];
	else
		address = (!(m_top_board_bank & 0x40)) ? &m_master_base[0x28000] : &m_master_base[0x30000];
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &address[0x8000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Red Line Racer */
void leland_state::redline_bankswitch()
{
	static const uint32_t bank_list[] = { 0x10000, 0x18000, 0x02000, 0x02000 };
	uint8_t *address;

	m_battery_ram_enable = ((m_alternate_bank & 3) == 1);

	address = &m_master_base[bank_list[m_alternate_bank & 3]];
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &m_master_base[0xa000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Viper, Quarterback, Team Quarterback, and All American Football */
void leland_state::viper_bankswitch()
{
	static const uint32_t bank_list[] = { 0x02000, 0x10000, 0x18000, 0x02000 };
	uint8_t *address;

	m_battery_ram_enable = ((m_alternate_bank & 0x04) != 0);

	address = &m_master_base[bank_list[m_alternate_bank & 3]];
	if (bank_list[m_alternate_bank & 3] >= m_master_base.length())
	{
		logerror("%s:Master bank %02X out of range!\n", machine().describe_context(), m_alternate_bank & 3);
		address = &m_master_base[bank_list[0]];
	}
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &m_master_base[0xa000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Super Offroad, Super Offroad Track Pack, and Pig Out */
void leland_state::offroad_bankswitch()
{
	static const uint32_t bank_list[] = { 0x02000, 0x02000, 0x10000, 0x18000, 0x20000, 0x28000, 0x30000, 0x38000 };
	uint8_t *address;

	m_battery_ram_enable = ((m_alternate_bank & 7) == 1);

	address = &m_master_base[bank_list[m_alternate_bank & 7]];
	if (bank_list[m_alternate_bank & 7] >= m_master_base.length())
	{
		logerror("%s:Master bank %02X out of range!\n", machine().describe_context(), m_alternate_bank & 7);
		address = &m_master_base[bank_list[0]];
	}
	m_master_bankslot[0]->set_base(address);

	address = m_battery_ram_enable ? m_battery_ram : &m_master_base[0xa000];
	m_master_bankslot[1]->set_base(address);
}


/* bankswitching for Ataxx, WSF, Indy Heat, and Brute Force */
void ataxx_state::ataxx_bankswitch()
{
	static const uint32_t bank_list[] =
	{
		0x02000, 0x18000, 0x20000, 0x28000, 0x30000, 0x38000, 0x40000, 0x48000,
		0x50000, 0x58000, 0x60000, 0x68000, 0x70000, 0x78000, 0x80000, 0x88000
	};
	uint8_t *address;

	m_battery_ram_enable = ((m_master_bank & 0x30) == 0x10);

	address = &m_master_base[bank_list[m_master_bank & 15]];
	if (bank_list[m_master_bank & 15] >= m_master_base.length())
	{
		logerror("%s:Master bank %02X out of range!\n", machine().describe_context(), m_master_bank & 15);
		address = &m_master_base[bank_list[0]];
	}
	m_master_bankslot[0]->set_base(address);

	if (m_battery_ram_enable)
		address = m_battery_ram;
	else if ((m_master_bank & 0x30) == 0x20)
		address = &m_ataxx_qram[(m_master_bank & 0xc0) << 8];
	else
		address = &m_master_base[0xa000];
	m_master_bankslot[1]->set_base(address);

	m_wcol_enable = ((m_master_bank & 0x30) == 0x30);
}



/*************************************
 *
 *  EEPROM handling (64 x 16bits)
 *
 *************************************/

void leland_state::leland_init_eeprom(uint8_t default_val, const uint16_t *data, uint8_t serial_offset, uint8_t serial_type)
{
	uint8_t xorval = (serial_type == SERIAL_TYPE_ADD_XOR || serial_type == SERIAL_TYPE_ENCRYPT_XOR) ? 0xff : 0x00;
	uint8_t eeprom_data[64*2];
	uint32_t serial;

	/*
	    NOTE: This code is just illustrative, and explains how to generate the
	    serial numbers for the classic Leland games. We currently load default
	    EEPROM data from the ROMs rather than generating it.

	    Here are the input parameters for various games:

	        game        default_val     serial_offset   serial_type
	        cerberus    0x00            0               SERIAL_TYPE_NONE
	        mayhem      0x00            0x28            SERIAL_TYPE_ADD
	        powrplay    0xff            0x2d            SERIAL_TYPE_ADD_XOR
	        wseries     0xff            0x12            SERIAL_TYPE_ENCRYPT_XOR
	        alleymas    0xff            0x0c            SERIAL_TYPE_ENCRYPT_XOR
	        upyoural    0xff            0x0c            SERIAL_TYPE_ENCRYPT_XOR
	        dangerz     0xff            0x10            SERIAL_TYPE_ENCRYPT_XOR
	        basebal2    0xff            0x12            SERIAL_TYPE_ENCRYPT_XOR
	        dblplay     0xff            0x11            SERIAL_TYPE_ENCRYPT_XOR
	        strkzone    0xff            0x0f            SERIAL_TYPE_ENCRYPT_XOR
	        redlin2p    0xff            0x18            SERIAL_TYPE_ENCRYPT_XOR
	        quarterb    0xff            0x24            SERIAL_TYPE_ENCRYPT_XOR
	        viper       0xff            0x0c            SERIAL_TYPE_ENCRYPT_XOR
	        teamqb      0xff            0x1a            SERIAL_TYPE_ENCRYPT_XOR
	        aafb        0xff            0x1a            SERIAL_TYPE_ENCRYPT_XOR
	        offroad     0xff            0x00            SERIAL_TYPE_ENCRYPT_XOR
	        pigout      0xff            0x00            SERIAL_TYPE_ENCRYPT
	*/

	/* initialize everything to the default value */
	memset(eeprom_data, default_val, sizeof(eeprom_data));

	/* fill in the preset data */
	while (*data != 0xffff)
	{
		int offset = *data++;
		int value = *data++;
		eeprom_data[offset * 2 + 0] = value >> 8;
		eeprom_data[offset * 2 + 1] = value & 0xff;
	}

	/* pick a serial number -- examples of real serial numbers:

	    Team QB:      21101957
	    AAFB:         26101119 and 26101039
	*/
	serial = 0x12345678;

	/* switch off the serial number type */
	switch (serial_type)
	{
		case SERIAL_TYPE_ADD:
		case SERIAL_TYPE_ADD_XOR:
		{
			int i;
			for (i = 0; i < 10; i++)
			{
				int digit;

				if (i >= 8)
					digit = 0;
				else
					digit = ((serial << (i * 4)) >> 28) & 15;
				digit = ('0' + digit) * 2;

				eeprom_data[serial_offset * 2 +  0 + (i ^ 1)] = (digit / 3) ^ xorval;
				eeprom_data[serial_offset * 2 + 10 + (i ^ 1)] = (digit / 3) ^ xorval;
				eeprom_data[serial_offset * 2 + 20 + (i ^ 1)] = (digit - (2 * (digit / 3))) ^ xorval;
			}
			break;
		}

		case SERIAL_TYPE_ENCRYPT:
		case SERIAL_TYPE_ENCRYPT_XOR:
		{
			int d, e, h, l;

			/* break the serial number out into pieces */
			l = (serial >> 24) & 0xff;
			h = (serial >> 16) & 0xff;
			e = (serial >> 8) & 0xff;
			d = serial & 0xff;

			/* decrypt the data */
			h = ((h ^ 0x2a ^ l) ^ 0xff) + 5;
			d = ((d + 0x2a) ^ e) ^ 0xff;
			l ^= e;
			e ^= 0x2a;

			/* store the bytes */
			eeprom_data[serial_offset * 2 + 0] = h ^ xorval;
			eeprom_data[serial_offset * 2 + 1] = l ^ xorval;
			eeprom_data[serial_offset * 2 + 2] = d ^ xorval;
			eeprom_data[serial_offset * 2 + 3] = e ^ xorval;
			break;
		}
	}
}



/*************************************
 *
 *  EEPROM handling (128 x 16bits)
 *
 *************************************/

void leland_state::ataxx_init_eeprom(const uint16_t *data)
{
	uint8_t eeprom_data[128*2];
	uint8_t serial_offset = 0;
	uint8_t default_val = 0;
	uint32_t serial;

	/*
	    NOTE: This code is just illustrative, and explains how to generate the
	    serial numbers for the classic Leland games. We currently load default
	    EEPROM data from the ROMs rather than generating it.
	*/

	/* initialize everything to the default value */
	memset(eeprom_data, default_val, sizeof(eeprom_data));

	/* fill in the preset data */
	while (*data != 0xffff)
	{
		int offset = *data++;
		int value = *data++;
		eeprom_data[offset * 2 + 0] = value >> 8;
		eeprom_data[offset * 2 + 1] = value & 0xff;
	}

	/* pick a serial number -- examples of real serial numbers:

	    WSF:         30101190
	    Indy Heat:   31201339
	*/
	serial = 0x12345678;

	/* encrypt the serial number */
	{
		int d, e, h, l;

		/* break the serial number out into pieces */
		l = (serial >> 24) & 0xff;
		h = (serial >> 16) & 0xff;
		e = (serial >> 8) & 0xff;
		d = serial & 0xff;

		/* decrypt the data */
		h = ((h ^ 0x2a ^ l) ^ 0xff) + 5;
		d = ((d + 0x2a) ^ e) ^ 0xff;
		l ^= e;
		e ^= 0x2a;

		/* store the bytes */
		eeprom_data[serial_offset * 2 + 0] = h;
		eeprom_data[serial_offset * 2 + 1] = l;
		eeprom_data[serial_offset * 2 + 2] = d;
		eeprom_data[serial_offset * 2 + 3] = e;
	}

	/* compute the checksum */
	{
		int i, sum = 0;
		for (i = 0; i < 0x7f * 2; i++)
			sum += eeprom_data[i];
		sum ^= 0xffff;
		eeprom_data[0x7f * 2 + 0] = (sum >> 8) & 0xff;
		eeprom_data[0x7f * 2 + 1] = sum & 0xff;
	}
}



/*************************************
 *
 *  Ataxx EEPROM interfacing
 *
 *************************************/

READ8_MEMBER(ataxx_state::ataxx_eeprom_r)
{
	int port = ioport("IN2")->read();
	if (LOG_EEPROM) logerror("%s:EE read\n", machine().describe_context());
	return port;
}


WRITE8_MEMBER(ataxx_state::ataxx_eeprom_w)
{
	if (LOG_EEPROM) logerror("%s:EE write %d%d%d\n", machine().describe_context(),
			(data >> 6) & 1, (data >> 5) & 1, (data >> 4) & 1);
	m_eeprom->di_write ((data & 0x10) >> 4);
	m_eeprom->clk_write((data & 0x20) ? ASSERT_LINE : CLEAR_LINE);
	m_eeprom->cs_write ((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
}



/*************************************
 *
 *  Battery backed RAM
 *
 *************************************/

WRITE8_MEMBER(leland_state::leland_battery_ram_w)
{
	if (m_battery_ram_enable)
	{
		if (LOG_BATTERY_RAM) logerror("%04X:BatteryW@%04X=%02X\n", m_master->pc(), offset, data);
		m_battery_ram[offset] = data;
	}
	else
		logerror("%04X:BatteryW@%04X (invalid!)\n", m_master->pc(), offset);
}


WRITE8_MEMBER(ataxx_state::ataxx_battery_ram_w)
{
	if (m_battery_ram_enable)
	{
		if (LOG_BATTERY_RAM) logerror("%04X:BatteryW@%04X=%02X\n", m_master->pc(), offset, data);
		m_battery_ram[offset] = data;
	}
	else if ((m_master_bank & 0x30) == 0x20)
	{
		m_ataxx_qram[((m_master_bank & 0xc0) << 8) | offset] = data;
		m_tilemap->mark_tile_dirty(((m_master_bank & 0x80) << 8) | offset);
	}
	else
		logerror("%04X:BatteryW@%04X (invalid!)\n", m_master->pc(), offset);
}



/*************************************
 *
 *  Master CPU keycard I/O
 *
 ************************************/

/*--------------------------------------------------------------------

  A note about keycards:

  These were apparently static programmable ROMs that could be
  inserted into certain games. The games would then save/load
  statistics on them.

  The data is accessed via a serial protocol, which is
  implemented below. There are two known commands that are
  written; each command is 3 bytes and accesses 128 bytes of
  data from the keycard:

        62 00 80
        9D 00 80

  the last byte appears to specify the length of data to transfer.

  The format of the data on the card is pretty heavily encrypted.
  The first 7 bytes read serves as a header:

        D5 43 49 4E 2A xx yy

  where xx is a game-specific key, and yy is the complement of the
  key. For example, World Series Baseball uses 04/FB. Alley Master
  uses 05/FA.

  The last 112 bytes of data is encrypted via the following method:

        for (i = 16, b = 0x70, r = 0x08; i < 128; i++, b--, r += 0x10)
        {
            uint8_t a = original_data[i] ^ 0xff;
            a = (a >> 3) | (a << 5);
            a = (((a ^ r) + 1 + b) ^ b) - b;
            encrypted_data[i] = a;
        }

  The data that is encrypted is stored alternating with a checksum
  byte. The checksum for a value A is ((A ^ 0xa5) + 0x27) ^ 0x34.

--------------------------------------------------------------------*/

int leland_state::keycard_r()
{
	int result = 0;

	if (LOG_KEYCARDS_FULL) logerror("  (%s:keycard_r)\n", machine().describe_context());

	/* if we have a valid keycard read state, we're reading from the keycard */
	if (m_keycard_state & 0x80)
	{
		/* clock in new data */
		if (m_keycard_bit == 1)
		{
			m_keycard_shift = 0xff;  /* no data, but this is where we would clock it in */
			if (LOG_KEYCARDS) logerror("  (clocked in %02X)\n", m_keycard_shift);
		}

		/* clock in the bit */
		result = (~m_keycard_shift & 1) << ((m_keycard_state >> 4) & 3);
		if (LOG_KEYCARDS) logerror("  (read %02X)\n", result);
	}
	return result;
}

void leland_state::keycard_w(int data)
{
	int new_state = data & 0xb0;
	int new_clock = data & 0x40;

	if (LOG_KEYCARDS_FULL) logerror("  (%s:keycard_w=%02X)\n", machine().describe_context(), data);

	/* check for going active */
	if (!m_keycard_state && new_state)
	{
		m_keycard_command[0] = m_keycard_command[1] = m_keycard_command[2] = 0;
		if (LOG_KEYCARDS) logerror("keycard going active (state=%02X)\n", new_state);
	}

	/* check for going inactive */
	else if (m_keycard_state && !new_state)
	{
		m_keycard_command[0] = m_keycard_command[1] = m_keycard_command[2] = 0;
		if (LOG_KEYCARDS) logerror("keycard going inactive\n");
	}

	/* check for clocks */
	else if (m_keycard_state == new_state)
	{
		/* work off of falling edge */
		if (!new_clock && m_keycard_clock)
		{
			m_keycard_shift >>= 1;
			m_keycard_bit = (m_keycard_bit + 1) & 7;
		}

		/* look for a bit write */
		else if (!new_clock && !m_keycard_clock && !(data & 0x80))
		{
			if (LOG_KEYCARDS) logerror("  (write %02X)\n", data);

			m_keycard_shift &= ~0x80;
			if (data & (1 << ((new_state >> 4) & 3)))
				m_keycard_shift |= 0x80;

			/* clock out the data on the last bit */
			if (m_keycard_bit == 7)
			{
				if (LOG_KEYCARDS) logerror("  (clocked out %02X)\n", m_keycard_shift);
				m_keycard_command[0] = m_keycard_command[1];
				m_keycard_command[1] = m_keycard_command[2];
				m_keycard_command[2] = m_keycard_shift;
				if (m_keycard_command[0] == 0x62 && m_keycard_command[1] == 0x00 && m_keycard_command[2] == 0x80)
				{
					if (LOG_KEYCARDS) logerror("  (got command $62)\n");
				}
			}
		}
	}

	/* error case */
	else
	{
		/* only an error if the selected bit changes; read/write transitions are okay */
		if ((new_state & 0x30) != (m_keycard_state & 0x30))
			if (LOG_KEYCARDS) logerror("ERROR: Caught keycard state transition %02X -> %02X\n", m_keycard_state, new_state);
	}

	m_keycard_state = new_state;
	m_keycard_clock = new_clock;
}



/*************************************
 *
 *  Master CPU analog and keycard I/O
 *
 *************************************/

READ8_MEMBER(leland_state::leland_master_analog_key_r)
{
	int result = 0;

	switch (offset)
	{
		case 0x00:  /* FD = analog data read */
			result = m_analog_result;
			break;

		case 0x01:  /* FE = analog status read */
			/* bit 7 indicates the analog input is busy for some games */
			result = 0x00;
			break;

		case 0x02:  /* FF = keycard serial data read */
			result = keycard_r();

			/* bit 7 indicates the analog input is busy for some games */
			result &= ~0x80;
			break;
	}
	return result;
}



WRITE8_MEMBER(leland_state::leland_master_analog_key_w)
{
	static const char *const portnames[] = { "AN0", "AN1", "AN2", "AN3", "AN4", "AN5" };

	switch (offset)
	{
		case 0x00:  /* FD = analog port trigger */
			break;

		case 0x01:  /* FE = analog port select/bankswitch */
			m_analog_result = ioport(portnames[data & 15])->read();

			/* update top board banking for some games */
			if (LOG_BANKSWITCHING_M)
				if ((m_top_board_bank ^ data) & 0xc0)
					logerror("%04X:top_board_bank = %02X\n", m_master->pc(), data & 0xc0);
			m_top_board_bank = data & 0xc0;
			(this->*m_update_master_bank)();
			break;

		case 0x02:  /* FF = keycard data write */
			keycard_w(data);
			break;
	}
}



/*************************************
 *
 *  Master CPU internal I/O
 *
 *************************************/

READ8_MEMBER(leland_state::leland_master_input_r)
{
	int result = 0xff;

	switch (offset)
	{
		case 0x00:  /* /GIN0 */
			result = ioport("IN0")->read();
			break;

		case 0x01:  /* /GIN1 */
			result = ioport("IN1")->read();
			if (m_slave->state_int(Z80_HALT))
				result ^= 0x01;
			break;

		case 0x02:  /* /GIN2 */
		case 0x12:
			m_master->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
			break;

		case 0x03:  /* /IGID */
		case 0x13:
			if (m_ay8910)
				result &= m_ay8910->data_r(space, 0);

			if (m_ay8912)
				result &= m_ay8912->data_r(space, 0);
			break;

		case 0x10:  /* /GIN0 */
			result = ioport("IN2")->read();
			break;

		case 0x11:  /* /GIN1 */
			result = ioport("IN3")->read();
			if (LOG_EEPROM) logerror("%s:EE read\n", machine().describe_context());
			break;

		default:
			logerror("Master I/O read offset %02X\n", offset);
			break;
	}
	return result;
}


WRITE8_MEMBER(leland_state::leland_master_output_w)
{
	switch (offset)
	{
		case 0x09:  /* /MCONT */
			m_slave->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
			m_wcol_enable = (data & 0x02);
			m_slave->set_input_line(INPUT_LINE_NMI, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE);
			m_slave->set_input_line(0, (data & 0x08) ? CLEAR_LINE : ASSERT_LINE);

			if (LOG_EEPROM) logerror("%s:EE write %d%d%d\n", machine().describe_context(),
					(data >> 6) & 1, (data >> 5) & 1, (data >> 4) & 1);
			m_eeprom->di_write ((data & 0x10) >> 4);
			m_eeprom->clk_write((data & 0x20) ? ASSERT_LINE : CLEAR_LINE);
			m_eeprom->cs_write ((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
			break;

		case 0x0a:  /* /OGIA */
		case 0x0b:  /* /OGID */
			if (m_ay8910)
				m_ay8910->address_data_w(space, offset - 0x0a, data);

			if (m_ay8912)
				m_ay8912->address_data_w(space, offset - 0x0a, data);
			break;

		case 0x0c:  /* /BKXL */
		case 0x0d:  /* /BKXH */
		case 0x0e:  /* /BKYL */
		case 0x0f:  /* /BKYH */
			leland_scroll_w(space, offset - 0x0c, data);
			break;

		default:
			logerror("Master I/O write offset %02X=%02X\n", offset, data);
			break;
	}
}


READ8_MEMBER(ataxx_state::ataxx_master_input_r)
{
	int result = 0xff;

	switch (offset)
	{
		case 0x06:  /* /GIN0 */
			result = ioport("IN0")->read();
			break;

		case 0x07:  /* /SLVBLK */
			result = ioport("IN1")->read();
			if (m_slave->state_int(Z80_HALT))
				result ^= 0x01;
			break;

		default:
			logerror("Master I/O read offset %02X\n", offset);
			break;
	}
	return result;
}


WRITE8_MEMBER(ataxx_state::ataxx_master_output_w)
{
	switch (offset)
	{
		case 0x00:  /* /BKXL */
		case 0x01:  /* /BKXH */
		case 0x02:  /* /BKYL */
		case 0x03:  /* /BKYH */
			leland_scroll_w(space, offset, data);
			break;

		case 0x04:  /* /MBNK */
			if (LOG_BANKSWITCHING_M)
				if ((m_master_bank ^ data) & 0xff)
					logerror("%04X:master_bank = %02X\n", m_master->pc(), data & 0xff);
			m_master_bank = data;
			ataxx_bankswitch();
			break;

		case 0x05:  /* /SLV0 */
			m_slave->set_input_line(0, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
			m_slave->set_input_line(INPUT_LINE_NMI, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE);
			m_slave->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
			break;

		case 0x08:  /*  */
			m_master_int_timer->adjust(m_screen->time_until_pos(data + 1), data + 1);
			break;

		default:
			logerror("Master I/O write offset %02X=%02X\n", offset, data);
			break;
	}
}



/*************************************
 *
 *  Master CPU palette gates
 *
 *************************************/

WRITE8_MEMBER(leland_state::leland_gated_paletteram_w)
{
	if (m_wcol_enable)
		m_palette->write8(space, offset, data);
}


READ8_MEMBER(leland_state::leland_gated_paletteram_r)
{
	if (m_wcol_enable)
		return m_palette->basemem().read8(offset);
	return 0xff;
}


WRITE8_MEMBER(ataxx_state::ataxx_paletteram_and_misc_w)
{
	if (m_wcol_enable)
		m_palette->write8(space, offset, data);
	else if (offset == 0x7f8 || offset == 0x7f9)
		leland_master_video_addr_w(space, offset - 0x7f8, data);
	else if (offset == 0x7fc)
	{
		m_xrom1_addr = (m_xrom1_addr & 0xff00) | (data & 0x00ff);
		if (LOG_XROM) logerror("%04X:XROM1 address low write = %02X (addr=%04X)\n", m_master->pc(), data, m_xrom1_addr);
	}
	else if (offset == 0x7fd)
	{
		m_xrom1_addr = (m_xrom1_addr & 0x00ff) | ((data << 8) & 0xff00);
		if (LOG_XROM) logerror("%04X:XROM1 address high write = %02X (addr=%04X)\n", m_master->pc(), data, m_xrom1_addr);
	}
	else if (offset == 0x7fe)
	{
		m_xrom2_addr = (m_xrom2_addr & 0xff00) | (data & 0x00ff);
		if (LOG_XROM) logerror("%04X:XROM2 address low write = %02X (addr=%04X)\n", m_master->pc(), data, m_xrom2_addr);
	}
	else if (offset == 0x7ff)
	{
		m_xrom2_addr = (m_xrom2_addr & 0x00ff) | ((data << 8) & 0xff00);
		if (LOG_XROM) logerror("%04X:XROM2 address high write = %02X (addr=%04X)\n", m_master->pc(), data, m_xrom2_addr);
	}
	else
		m_extra_tram[offset] = data;
}


READ8_MEMBER(ataxx_state::ataxx_paletteram_and_misc_r)
{
	if (m_wcol_enable)
		return m_palette->basemem().read8(offset);
	else if (offset == 0x7fc || offset == 0x7fd)
	{
		int result = m_xrom_base[0x00000 | m_xrom1_addr | ((offset & 1) << 16)];
		if (LOG_XROM) logerror("%04X:XROM1 read(%d) = %02X (addr=%04X)\n", m_master->pc(), offset - 0x7fc, result, m_xrom1_addr);
		return result;
	}
	else if (offset == 0x7fe || offset == 0x7ff)
	{
		int result = m_xrom_base[0x20000 | m_xrom2_addr | ((offset & 1) << 16)];
		if (LOG_XROM) logerror("%04X:XROM2 read(%d) = %02X (addr=%04X)\n", m_master->pc(), offset - 0x7fc, result, m_xrom2_addr);
		return result;
	}
	else
		return m_extra_tram[offset];
}



/*************************************
 *
 *  AY8910-controlled graphics latch
 *
 *************************************/

READ8_MEMBER(leland_state::leland_sound_port_r)
{
	return m_gfx_control;
}


WRITE8_MEMBER(leland_state::leland_sound_port_w)
{
	/* update the graphics banking */
	leland_gfx_port_w(space, 0, data);

	/* set the new value */
	m_gfx_control = data;
	m_dac_control = data & 3;

	/* some bankswitching occurs here */
	if (LOG_BANKSWITCHING_M)
		if ((m_sound_port_bank ^ data) & 0x24)
			logerror("%s:sound_port_bank = %02X\n", machine().describe_context(), data & 0x24);
	m_sound_port_bank = data & 0x24;
	(this->*m_update_master_bank)();
}



/*************************************
 *
 *  Slave CPU bankswitching
 *
 *************************************/

WRITE8_MEMBER(leland_state::leland_slave_small_banksw_w)
{
	int bankaddress = 0x10000 + 0xc000 * (data & 1);

	if (bankaddress >= m_slave_base.length())
	{
		logerror("%04X:Slave bank %02X out of range!", m_slave->pc(), data & 1);
		bankaddress = 0x10000;
	}
	m_slave_bankslot->set_base(&m_slave_base[bankaddress]);

	if (LOG_BANKSWITCHING_S) logerror("%04X:Slave bank = %02X (%05X)\n", m_slave->pc(), data & 1, bankaddress);
}


WRITE8_MEMBER(leland_state::leland_slave_large_banksw_w)
{
	int bankaddress = 0x10000 + 0x8000 * (data & 15);

	if (bankaddress >= m_slave_base.length())
	{
		logerror("%04X:Slave bank %02X out of range!", m_slave->pc(), data & 15);
		bankaddress = 0x10000;
	}
	m_slave_bankslot->set_base(&m_slave_base[bankaddress]);

	if (LOG_BANKSWITCHING_S) logerror("%04X:Slave bank = %02X (%05X)\n", m_slave->pc(), data & 15, bankaddress);
}


WRITE8_MEMBER(leland_state::ataxx_slave_banksw_w)
{
	int bankaddress, bank = data & 15;

	if (bank == 0)
		bankaddress = 0x2000;
	else
	{
		bankaddress = 0x10000 * bank + 0x8000 * ((data >> 4) & 1);
		if (m_slave_base.length() > 0x100000)
			bankaddress += 0x100000 * ((data >> 5) & 1);
	}

	if (bankaddress >= m_slave_base.length())
	{
		logerror("%04X:Slave bank %02X out of range!", m_slave->pc(), data & 0x3f);
		bankaddress = 0x2000;
	}
	m_slave_bankslot->set_base(&m_slave_base[bankaddress]);

	if (LOG_BANKSWITCHING_S) logerror("%04X:Slave bank = %02X (%05X)\n", m_slave->pc(), data, bankaddress);
}



/*************************************
 *
 *  Slave CPU I/O
 *
 *************************************/

READ8_MEMBER(leland_state::leland_raster_r)
{
	return m_screen->vpos();
}



/*************************************
 *
 *  Driver initialization
 *
 *************************************/

/* also called by Ataxx */
void leland_state::leland_rotate_memory(const char *cpuname)
{
	int startaddr = 0x10000;
	int banks = (memregion(cpuname)->bytes() - startaddr) / 0x8000;
	uint8_t *ram = memregion(cpuname)->base();
	uint8_t temp[0x2000];
	int i;

	for (i = 0; i < banks; i++)
	{
		memmove(temp, &ram[startaddr + 0x0000], 0x2000);
		memmove(&ram[startaddr + 0x0000], &ram[startaddr + 0x2000], 0x6000);
		memmove(&ram[startaddr + 0x6000], temp, 0x2000);
		startaddr += 0x8000;
	}
}