summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/vii.c
blob: 406cd9da72f5ca573f055034cb327860b50115f9 (plain) (tree)
1
2
               
                                         







































































                                                                                         
                             
 
                                      
 







                                      





                                                                                   
                                            



                                                    
                                          
                                               


                                             
























                                                  
                             
















                                          


                                     
                                                                                                         
                                         

                                         

                                                      

          
                                            

                                             




                                                                                                                                                            
                                                                                     



                                                       











                           


                                                  

 
                           


                              
                                                                      
 
                      






                                          
         
      
 




                          
                             


 
                                                      





                                         
                                                         
 
                                                  


                                                   
                                                        
 


                                                                                                       

 
                                                        
 


                                                               

 
                                                                                                                                                              
 
                                                            






























                                                                                   
                                                                                  










                                                            
                                                                              



                                                
                                                              



                                                          
                                                                                


                                            
                                                                                






                                         
                                                                                                                           








                                     
                                                            




















                                                                             
                                                                                     







                                           
                                                                                           







                                               
                                                         
                                                    
                                                                               

                                                    
                                                                                  

                                                    
                                                                                




                                                                     
                                                                                                  



                 
                                                                                                             
 
                                                            


                          
                                                       
 



                                                     










                                                                             
                                  













                                                                                    
                                                                     

 
                                                                                            
 

                 
                                      





                                
                                                          
                 
                                                                               



                 
                                                                                                           
 



                                 
                                                    


                              


                                                                                                   





                                        
                                                                                                                                           











                                      
                                                          





                                                 
                                                                          










                                              
                                                                                                     


                                                    
                                                                                                     


                                                    
                                                                                                                            








                                        
                                                            



                                                            
                                                            


                                                            

                                            



                                                            
                                                                                                       



                                                            
                                                                                                            


                                                      
                                                                                      



                                              
                                                                                                       



                                                            
                                                                                                     



                                                            
                                                                                                       



                                         
                                                                                                                             









                                                            
                                                                                               









                                        
                                                                                                                             





                                            
                                            






















                                                                                                 
                                        






                                                                                  
                                                


                              
                                                      























                                                             
                                                          





                                                                          
                                                                          
















                                                                                                                                                            
                                                                                                                                                               





                                                                              
                                                                                                                                                               



                                                        
                                                                                         


                                         
                                                                                                         


                                        
                                                                                                        



                                                            
                                                                                                                           


                                          
                                                                  
                                                                                               


                                                   
                                                                                                       





                                                                    
                                                                                               


                                        
                                                                                             


                                         
                                                                                              


                              
                                                                                            

















                                                                                                                                                            
                                                                                                        









                                                                         
                                                                                                                                                  



                                                         
                                                   

                                                                              
                                                                                 



                                                                                           
                                                                                 




                                                                                           
                                                                                                          


                                                           
                                                                                      



                                             
                                                                                                              


                                                 
                                                                                      



                                          

                                                                                                   
                                                                                                


                                          
                                                                                                



                                                         
                                                                


                                            
                                                                                                                                    



                                                         
                                                                                                                                    



                                                         
                                                                                                   



                                                         
                                                                                                      



                                                         
                                                                                                   



                                                         
                                                                                                



                                                         
                                                                                               



                                                         
                                                                                                       



                                                         
                                                                                               




                                                             
                                                                                                    













                                                         
                                                                                                                          










                                                         
                                                                                                    








                                            
                                                                                                    





























































                                                                                                             
 
                                               
 
                                            













                                                                                                    
                                                                   









                                         
                                           



                               
                                                  
 

                                                      


                                           
                                        


            

                                                                     
         


                                                                     
                                             

                                                         


                               
 
                                           
 
                             

 
                                           
 
                             

 
                               
 


                                                        
 



                                     
 
                                                          

                                                   
                                                                          

         

                                    
 

                                                                                                            

                        

 
                               


 
                                           
 


                                            

 
                                                



                                         


                


                                                        
 
                            
 

                                                        
         
                                             
                                                                       


         
                                       
                                                               
     
                                                      
         
                                                       
                                                                       

         
                                                        
                                                
                               
         
                                                 
                                                                       

         
                                       
                                                               

     
                                                      
         
                                                
                                                                       
         
                                                      
         
                                                              
                                                                       
         
                                                      
         
                                                                   
                                                                       







                                                  
                                                                    
 




                                                    
                                                               
                                          


                                             
                                                 








                                                  
                                                                    
 




                                                    
                                                               
                                          


                                             
                                                    

                                              
                                                         

                  



                                                  
                                                                    
 
 

                                    




                                                    
                                                               
                                          



                                 





                                    





                                      
                                                      




                                   


















                                                                                                                              
                                                                                                                                   

                                                          










                                                                                                                                                                     
                                                                                                                                                                                                  

                                                                                                                                                                     
// license:MAME
// copyright-holders:Ryan Holtz, Robbbert
/******************************************************************************


    Sport Vii / The Batman
    ----------------------

    MESS driver by Harmony
    Based largely off of Unununium, by Segher


*******************************************************************************

    Short Description:

        Systems run on the SPG243 SoC

    Status:

        Mostly working

    To-Do:

        Audio (SPG243)
        Motion controls (Vii)

    Known u'nSP-Based Systems:

        ND - SPG243 - Some form of Leapfrog "edutainment" system
        ND - SPG243 - Star Wars: Clone Wars
        ND - SPG243 - Toy Story
        ND - SPG243 - Animal Art Studio
        ND - SPG243 - Finding Nemo
         D - SPG243 - The Batman
         D - SPG243 - Wall-E
         D - SPG243 - Chintendo / KenSingTon / Siatronics / Jungle Soft Vii
 Partial D - SPG200 - V-Tech V-Smile
        ND - Likely many more


Similar Systems: ( from http://en.wkikpedia.org/wiki/V.Smile )
- V.Smile by Vtech, a system designed for children under the age of 10
- V.Smile Pocket (2 versions)
- V.SMile Cyber Pocket
- V.Smile PC Pal
- V-Motion Active Learning System
- Leapster
- V.Smile Baby Infant Development System
- V.Flash

Detailed list of bugs:
- When loading a cart from file manager, sometimes it will crash
- On 'vii_vc1' & 'vii_vc2' cart, the left-right keys are transposed with the up-down keys
- The game 'Jewel Master' on both above carts displays a priority error at top of screen
- In the default bios (no cart loaded):
-- In the menu, when 'Come On!' is selected, a graphics error appears
-- Catch Fish, black screen
-- Come On! freezes at the high score screen, controls seem haywire
-- Bird Knight, no controls
-- Lucky Dice, the dice never stop spinning
-- Fever Move, after pressing A it freezes
-- Alacrity Golf, black screen
-- Smart Dart, black screen
-- Happy Tennis, controls are haywire
-- Bowling, freezes at the high score screen


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

#include "emu.h"
#include "cpu/unsp/unsp.h"
#include "imagedev/cartslot.h"
#include "machine/i2cmem.h"
#include "formats/imageutl.h"

#define PAGE_ENABLE_MASK        0x0008

#define PAGE_DEPTH_FLAG_MASK    0x3000
#define PAGE_DEPTH_FLAG_SHIFT   12
#define PAGE_TILE_HEIGHT_MASK   0x00c0
#define PAGE_TILE_HEIGHT_SHIFT  6
#define PAGE_TILE_WIDTH_MASK    0x0030
#define PAGE_TILE_WIDTH_SHIFT   4
#define TILE_X_FLIP             0x0004
#define TILE_Y_FLIP             0x0008

class vii_state : public driver_device
{
public:
	vii_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_p_ram(*this, "p_ram"),
		m_p_rowscroll(*this, "p_rowscroll"),
		m_p_palette(*this, "p_palette"),
		m_p_spriteram(*this, "p_spriteram"),
		m_p_cart(*this, "p_cart"),
		m_region_cpu(*this, "maincpu"),
		m_region_cart(*this, "cart"),
		m_io_p1(*this, "P1")
	{ }

	required_device<cpu_device> m_maincpu;
	DECLARE_READ16_MEMBER(vii_video_r);
	DECLARE_WRITE16_MEMBER(vii_video_w);
	DECLARE_READ16_MEMBER(vii_audio_r);
	DECLARE_WRITE16_MEMBER(vii_audio_w);
	DECLARE_READ16_MEMBER(vii_io_r);
	DECLARE_WRITE16_MEMBER(vii_io_w);
	DECLARE_WRITE16_MEMBER(vii_rowscroll_w);
	DECLARE_WRITE16_MEMBER(vii_spriteram_w);
	required_shared_ptr<UINT16> m_p_ram;
	required_shared_ptr<UINT16> m_p_rowscroll;
	required_shared_ptr<UINT16> m_p_palette;
	required_shared_ptr<UINT16> m_p_spriteram;
	required_shared_ptr<UINT16> m_p_cart;

	UINT32 m_current_bank;

	UINT16 m_video_regs[0x100];
	UINT32 m_centered_coordinates;

	struct
	{
		UINT8 r, g, b;
	}
	m_screenram[320*240];

	UINT16 m_io_regs[0x200];
	UINT16 m_uart_rx_count;
	UINT8 m_controller_input[8];
	UINT32 m_spg243_mode;

	emu_timer *m_tmb1;
	emu_timer *m_tmb2;
	void vii_do_dma(UINT32 len);
	void vii_do_gpio(UINT32 offset);
	void vii_switch_bank(UINT32 bank);
	void vii_do_i2c();
	void spg_do_dma(UINT32 len);
	DECLARE_DRIVER_INIT(vsmile);
	DECLARE_DRIVER_INIT(walle);
	DECLARE_DRIVER_INIT(vii);
	DECLARE_DRIVER_INIT(batman);
	virtual void machine_start();
	virtual void machine_reset();
	virtual void video_start();
	UINT32 screen_update_vii(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	INTERRUPT_GEN_MEMBER(vii_vblank);
	TIMER_CALLBACK_MEMBER(tmb1_tick);
	TIMER_CALLBACK_MEMBER(tmb2_tick);
	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(vii_cart);
	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(vsmile_cart);

protected:
	required_memory_region m_region_cpu;
	optional_memory_region m_region_cart;
	required_ioport m_io_p1;

	void vii_blit(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 xoff, UINT32 yoff, UINT32 attr, UINT32 ctrl, UINT32 bitmap_addr, UINT16 tile);
	void vii_blit_page(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth, UINT32 bitmap_addr, UINT16 *regs);
	void vii_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth, UINT32 base_addr);
	void vii_blit_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth);
	inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3,4);
	inline UINT8 expand_rgb5_to_rgb8(UINT8 val);
	inline UINT8 vii_mix_channel(UINT8 a, UINT8 b);
	void vii_mix_pixel(UINT32 offset, UINT16 rgb);
	void vii_set_pixel(UINT32 offset, UINT16 rgb);
};

enum
{
	SPG243_VII = 0,
	SPG243_BATMAN,
	SPG243_VSMILE,

	SPG243_MODEL_COUNT,
};


#define VII_CTLR_IRQ_ENABLE m_io_regs[0x21]
#define VII_VIDEO_IRQ_ENABLE    m_video_regs[0x62]
#define VII_VIDEO_IRQ_STATUS    m_video_regs[0x63]


#define VERBOSE_LEVEL   (3)

#define ENABLE_VERBOSE_LOG (1)

inline void vii_state::verboselog(int n_level, const char *s_fmt, ...)
{
#if ENABLE_VERBOSE_LOG
	if( VERBOSE_LEVEL >= n_level )
	{
		va_list v;
		char buf[ 32768 ];
		va_start( v, s_fmt );
		vsprintf( buf, s_fmt, v );
		va_end( v );
	}
#endif
}

/*************************
*     Video Hardware     *
*************************/

void vii_state::video_start()
{
}

inline UINT8 vii_state::expand_rgb5_to_rgb8(UINT8 val)
{
	UINT8 temp = val & 0x1f;
	return (temp << 3) | (temp >> 2);
}

// Perform a lerp between a and b
inline UINT8 vii_state::vii_mix_channel(UINT8 a, UINT8 b)
{
	UINT8 alpha = m_video_regs[0x1c] & 0x00ff;
	return ((64 - alpha) * a + alpha * b) / 64;
}

void vii_state::vii_mix_pixel(UINT32 offset, UINT16 rgb)
{
	m_screenram[offset].r = vii_mix_channel(m_screenram[offset].r, expand_rgb5_to_rgb8(rgb >> 10));
	m_screenram[offset].g = vii_mix_channel(m_screenram[offset].g, expand_rgb5_to_rgb8(rgb >> 5));
	m_screenram[offset].b = vii_mix_channel(m_screenram[offset].b, expand_rgb5_to_rgb8(rgb));
}

void vii_state::vii_set_pixel(UINT32 offset, UINT16 rgb)
{
	m_screenram[offset].r = expand_rgb5_to_rgb8(rgb >> 10);
	m_screenram[offset].g = expand_rgb5_to_rgb8(rgb >> 5);
	m_screenram[offset].b = expand_rgb5_to_rgb8(rgb);
}

void vii_state::vii_blit(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT32 xoff, UINT32 yoff, UINT32 attr, UINT32 ctrl, UINT32 bitmap_addr, UINT16 tile)
{
	address_space &space = m_maincpu->space(AS_PROGRAM);

	UINT32 h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
	UINT32 w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);

	UINT32 yflipmask = attr & TILE_Y_FLIP ? h - 1 : 0;
	UINT32 xflipmask = attr & TILE_X_FLIP ? w - 1 : 0;

	UINT32 nc = ((attr & 0x0003) + 1) << 1;

	UINT32 palette_offset = (attr & 0x0f00) >> 4;
	palette_offset >>= nc;
	palette_offset <<= nc;

	UINT32 m = bitmap_addr + nc*w*h/16*tile;
	UINT32 bits = 0;
	UINT32 nbits = 0;

	UINT32 x, y;

	for(y = 0; y < h; y++)
	{
		UINT32 yy = (yoff + (y ^ yflipmask)) & 0x1ff;

		for(x = 0; x < w; x++)
		{
			UINT32 xx = (xoff + (x ^ xflipmask)) & 0x1ff;
			UINT32 pal;

			bits <<= nc;
			if(nbits < nc)
			{
				UINT16 b = space.read_word((m++ & 0x3fffff) << 1);
				b = (b << 8) | (b >> 8);
				bits |= b << (nc - nbits);
				nbits += 16;
			}
			nbits -= nc;

			pal = palette_offset | (bits >> 16);
			bits &= 0xffff;

			if((ctrl & 0x0010) && yy < 240)
			{
				xx = (xx - (INT16)m_p_rowscroll[yy]) & 0x01ff;
			}

			if(xx < 320 && yy < 240)
			{
				UINT16 rgb = m_p_palette[pal];
				if(!(rgb & 0x8000))
				{
					if (attr & 0x4000)
					{
						vii_mix_pixel(xx + 320*yy, rgb);
					}
					else
					{
						vii_set_pixel(xx + 320*yy, rgb);
					}
				}
			}
		}
	}
}

void vii_state::vii_blit_page(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth, UINT32 bitmap_addr, UINT16 *regs)
{
	UINT32 x0, y0;
	UINT32 xscroll = regs[0];
	UINT32 yscroll = regs[1];
	UINT32 attr = regs[2];
	UINT32 ctrl = regs[3];
	UINT32 tilemap = regs[4];
	UINT32 palette_map = regs[5];
	UINT32 h, w, hn, wn;
	address_space &space = m_maincpu->space(AS_PROGRAM);

	if(!(ctrl & PAGE_ENABLE_MASK))
	{
		return;
	}

	if(((attr & PAGE_DEPTH_FLAG_MASK) >> PAGE_DEPTH_FLAG_SHIFT) != depth)
	{
		return;
	}

	h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
	w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);

	hn = 256 / h;
	wn = 512 / w;

	for(y0 = 0; y0 < hn; y0++)
	{
		for(x0 = 0; x0 < wn; x0++)
		{
			UINT16 tile = space.read_word((tilemap + x0 + wn * y0) << 1);
			UINT16 palette = 0;
			UINT32 xx, yy;

			if(!tile)
			{
				continue;
			}

			palette = space.read_word((palette_map + (x0 + wn * y0) / 2) << 1);
			if(x0 & 1)
			{
				palette >>= 8;
			}

			UINT32 tileattr = attr;
			UINT32 tilectrl = ctrl;
			if ((ctrl & 2) == 0)
			{   // -(1) bld(1) flip(2) pal(4)
				tileattr &= ~0x000c;
				tileattr |= (palette >> 2) & 0x000c;    // flip

				tileattr &= ~0x0f00;
				tileattr |= (palette << 8) & 0x0f00;    // palette

				tileattr &= ~0x0100;
				tileattr |= (palette << 2) & 0x0100;    // blend
			}

			yy = ((h*y0 - yscroll + 0x10) & 0xff) - 0x10;
			xx = (w*x0 - xscroll) & 0x1ff;

			vii_blit(bitmap, cliprect, xx, yy, tileattr, tilectrl, bitmap_addr, tile);
		}
	}
}

void vii_state::vii_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth, UINT32 base_addr)
{
	address_space &space = m_maincpu->space(AS_PROGRAM);
	UINT16 tile, attr;
	INT16 x, y;
	UINT32 h, w;
	UINT32 bitmap_addr = 0x40 * m_video_regs[0x22];

	tile = space.read_word((base_addr + 0) << 1);
	x = space.read_word((base_addr + 1) << 1);
	y = space.read_word((base_addr + 2) << 1);
	attr = space.read_word((base_addr + 3) << 1);

	if(!tile)
	{
		return;
	}

	if(((attr & PAGE_DEPTH_FLAG_MASK) >> PAGE_DEPTH_FLAG_SHIFT) != depth)
	{
		return;
	}

	if(m_centered_coordinates)
	{
		x = 160 + x;
		y = 120 - y;

		h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT);
		w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT);

		x -= (w/2);
		y -= (h/2) - 8;
	}

	x &= 0x01ff;
	y &= 0x01ff;

	vii_blit(bitmap, cliprect, x, y, attr, 0, bitmap_addr, tile);
}

void vii_state::vii_blit_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int depth)
{
	UINT32 n;

	if (!(m_video_regs[0x42] & 1))
	{
		return;
	}

	for(n = 0; n < 256; n++)
	{
		//if(space.read_word((0x2c00 + 4*n) << 1))
		{
			vii_blit_sprite(bitmap, cliprect, depth, 0x2c00 + 4*n);
		}
	}
}

UINT32 vii_state::screen_update_vii(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	int i, x, y;

	bitmap.fill(0, cliprect);

	memset(m_screenram, 0, sizeof(m_screenram));

	for(i = 0; i < 4; i++)
	{
		vii_blit_page(bitmap, cliprect, i, 0x40 * m_video_regs[0x20], m_video_regs + 0x10);
		vii_blit_page(bitmap, cliprect, i, 0x40 * m_video_regs[0x21], m_video_regs + 0x16);
		vii_blit_sprites(bitmap, cliprect, i);
	}

	for(y = 0; y < 240; y++)
	{
		for(x = 0; x < 320; x++)
		{
			bitmap.pix32(y, x) = (m_screenram[x + 320*y].r << 16) | (m_screenram[x + 320*y].g << 8) | m_screenram[x + 320*y].b;
		}
	}

	return 0;
}

/*************************
*    Machine Hardware    *
*************************/

void vii_state::vii_do_dma(UINT32 len)
{
	address_space &mem = m_maincpu->space(AS_PROGRAM);
	UINT32 src = m_video_regs[0x70];
	UINT32 dst = m_video_regs[0x71] + 0x2c00;
	UINT32 j;

	for(j = 0; j < len; j++)
	{
		mem.write_word((dst+j) << 1, mem.read_word((src+j) << 1));
	}

	m_video_regs[0x72] = 0;
	m_video_regs[0x63] |= 4;
}

READ16_MEMBER( vii_state::vii_video_r )
{
	switch(offset)
	{
		case 0x62: // Video IRQ Enable
			verboselog(0, "vii_video_r: Video IRQ Enable: %04x\n", VII_VIDEO_IRQ_ENABLE);
			return VII_VIDEO_IRQ_ENABLE;

		case 0x63: // Video IRQ Status
			verboselog(0, "vii_video_r: Video IRQ Status: %04x\n", VII_VIDEO_IRQ_STATUS);
			return VII_VIDEO_IRQ_STATUS;

		default:
			verboselog(0, "vii_video_r: Unknown register %04x = %04x\n", 0x2800 + offset, m_video_regs[offset]);
			break;
	}
	return m_video_regs[offset];
}

WRITE16_MEMBER( vii_state::vii_video_w )
{
	switch(offset)
	{
		case 0x10: case 0x16:   // page 1,2 X scroll
			data &= 0x01ff;
			COMBINE_DATA(&m_video_regs[offset]);
			break;

		case 0x11: case 0x17:   // page 1,2 Y scroll
			data &= 0x00ff;
			COMBINE_DATA(&m_video_regs[offset]);
			break;
		case 0x36:      // IRQ pos V
		case 0x37:      // IRQ pos H
			data &= 0x01ff;
			COMBINE_DATA(&m_video_regs[offset]);
			break;
		case 0x62: // Video IRQ Enable
			verboselog(0, "vii_video_w: Video IRQ Enable = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&VII_VIDEO_IRQ_ENABLE);
			break;

		case 0x63: // Video IRQ Acknowledge
			verboselog(0, "vii_video_w: Video IRQ Acknowledge = %04x (%04x)\n", data, mem_mask);
			VII_VIDEO_IRQ_STATUS &= ~data;
			if(!VII_VIDEO_IRQ_STATUS)
			{
				m_maincpu->set_input_line(UNSP_IRQ0_LINE, CLEAR_LINE);
			}
			break;

		case 0x70: // Video DMA Source
			verboselog(0, "vii_video_w: Video DMA Source = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_video_regs[offset]);
			break;

		case 0x71: // Video DMA Dest
			verboselog(0, "vii_video_w: Video DMA Dest = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_video_regs[offset]);
			break;

		case 0x72: // Video DMA Length
			verboselog(0, "vii_video_w: Video DMA Length = %04x (%04x)\n", data, mem_mask);
			vii_do_dma(data);
			break;

		default:
			verboselog(0, "vii_video_w: Unknown register %04x = %04x (%04x)\n", 0x2800 + offset, data, mem_mask);
			COMBINE_DATA(&m_video_regs[offset]);
			break;
	}
}

READ16_MEMBER( vii_state::vii_audio_r )
{
	switch(offset)
	{
		default:
			verboselog(4, "vii_audio_r: Unknown register %04x\n", 0x3000 + offset);
			break;
	}
	return 0;
}

WRITE16_MEMBER( vii_state::vii_audio_w )
{
	switch(offset)
	{
		default:
			verboselog(4, "vii_audio_w: Unknown register %04x = %04x (%04x)\n", 0x3000 + offset, data, mem_mask);
			break;
	}
}

void vii_state::vii_switch_bank(UINT32 bank)
{
	UINT8 *cart = m_region_cart->base();

	if(bank != m_current_bank)
	{
		m_current_bank = bank;

		memcpy(m_p_cart, cart + 0x400000 * bank * 2 + 0x4000*2, (0x400000 - 0x4000) * 2);
	}
}

void vii_state::vii_do_gpio(UINT32 offset)
{
	UINT32 index  = (offset - 1) / 5;
	UINT16 buffer = m_io_regs[5*index + 2];
	UINT16 dir    = m_io_regs[5*index + 3];
	UINT16 attr   = m_io_regs[5*index + 4];
	UINT16 special= m_io_regs[5*index + 5];

	UINT16 push   = dir;
	UINT16 pull   = (~dir) & (~attr);
	UINT16 what   = (buffer & (push | pull));
	what ^= (dir & ~attr);
	what &= ~special;

	if (m_spg243_mode == SPG243_VII)
	{
		if(index == 1)
		{
			UINT32 bank = ((what & 0x80) >> 7) | ((what & 0x20) >> 4);
			vii_switch_bank(bank);
		}
	}
	else if (m_spg243_mode == SPG243_BATMAN)
	{
		if(index == 0)
		{
			UINT16 temp = m_io_p1->read();
			what |= (temp & 0x0001) ? 0x8000 : 0;
			what |= (temp & 0x0002) ? 0x4000 : 0;
			what |= (temp & 0x0004) ? 0x2000 : 0;
			what |= (temp & 0x0008) ? 0x1000 : 0;
			what |= (temp & 0x0010) ? 0x0800 : 0;
			what |= (temp & 0x0020) ? 0x0400 : 0;
			what |= (temp & 0x0040) ? 0x0200 : 0;
			what |= (temp & 0x0080) ? 0x0100 : 0;
		}

		if(index == 2)
		{
		}
	}

	m_io_regs[5*index + 1] = what;
}

void vii_state::vii_do_i2c()
{
}

void vii_state::spg_do_dma(UINT32 len)
{
	address_space &mem = m_maincpu->space(AS_PROGRAM);

	UINT32 src = ((m_io_regs[0x101] & 0x3f) << 16) | m_io_regs[0x100];
	UINT32 dst = m_io_regs[0x103] & 0x3fff;
	UINT32 j;

	for(j = 0; j < len; j++)
		mem.write_word((dst+j) << 1, mem.read_word((src+j) << 1));

	m_io_regs[0x102] = 0;
}

READ16_MEMBER( vii_state::vii_io_r )
{
	static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
	static const char gpioports[] = { 'A', 'B', 'C' };

	offset -= 0x500;

	UINT16 val = m_io_regs[offset];

	switch(offset)
	{
		case 0x01: case 0x06: case 0x0b: // GPIO Data Port A/B/C
			vii_do_gpio(offset);
			verboselog(3, "vii_io_r: %s %c = %04x (%04x)\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset], mem_mask);
			val = m_io_regs[offset];
			break;

		case 0x02: case 0x03: case 0x04: case 0x05:
		case 0x07: case 0x08: case 0x09: case 0x0a:
		case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Other GPIO regs
			verboselog(3, "vii_io_r: %s %c = %04x (%04x)\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], m_io_regs[offset], mem_mask);
			break;

		case 0x1c: // Random
			val = machine().rand() & 0x00ff;
			verboselog(3, "vii_io_r: Random = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x21: // IRQ Control
			verboselog(3, "vii_io_r: Controller IRQ Control = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x22: // IRQ Status
			verboselog(3, "vii_io_r: Controller IRQ Status = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x2c: case 0x2d: // Timers?
			val = machine().rand() & 0x0000ffff;
			verboselog(3, "vii_io_r: Unknown Timer %d Register = %04x (%04x)\n", offset - 0x2c, val, mem_mask);
			break;

		case 0x2f: // Data Segment
			val = m_maincpu->state_int(UNSP_SR) >> 10;
			verboselog(3, "vii_io_r: Data Segment = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x31: // Unknown, UART Status?
			verboselog(3, "vii_io_r: Unknown (UART Status?) = %04x (%04x)\n", 3, mem_mask);
			val = 3;
			break;

		case 0x36: // UART RX Data
			val = m_controller_input[m_uart_rx_count];
			m_uart_rx_count = (m_uart_rx_count + 1) % 8;
			verboselog(3, "vii_io_r: UART RX Data = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x59: // I2C Status
			verboselog(3, "vii_io_r: I2C Status = %04x (%04x)\n", val, mem_mask);
			break;

		case 0x5e: // I2C Data In
			verboselog(3, "vii_io_r: I2C Data In = %04x (%04x)\n", val, mem_mask);
			break;

		default:
			verboselog(3, "vii_io_r: Unknown register %04x\n", 0x3d00 + offset);
			break;
	}

	return val;
}

WRITE16_MEMBER( vii_state::vii_io_w )
{
	static const char *const gpioregs[] = { "GPIO Data Port", "GPIO Buffer Port", "GPIO Direction Port", "GPIO Attribute Port", "GPIO IRQ/Latch Port" };
	static const char gpioports[3] = { 'A', 'B', 'C' };

	UINT16 temp = 0;

	offset -= 0x500;

	switch(offset)
	{
		case 0x00: // GPIO special function select
			verboselog(3, "vii_io_w: GPIO Function Select = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x01: case 0x06: case 0x0b: // GPIO data, port A/B/C
			offset++;
			// Intentional fallthrough

		case 0x02: case 0x03: case 0x04: case 0x05: // Port A
		case 0x07: case 0x08: case 0x09: case 0x0a: // Port B
		case 0x0c: case 0x0d: case 0x0e: case 0x0f: // Port C
			verboselog(3, "vii_io_w: %s %c = %04x (%04x)\n", gpioregs[(offset - 1) % 5], gpioports[(offset - 1) / 5], data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			vii_do_gpio(offset);
			break;

		case 0x10:      // timebase control
			if ((m_io_regs[offset] & 0x0003) != (data & 0x0003)) {
				UINT16 hz = 8 << (data & 0x0003);
				verboselog(3, "*** TMB1 FREQ set to %dHz\n", hz);
				m_tmb1->adjust(attotime::zero, 0, attotime::from_hz( hz ));
			}
			if ((m_io_regs[offset] & 0x000c) != (data & 0x000c)) {
				UINT16 hz = 128 << ((data & 0x000c) >> 2);
				verboselog(3, "*** TMB2 FREQ set to %dHz\n", hz);
				m_tmb2->adjust(attotime::zero, 0, attotime::from_hz( hz ));
			}
			COMBINE_DATA(&m_io_regs[offset]);
			break;
		case 0x21: // IRQ Enable
			verboselog(3, "vii_io_w: Controller IRQ Control = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&VII_CTLR_IRQ_ENABLE);
			if(!VII_CTLR_IRQ_ENABLE)
			{
				m_maincpu->set_input_line(UNSP_IRQ3_LINE, CLEAR_LINE);
			}
			break;

		case 0x22: // IRQ Acknowledge
			verboselog(3, "vii_io_w: Controller IRQ Acknowledge = %04x (%04x)\n", data, mem_mask);
			m_io_regs[0x22] &= ~data;
			if(!m_io_regs[0x22])
			{
				m_maincpu->set_input_line(UNSP_IRQ3_LINE, CLEAR_LINE);
			}
			break;

		case 0x2f: // Data Segment
			temp = m_maincpu->state_int(UNSP_SR);
			m_maincpu->set_state_int(UNSP_SR, (temp & 0x03ff) | ((data & 0x3f) << 10));
			verboselog(3, "vii_io_w: Data Segment = %04x (%04x)\n", data, mem_mask);
			break;

		case 0x31: // Unknown UART
			verboselog(3, "vii_io_w: Unknown UART = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x32: // UART Reset
			verboselog(3, "vii_io_r: UART Reset\n");
			break;

		case 0x33: // UART Baud Rate
			verboselog(3, "vii_io_w: UART Baud Rate = %u\n", 27000000 / 16 / (0x10000 - (m_io_regs[0x34] << 8) - data));
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x35: // UART TX Data
			verboselog(3, "vii_io_w: UART Baud Rate = %u\n", 27000000 / 16 / (0x10000 - (data << 8) - m_io_regs[0x33]));
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5a: // I2C Access Mode
			verboselog(3, "vii_io_w: I2C Access Mode = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5b: // I2C Device Address
			verboselog(3, "vii_io_w: I2C Device Address = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5c: // I2C Sub-Address
			verboselog(3, "vii_io_w: I2C Sub-Address = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5d: // I2C Data Out
			verboselog(3, "vii_io_w: I2C Data Out = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5e: // I2C Data In
			verboselog(3, "vii_io_w: I2C Data In = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x5f: // I2C Controller Mode
			verboselog(3, "vii_io_w: I2C Controller Mode = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x58: // I2C Command
			verboselog(3, "vii_io_w: I2C Command = %04x (%04x)\n", data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			vii_do_i2c();
			break;

		case 0x59: // I2C Status / IRQ Acknowledge(?)
			verboselog(3, "vii_io_w: I2C Status / Ack = %04x (%04x)\n", data, mem_mask);
			m_io_regs[offset] &= ~data;
			break;

		case 0x100: // DMA Source (L)
		case 0x101: // DMA Source (H)
		case 0x103: // DMA Destination
			COMBINE_DATA(&m_io_regs[offset]);
			break;

		case 0x102: // DMA Length
			spg_do_dma(data);
			break;

		default:
			verboselog(3, "vii_io_w: Unknown register %04x = %04x (%04x)\n", 0x3d00 + offset, data, mem_mask);
			COMBINE_DATA(&m_io_regs[offset]);
			break;
	}
}

/*
WRITE16_MEMBER( vii_state::vii_rowscroll_w )
{
    switch(offset)
    {
        default:
            verboselog(0, "vii_rowscroll_w: %04x = %04x (%04x)\n", 0x2900 + offset, data, mem_mask);
            break;
    }
}

WRITE16_MEMBER( vii_state::vii_spriteram_w )
{
    switch(offset)
    {
        default:
            verboselog(0, "vii_spriteram_w: %04x = %04x (%04x)\n", 0x2c00 + offset, data, mem_mask);
            break;
    }
}
*/

static ADDRESS_MAP_START( vii_mem, AS_PROGRAM, 16, vii_state )
	AM_RANGE( 0x000000, 0x004fff ) AM_RAM AM_SHARE("p_ram")
	AM_RANGE( 0x005000, 0x0051ff ) AM_READWRITE(vii_video_r, vii_video_w)
	AM_RANGE( 0x005200, 0x0055ff ) AM_RAM AM_SHARE("p_rowscroll")
	AM_RANGE( 0x005600, 0x0057ff ) AM_RAM AM_SHARE("p_palette")
	AM_RANGE( 0x005800, 0x005fff ) AM_RAM AM_SHARE("p_spriteram")
	AM_RANGE( 0x006000, 0x006fff ) AM_READWRITE(vii_audio_r, vii_audio_w)
	AM_RANGE( 0x007000, 0x007fff ) AM_READWRITE(vii_io_r,    vii_io_w)
	AM_RANGE( 0x008000, 0x7fffff ) AM_ROM AM_SHARE("p_cart")
ADDRESS_MAP_END

static INPUT_PORTS_START( vii )
	PORT_START("P1")
		PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )    PORT_PLAYER(1) PORT_NAME("Joypad Up")
		PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )  PORT_PLAYER(1) PORT_NAME("Joypad Down")
		PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )  PORT_PLAYER(1) PORT_NAME("Joypad Left")
		PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("Joypad Right")
		PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )        PORT_PLAYER(1) PORT_NAME("Button A")
		PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 )        PORT_PLAYER(1) PORT_NAME("Button B")
		PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 )        PORT_PLAYER(1) PORT_NAME("Button C")
		PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON4 )        PORT_PLAYER(1) PORT_NAME("Button D")
INPUT_PORTS_END

static INPUT_PORTS_START( batman )
	PORT_START("P1")
		PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )    PORT_PLAYER(1) PORT_NAME("Joypad Up")
		PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )  PORT_PLAYER(1) PORT_NAME("Joypad Down")
		PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )  PORT_PLAYER(1) PORT_NAME("Joypad Left")
		PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("Joypad Right")
		PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )        PORT_PLAYER(1) PORT_NAME("A Button")
		PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 )        PORT_PLAYER(1) PORT_NAME("Menu")
		PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 )        PORT_PLAYER(1) PORT_NAME("B Button")
		PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON4 )        PORT_PLAYER(1) PORT_NAME("X Button")
INPUT_PORTS_END

static INPUT_PORTS_START( vsmile )
	PORT_START("P1")
		PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )    PORT_PLAYER(1) PORT_NAME("Joypad Up")
		PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )  PORT_PLAYER(1) PORT_NAME("Joypad Down")
		PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )  PORT_PLAYER(1) PORT_NAME("Joypad Left")
		PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("Joypad Right")
		PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )        PORT_PLAYER(1) PORT_NAME("A Button")
		PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 )        PORT_PLAYER(1) PORT_NAME("Menu")
		PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 )        PORT_PLAYER(1) PORT_NAME("B Button")
		PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON4 )        PORT_PLAYER(1) PORT_NAME("X Button")
INPUT_PORTS_END

static INPUT_PORTS_START( walle )
	PORT_START("P1")
		PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )    PORT_PLAYER(1) PORT_NAME("Joypad Up")
		PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )  PORT_PLAYER(1) PORT_NAME("Joypad Down")
		PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )  PORT_PLAYER(1) PORT_NAME("Joypad Left")
		PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("Joypad Right")
		PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )        PORT_PLAYER(1) PORT_NAME("A Button")
		PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 )        PORT_PLAYER(1) PORT_NAME("B Button")
INPUT_PORTS_END


DEVICE_IMAGE_LOAD_MEMBER( vii_state, vii_cart )
{
	UINT8 *cart = m_region_cart->base();
	if (image.software_entry() == NULL)
	{
		int size = image.length();

		if( image.fread(cart, size ) != size )
		{
			image.seterror( IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file" );
			return IMAGE_INIT_FAIL;
		}
	} else {
		int filesize = image.get_software_region_length("rom");
		memcpy(cart, image.get_software_region("rom"), filesize);
	}

	memcpy(m_p_cart, cart + 0x4000*2, (0x400000 - 0x4000) * 2);

	if( cart[0x3cd808] == 0x99 &&
		cart[0x3cd809] == 0x99 &&
		cart[0x3cd80a] == 0x83 &&
		cart[0x3cd80b] == 0x5e &&
		cart[0x3cd80c] == 0x52 &&
		cart[0x3cd80d] == 0x6b &&
		cart[0x3cd80e] == 0x78 &&
		cart[0x3cd80f] == 0x7f )
	{
		m_centered_coordinates = 0;
	}
	return IMAGE_INIT_PASS;
}

DEVICE_IMAGE_LOAD_MEMBER( vii_state, vsmile_cart )
{
	UINT8 *CART = m_region_cart->base();
	UINT16 *ROM = (UINT16 *) m_region_cpu->base();
	if (image.software_entry() == NULL)
	{
		int size = image.length();
		image.fread(CART, size);
	}
	else
	{
		int size = image.get_software_region_length("rom");
		memcpy(CART, image.get_software_region("rom"), size);
	}

	// for whatever reason if we copy more than this, the CPU
	// is not happy and VSmile won't show anything... bankswitch?
	for (int i = 0; i < 0x800000; i += 2)
		ROM[i / 2] = pick_integer_le(CART, i, 2);

	return IMAGE_INIT_PASS;
}


TIMER_CALLBACK_MEMBER(vii_state::tmb1_tick)
{
	m_io_regs[0x22] |= 1;
}

TIMER_CALLBACK_MEMBER(vii_state::tmb2_tick)
{
	m_io_regs[0x22] |= 2;
}

void vii_state::machine_start()
{
	memset(m_video_regs, 0, 0x100 * sizeof(UINT16));
	memset(m_io_regs, 0, 0x100 * sizeof(UINT16));
	m_current_bank = 0;

	m_controller_input[0] = 0;
	m_controller_input[4] = 0;
	m_controller_input[6] = 0xff;
	m_controller_input[7] = 0;

	if ( m_region_cart && m_spg243_mode == SPG243_VII)
	{
		UINT8 *rom = m_region_cart->base();
		memcpy(m_p_cart, rom + 0x4000*2, (0x400000 - 0x4000) * 2);
	}

	m_video_regs[0x36] = 0xffff;
	m_video_regs[0x37] = 0xffff;

	m_tmb1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vii_state::tmb1_tick),this));
	m_tmb2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vii_state::tmb2_tick),this));
	m_tmb1->reset();
	m_tmb2->reset();
}

void vii_state::machine_reset()
{
}

INTERRUPT_GEN_MEMBER(vii_state::vii_vblank)
{
	UINT32 x = machine().rand() & 0x3ff;
	UINT32 y = machine().rand() & 0x3ff;
	UINT32 z = machine().rand() & 0x3ff;


	m_controller_input[0] = m_io_p1->read();
	m_controller_input[1] = (UINT8)x;
	m_controller_input[2] = (UINT8)y;
	m_controller_input[3] = (UINT8)z;
	m_controller_input[4] = 0;
	x >>= 8;
	y >>= 8;
	z >>= 8;
	m_controller_input[5] = (z << 4) | (y << 2) | x;
	m_controller_input[6] = 0xff;
	m_controller_input[7] = 0;

	m_uart_rx_count = 0;

	VII_VIDEO_IRQ_STATUS = VII_VIDEO_IRQ_ENABLE & 1;
	if(VII_VIDEO_IRQ_STATUS)
	{
		verboselog(0, "Video IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ0_LINE, ASSERT_LINE);
	}

//  {
//      verboselog(0, "audio 1 IRQ\n");
//      m_maincpu->set_input_line(UNSP_IRQ1_LINE, ASSERT_LINE);
//  }
	if(m_io_regs[0x22] & m_io_regs[0x21] & 0x0c00)
	{
		verboselog(0, "timerA, timer B IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ2_LINE, ASSERT_LINE);
	}

	//if(m_io_regs[0x22] & m_io_regs[0x21] & 0x2100)
	// For now trigger always if any enabled
	if(VII_CTLR_IRQ_ENABLE)
	{
		verboselog(0, "UART, ADC IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ3_LINE, ASSERT_LINE);
	}
//  {
//      verboselog(0, "audio 4 IRQ\n");
//      m_maincpu->set_input_line(UNSP_IRQ4_LINE, ASSERT_LINE);
//  }

	if(m_io_regs[0x22] & m_io_regs[0x21] & 0x1200)
	{
		verboselog(0, "External IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ5_LINE, ASSERT_LINE);
	}
	if(m_io_regs[0x22] & m_io_regs[0x21] & 0x0070)
	{
		verboselog(0, "1024Hz, 2048HZ, 4096HZ IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ6_LINE, ASSERT_LINE);
	}
	if(m_io_regs[0x22] & m_io_regs[0x21] & 0x008b)
	{
		verboselog(0, "TMB1, TMB2, 4Hz, key change IRQ\n");
		m_maincpu->set_input_line(UNSP_IRQ7_LINE, ASSERT_LINE);
	}

}

static MACHINE_CONFIG_START( vii, vii_state )

	MCFG_CPU_ADD( "maincpu", UNSP, XTAL_27MHz)
	MCFG_CPU_PROGRAM_MAP( vii_mem )
	MCFG_CPU_VBLANK_INT_DRIVER("screen", vii_state,  vii_vblank)


	MCFG_SCREEN_ADD( "screen", RASTER )
	MCFG_SCREEN_REFRESH_RATE(60)
	MCFG_SCREEN_SIZE(320, 240)
	MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1)
	MCFG_SCREEN_UPDATE_DRIVER(vii_state, screen_update_vii)
	MCFG_PALETTE_ADD("palette", 32768)

	MCFG_CARTSLOT_ADD( "cart" )
	MCFG_CARTSLOT_EXTENSION_LIST( "bin" )
	MCFG_CARTSLOT_LOAD( vii_state, vii_cart )
	MCFG_CARTSLOT_INTERFACE("vii_cart")

	MCFG_SOFTWARE_LIST_ADD("vii_cart","vii")
MACHINE_CONFIG_END

static MACHINE_CONFIG_START( vsmile, vii_state )

	MCFG_CPU_ADD( "maincpu", UNSP, XTAL_27MHz)
	MCFG_CPU_PROGRAM_MAP( vii_mem )
	MCFG_CPU_VBLANK_INT_DRIVER("screen", vii_state,  vii_vblank)


	MCFG_SCREEN_ADD( "screen", RASTER )
	MCFG_SCREEN_REFRESH_RATE(60)
	MCFG_SCREEN_SIZE(320, 240)
	MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1)
	MCFG_SCREEN_UPDATE_DRIVER(vii_state, screen_update_vii)
	MCFG_PALETTE_ADD("palette", 32768)

	MCFG_CARTSLOT_ADD( "cart" )
	MCFG_CARTSLOT_EXTENSION_LIST( "bin" )
	MCFG_CARTSLOT_LOAD( vii_state, vsmile_cart )
	MCFG_CARTSLOT_INTERFACE("vsmile_cart")

	MCFG_SOFTWARE_LIST_ADD("cart_list","vsmile_cart")
MACHINE_CONFIG_END

static MACHINE_CONFIG_START( batman, vii_state )

	MCFG_CPU_ADD( "maincpu", UNSP, XTAL_27MHz)
	MCFG_CPU_PROGRAM_MAP( vii_mem )
	MCFG_CPU_VBLANK_INT_DRIVER("screen", vii_state,  vii_vblank)


	MCFG_I2CMEM_ADD("i2cmem")
	MCFG_I2CMEM_DATA_SIZE(0x200)

	MCFG_SCREEN_ADD( "screen", RASTER )
	MCFG_SCREEN_REFRESH_RATE(60)
	MCFG_SCREEN_SIZE(320, 240)
	MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1)
	MCFG_SCREEN_UPDATE_DRIVER(vii_state, screen_update_vii)
	MCFG_PALETTE_ADD("palette", 32768)
MACHINE_CONFIG_END

DRIVER_INIT_MEMBER(vii_state,vii)
{
	m_spg243_mode = SPG243_VII;
	m_centered_coordinates = 1;
}

DRIVER_INIT_MEMBER(vii_state,batman)
{
	m_spg243_mode = SPG243_BATMAN;
	m_centered_coordinates = 1;
}

DRIVER_INIT_MEMBER(vii_state,vsmile)
{
	m_spg243_mode = SPG243_BATMAN;//SPG243_VSMILE;
	m_centered_coordinates = 1;
}

DRIVER_INIT_MEMBER(vii_state,walle)
{
	m_spg243_mode = SPG243_BATMAN;
	m_centered_coordinates = 0;
}

ROM_START( vii )
	ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )      /* dummy region for u'nSP */

	ROM_REGION( 0x2000000, "cart", ROMREGION_ERASE00 )
	ROM_LOAD( "vii.bin", 0x0000, 0x2000000, CRC(04627639) SHA1(f883a92d31b53c9a5b0cdb112d07cd793c95fc43))
	ROM_CART_LOAD("cart", 0x0000, 0x2000000, ROM_MIRROR)
ROM_END

ROM_START( batmantv )
	ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )      /* dummy region for u'nSP */
	ROM_LOAD16_WORD_SWAP( "batman.bin", 0x000000, 0x400000, CRC(46f848e5) SHA1(5875d57bb3fe0cac5d20e626e4f82a0e5f9bb94c) )
ROM_END

ROM_START( vsmile )
	ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )      /* dummy region for u'nSP */
	ROM_LOAD16_WORD_SWAP( "bios german.bin", 0x000000, 0x200000, CRC(205c5296) SHA1(7fbcf761b5885c8b1524607aabaf364b4559c8cc) )

	ROM_REGION( 0x2000000, "cart", ROMREGION_ERASE00 )
ROM_END

ROM_START( walle )
	ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )      /* dummy region for u'nSP */
	ROM_LOAD16_WORD_SWAP( "walle.bin", 0x000000, 0x400000, BAD_DUMP CRC(bd554cba) SHA1(6cd06a036ab12e7b0e1fd8003db873b0bb783868) )
	// Alternate dump, we need to decide which one is correct.
	//ROM_LOAD16_WORD_SWAP( "walle.bin", 0x000000, 0x400000, CRC(6bc90b16) SHA1(184d72de059057aae7800da510fcf05ed1da9ec9))
ROM_END

/*    YEAR  NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      COMPANY                                              FULLNAME      FLAGS */
CONS( 2004, batmantv, vii,      0,        batman,   batman, vii_state,   batman,   "JAKKS Pacific Inc / HotGen Ltd",                    "The Batman", GAME_NO_SOUND )
CONS( 2005, vsmile,   0,        0,        vsmile,   vsmile, vii_state,   vsmile,   "V-Tech",                                            "V-Smile (Germany)",    GAME_NO_SOUND | GAME_NOT_WORKING )
CONS( 2007, vii,      0,        0,        vii,      vii, vii_state,      vii,      "Jungle Soft / KenSingTon / Chintendo / Siatronics", "Vii",        GAME_NO_SOUND )
CONS( 2008, walle,    vii,      0,        batman,   walle, vii_state,    walle,    "JAKKS Pacific Inc",                                 "Wall-E",     GAME_NO_SOUND )