summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/ygv608.cpp
blob: 31ef389a673e5fde21f4309597cc6a0cda80afea (plain) (tree)
1
2
                       
                                                  




























                                                                         
  
                               


                                                                        
                                          
                                                 

                                                                          
                                        
                                                                                                                          

                                                                             
                                                                                                                         
                                                                                                    


                                  
   

 
                
                         

                   
 
 
                              

                                


                                

                                                                      
                                


















                              


                              

       

                                














                              


                              








                              



                               

                           






                         
 
 





                                                                            
 
                           
 
                                                    
 


                                                                                      
 
                                                    
 









































                                                                                              
 



































                                                     
                                    



                                                                                    

                                                                                    

             









                                                                            
                                               

                                              

                           

                                                                                                               
 
                                                                                                     
 



                                                                                                     
 
                         







                                                                                                     
                            

                                                                                         
                       
                                                           
 
                         





                                                      

               
                                                   

                                                   
 






                                         

                                              







                                                                                                                 
 
 



                                                   
 
                                                                                                               
                                                       
                                                                        
                                                  
                                                   
                                                 
                                                                                                                         










                                

                                  







                                   



                                      

                               
                                   





                               


                                       





                               







                                          
                  



                             

                              

                                       


                            

                                       
                             

                        



                                  
                                  














                                  
 













                                                                                                   






                                                   

                                         


















                                                                               

                                



                                                           


                                                                                                                                                                                                                                 
 


                                                                                                                                                                                                                                     
 


                                                                                                                                                                                                                                 
 


                                                                                                                                                                                                                                     




                                  
 
                                      



                                                   
 







                                                   
                                                                                       
 
                                    

                                                         

 












                                                               






                                                                                            
                                           




                                                      
                                           
 


                                                                        
                              



                 
 
                                                
 
                                     
                                

 



                                                       
 

                                                     
 






                                                       
 
                                                       
 

                                                                       
                                              




                                     
                    
 
                                                        
 


                                                 
                                                      
 
                           
                                              
                                                          
                                                                                
                                                     
 
                             
         
                                                    
         
                                  
         
                                                    



                                 

                                                                                       
                          
 
                              
                 
                                                                                   

                                                                
                                                                      
 
                                           
                         

                                                                                        
                         



                                                                   

                                   
                 




















                                                                                             

                 
                             
 
                                                            

                                                                      





                                                             
                                              


                                                                
                                                                                           



                                        
                                                          


                             
                                                         

                 
                                                              


         
                                                        



                                                 
                                                      
 
                           

                                                                         
                                           
                                                     
 
                              
         
                                                    
         
                                 
         
                                                    
         
                                 
         
                                                    



                                 

                                                                                       
                          
 
                             
                 

                                                                                   
 
                                           
                         

                                                                                        
                         



                                                                   

                                   
                 




















                                                                                             

                 

                             
                                                            

                                                                      





                                                             
                                              
                 
                                                               







                                                                    
                                                          


                             
                                                         

                 
                                                       


         
                                                         
 


                                                 
                                                      
 
                           
                                              
                                                          
                                                                                    
                                                     
 
                               
                                            
         
                                    
                                            



                         
                                                                 


                               


                                                                           

                                                        
                                                              
 
                                   
                 

                                                                        




                                                           

                           

              
















                                                                                     

         

                     
                                                    

                                                             

                                      
                                               


                      
                                      


                                                        
                                                                            




                                  
                                                 


                     
                                                 


         
                                               
         

 
                                                         
 


                                                 
                                                      
 
                           

                                                                         
                                             
                                                     
 
                               
                                            
         
                               
                                            
         
                                    
                                            



                         
                                                                 


                               



                                                                           
 
                                   
                 

                                                                                




                                                           

                           

              
















                                                                                     

         

                     
                                                    

                                                             

                                      
                                               


                      
                                      
         
                                                       







                                                      
                                                 


                     
                                                 

         
                                               
         

 
                                      
 

                                

 
                                         
 

                               



                                                    

                                         
























































































                                                  

 
 
                                                                                 

                      




                                                                               








                                                         
                                                              
                       


                               

                                                        
         
                                                                 
 




                                                                                       
                                           
 




                                                              
                 




                                                                
                 
 
                                                               




                                                                                                        
                                                
                 

                                                                     
                 
























                                                                              
 
         




                        





                                   
 
                                                                        

      

                                                                                                                                            


                                                           




                                                                
                                                                      
                                                        
                                                                      
 
                            
         






                                                              
 



                                                             
                                                                  

                                                                                              




                                                                      

                                                                                              
                       





                       


                                         



                                                                  
                                                                              


                 
 
                                                                                                             

                        
                        
      
                      
                
      


                      
                            
                                                         

                                     
                                                                     
                              

                                                                         
 
                                  
                                           
         


                         
                             
         
                                                                      

                                    
                                        

         
                              



                                                            
                                   
                                  
                                        



                                  
                                               
                                                                 
                    

                                                                  
 
                                                                 








                                                               
 
                                               
                                                                 
                    

                                                                  
 







                                                               

                                                                         
                                                  

                                    
                                         



                      
                                         
         
                                                              
 






                                                                                      
         




                      


                                                           
 
                                             

                                                                                      

                                             

                                                                                      
         


      

                                            
                                       
            
                                                    
 

                                      


          

                                          
 

                                                                                                        
                             

                                                                                              

                                                 

            

                                                                              

                                                                                      
 



                                                                                           
         
 
                                                             

                                                               
                                        
 

                                               
                                                
 
                                                                      

                                                                              
 



                                                                                   
 

                                              
                                                


                        
                                             
                                         
                                                           
                                      
                                                     
                                          



                                                                        

                                          



                                                                        
                                      



                 







                                                   
 
                   
 
                           
         

                                                          
                                                                                   
                                                                                                
 
                                                     
                                                                                                                
                              
 

                                                     
                                                                                                                    






                                                                  
                                                      
                                                                            
                                   
                                              
                                           
                                              
                                                              


                                   
 
                     
                                    
                             
 
                            
         
                                             

                                          
         
 

                                        
 


                                            
                                                                   
 
                           
                                   
 

                   
 
                          

                                            
                                                                                      
 
                           
         
                                   
                                               
                                          
                                                      

         
                   

 

                                             
 
                                                                           
 
                                    
         

                                    
                                  
                                            
         
 





                                            
                                               
                                                   
 
 
                                         
         



                                                          
                                 
                 


                                                                            
                      
         
 

                   
 
                     






                                                                                 

                                            
                                                                                                              
                                                                                     
 
 


                                               
                            
 
 



                                                  
 
                           


                                                          
                                                                                   
                                                                                                
 
                                                     
                                                                                                                

                              

                                                     
                                                                                                                    
                              



                      
                                                                   
                                                       
                                                      
                                                                            
                                   
                                              
                                           
                                              
                                                              





                                        
                     
                                    
                             
 
                            
         
                                             

                                          











                                                       
                 

                                                      
                         

                                                                             
                         
                 






                                                     
                 

                                                      
                         

                                                                             

                         

                                    
         
 
 


                                             
                                                            
 
                           
                                   
 
 


                                             
                                                                               
 
                           
         
                                   
                                               
                                          
                                                      


         


                                              
                                                                    
                                   
         
                                    

                                                                                                                          
                                                


                                                                           
 
                                  
                                            





                                               
                                                   
                                                     
 
                                            
 
                                         
         

                                           
 

                                                          




                                                                             
                      





                                                 


                                           





                                             
                                 
 
                                                       
                    
                                             
                       
                                             




                                                

                                
                                                

                                


 
                              
                                 
 
              
                              

                                                                                 

                                  


                                     
 
                                           




                                               

                                  

                                

                                                
                                                 

                                                







                                                                  
                                                    
 
                                             
 
     
                                                      

                                                                    
 
                                                    
                                                
              
 


                                                 
 
                                                      
 
                                
                            
         
 
                          


                                     
                              
 


                                                      
 
         
 
                              
                         
         
 
                                    
                            
                                         
 


                                                      
 
         
 
                              
                         
         


      





                                          


                                                     
                                                                                   






                                                      

                                                                                         
                                   
                                      
                                            
                                         

                                                                                      




                                                     
                                                    






                                                      

                                                                                         
                                   
                                      
                                         

                                                                                      

 







                                                                           
                                                                          



                                                
                                                  









                                                                         
                                               



                             
 











                                                
 


































                                                 
 














                                                                            
                                                           






                                               
                                        





                             
 
                                                       
 
                                                                             
                       

                                
                       


                                               
 
                                                     
 

                                         
            
         
                                          



                                      
                    





















                                                                
                                                                      






                                               
                                        


                                       
                                         
                                        
                                  
 

                             














                                                                           
                                                       




                                               
 
                                     
                                        
 
                                 
                                   


                                                            
 

















                                                                                
 







                                                                                                                                         
                                               
 


                                                                                                                    
 
                                          
                                                
 



                                              
                       
                                            
                                   

                                                                              





                                                 
                                                                                              










                                                
 
 













                                                                                             





                                              

                                         
 

                                                                   
 




                                          
 


                                               
 
 



                                         
 




                                               
 
                                                       
 
                                                      
         
 

                   
 










                                                 
 

                                                      
 

                                                       
 






                                                                                                                       
                                                       

                                            
 









                                                                                    
 
                                                                                               
                                                                            

 
                             
  

                                      
                                  






                                                       
 
                                

 

















                                                                                                
                     






















                                                                                                 
 


                                                              
 






                                                                    
 












                                                                      
 

                        
                                                                   
 
                                                
                                                              
 
                                                                     
                                                       
 
                                                                 

                              
 





                                                                    
 


                                                
                                                              
 
                                                                                                                                                         

                              
 





                                                                 
 

                        
                                                                   
 

                                                                       
                                                       
 
                                                                   

                              
 



                                                          
 
                                            

                                                            

                              
 



                                                     
 
                                                                                    











                                                                                                                                                           
                                                                                
                                                          
                                                                           




                                                                                                      

                                                                                                             
                                                                                                                                                                
 
                                                                               
 

                                

                                                                                                                                     
 
 
 
// license:BSD-3-Clause
// copyright-holders:Mark McDougall, Angelo Salese

/*
 *    Yamaha YGV608 - PVDC2 Pattern mode Video Display Controller 2
 *    - Mark McDougall
 *
 *    Notes:
 *    ======
 *
 *    This implementation is far from complete.
 *    There's enough here to emulate Namco ND-1 games.
 *    Some functionality is missing, some is incomplete.
 *    Also missing for ND-1 is rotation and scaling (cosmetic only).
 *
 *    It could also do with some optimisation for speed!
 *
 *    (Still lots of debugging info/options in here!)
 *
 *    TODO: soon
 *    create tilemaps at vh_start time and switch between at runtime
 *    mark tiles dirty when VRAM is written to instead of dirtying entire
 *       screen each frame
 *
 *    T.B.D. (not critical to ND-1)
 *    ======
 *
 *    Rotation
 *    Scaling
 *    Split-screen scrolling by row (by column supported) (see test mode)
 *    Everything else! :)
 *
 *    TODO (2017-2018 edition):
 *    - move ports into device_address_map (done);
 *    - add registers into own space, improve naming and variable usage;
 *    - remove code repetition in tilemap drawing functions;
 *    - add crtc section (done partially);
 *    - fix garbage tiles in Mappy Arrange (done)
 *    - fix tile encryption for Abnormal Check (sets extra bit in cuskey);
 *      nopping bit 0 writes to 0x40081e makes gfxs to draw better!?
 *    - fix Gynotai row scroll glitches;
 *    - fix attract mode garbage for Namco Collection Vol. 2 (either transparent or page banking select registers) (done);
 *    - fix tilemap dirty flags, move tilemap data in own space prolly helps;
 *    - DMA from/to ROM;
 *    - color palette accessors presumably accesses an internal RAMDAC with controllable auto-increment, convert to that;
 *    - fix char getting cut off from GAME SELECT msg in NCV2 (done, sprite wraparound for sx & sy);
 *    - clean-ups & documentation;
 *
 *
 */


#include "emu.h"
#include "video/ygv608.h"
#include "screen.h"



// TODO: move these into enums
// R#7(md)
#define MD_2PLANE_8BIT      0x00
#define MD_2PLANE_16BIT     0x01
#define MD_1PLANE_16COLOUR  0x02
#define MD_1PLANE_256COLOUR 0x03
#define MD_1PLANE           (MD_1PLANE_16COLOUR & MD_1PLANE_256COLOUR)
#define MD_SHIFT            0
#define MD_MASK             0x03

// R#8
#define PGS_64X32         0x0
#define PGS_32X64         0x1
#define PGS_SHIFT         0
#define PGS_MASK          0x01

// R#9
#define SLV_SCREEN        0x00
#define SLV_8             0x04
#define SLV_16            0x05
#define SLV_32            0x06
#define SLV_64            0x07
#define SLH_SCREEN        0x00
#define SLH_8             0x04
#define SLH_16            0x05
#define SLH_32            0x06
#define SLH_64            0x07
#define PTS_8X8           0x00
#define PTS_16X16         0x01
#define PTS_32X32         0x02
#define PTS_64X64         0x03

// R#10
#define SPAS_SPRITESIZE    false
#define SPAS_SPRITEREVERSE true

// R#10(spas)=1
#define SZ_8X8            0x00
#define SZ_16X16          0x01
#define SZ_32X32          0x02
#define SZ_64X64          0x03

// R#10(spas)=0
#define SZ_NOREVERSE      0x00
#define SZ_VERTREVERSE    0x01
#define SZ_HORIZREVERSE   0x02
#define SZ_BOTHREVERSE    0x03

// R#11(prm)
#define PRM_SABDEX        0x00
#define PRM_ASBDEX        0x01
#define PRM_SEABDX        0x02
#define PRM_ASEBDX        0x03

// R#40
#define HDW_SHIFT         0
#define HDW_MASK          0x3f

// R#44
#define VDW_SHIFT         0
#define VDW_MASK          0x3f

#define _ENABLE_SPRITES
#define _ENABLE_SCROLLX
#define _ENABLE_SCROLLY
//#define _ENABLE_SCREEN_RESIZE
//#define _SHOW_VIDEO_DEBUG

#define GFX_8X8_4BIT    0
#define GFX_16X16_4BIT  1
#define GFX_32X32_4BIT  2
#define GFX_64X64_4BIT  3
#define GFX_8X8_8BIT    4
#define GFX_16X16_8BIT  5



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

// device type definition
DEFINE_DEVICE_TYPE(YGV608, ygv608_device, "ygv608", "YGV608 VDP")

/* text-layer characters */

static const uint32_t pts_4bits_layout_xoffset[64] =
{
	STEP8( 0*256, 4 ), STEP8( 1*256, 4 ), STEP8( 4*256, 4 ), STEP8( 5*256, 4 ),
	STEP8( 16*256, 4 ), STEP8( 17*256, 4 ), STEP8( 20*256, 4 ), STEP8( 21*256, 4 )
};

static const uint32_t pts_4bits_layout_yoffset[64] =
{
	STEP8( 0*256, 8*4 ), STEP8( 2*256, 8*4 ), STEP8( 8*256, 8*4 ), STEP8( 10*256, 8*4 ),
	STEP8( 32*256, 8*4 ), STEP8( 34*256, 8*4 ), STEP8( 40*256, 8*4 ), STEP8( 42*256, 8*4 )
};

static const gfx_layout pts_8x8_4bits_layout =
{
	8,8,          /* 8*8 pixels */
	RGN_FRAC(1,1),        /* 65536 patterns */
	4,            /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	EXTENDED_XOFFS,
	EXTENDED_YOFFS,
	8*8*4,
	pts_4bits_layout_xoffset,
	pts_4bits_layout_yoffset
};

static const gfx_layout pts_16x16_4bits_layout =
{
	16,16,        /* 16*16 pixels */
	RGN_FRAC(1,1),        /* 16384 patterns */
	4,            /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	EXTENDED_XOFFS,
	EXTENDED_YOFFS,
	16*16*4,
	pts_4bits_layout_xoffset,
	pts_4bits_layout_yoffset
};

static const gfx_layout pts_32x32_4bits_layout =
{
	32,32,        /* 32*32 pixels */
	RGN_FRAC(1,1),         /* 4096 patterns */
	4,            /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	EXTENDED_XOFFS,
	EXTENDED_YOFFS,
	32*32*4,
	pts_4bits_layout_xoffset,
	pts_4bits_layout_yoffset
};

static const gfx_layout pts_64x64_4bits_layout =
{
	64,64,        /* 32*32 pixels */
	RGN_FRAC(1,1),         /* 1024 patterns */
	4,            /* 4 bits per pixel */
	{ 0, 1, 2, 3 },
	EXTENDED_XOFFS,
	EXTENDED_YOFFS,
	64*64*4,
	pts_4bits_layout_xoffset,
	pts_4bits_layout_yoffset
};


static const gfx_layout pts_8x8_8bits_layout =
{
	8,8,          /* 8*8 pixels */
	RGN_FRAC(1,1),        /* 32768 patterns */
	8,            /* 8 bits per pixel */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ STEP8( 0*512, 8 ) },
	{ STEP8( 0*512, 8*8 ) },
	8*8*8
};

static const gfx_layout pts_16x16_8bits_layout =
{
	16,16,        /* 16*16 pixels */
	RGN_FRAC(1,1),         /* 8192 patterns */
	8,            /* 8 bits per pixel */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ STEP8( 0*512, 8 ), STEP8( 1*512, 8 ) },
	{ STEP8( 0*512, 8*8 ), STEP8( 2*512, 8*8 ) },
	16*16*8
};

static GFXDECODE_START( gfx_ygv608 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_8x8_4bits_layout,    0,  16 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_16x16_4bits_layout,  0,  16 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_32x32_4bits_layout,  0,  16 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_64x64_4bits_layout,  0,  16 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_8x8_8bits_layout,    0,   1 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x00000000, pts_16x16_8bits_layout,  0,   1 )
GFXDECODE_END

//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

/***************************************
 *
 * Internal I/O register structure
 *
 ***************************************/

 // we use decimals here to match documentation
void ygv608_device::regs_map(address_map &map)
{

	// address pointers
	map(0, 0).rw(FUNC(ygv608_device::pattern_name_table_y_r), FUNC(ygv608_device::pattern_name_table_y_w));
	map(1, 1).rw(FUNC(ygv608_device::pattern_name_table_x_r), FUNC(ygv608_device::pattern_name_table_x_w));

	map(2, 2).rw(FUNC(ygv608_device::ram_access_ctrl_r), FUNC(ygv608_device::ram_access_ctrl_w));

	map(3, 3).rw(FUNC(ygv608_device::sprite_address_r), FUNC(ygv608_device::sprite_address_w));
	map(4, 4).rw(FUNC(ygv608_device::scroll_address_r), FUNC(ygv608_device::scroll_address_w));
	map(5, 5).rw(FUNC(ygv608_device::palette_address_r), FUNC(ygv608_device::palette_address_w));
	map(6, 6).rw(FUNC(ygv608_device::sprite_bank_r), FUNC(ygv608_device::sprite_bank_w));

	// screen control
	map(7, 7).rw(FUNC(ygv608_device::screen_ctrl_7_r), FUNC(ygv608_device::screen_ctrl_7_w));
	map(8, 8).rw(FUNC(ygv608_device::screen_ctrl_8_r), FUNC(ygv608_device::screen_ctrl_8_w));
	map(9, 9).rw(FUNC(ygv608_device::screen_ctrl_9_r), FUNC(ygv608_device::screen_ctrl_9_w));
	map(10, 10).rw(FUNC(ygv608_device::screen_ctrl_10_r), FUNC(ygv608_device::screen_ctrl_10_w));
	map(11, 11).rw(FUNC(ygv608_device::screen_ctrl_11_r), FUNC(ygv608_device::screen_ctrl_11_w));
	map(12, 12).rw(FUNC(ygv608_device::screen_ctrl_12_r), FUNC(ygv608_device::screen_ctrl_12_w));

	map(13, 13).w(FUNC(ygv608_device::border_color_w));
	// interrupt section
	map(14, 14).rw(FUNC(ygv608_device::irq_mask_r), FUNC(ygv608_device::irq_mask_w));
	map(15, 16).rw(FUNC(ygv608_device::irq_ctrl_r), FUNC(ygv608_device::irq_ctrl_w));
	// base address
	map(17, 24).w(FUNC(ygv608_device::base_address_w));

	// ROZ parameters
	map(25, 27).w(FUNC(ygv608_device::roz_ax_w));
	map(28, 29).w(FUNC(ygv608_device::roz_dx_w));
	map(30, 31).w(FUNC(ygv608_device::roz_dxy_w));
	map(32, 34).w(FUNC(ygv608_device::roz_ay_w));
	map(35, 36).w(FUNC(ygv608_device::roz_dy_w));
	map(37, 38).w(FUNC(ygv608_device::roz_dyx_w));

	// CRTC
	map(39, 46).w(FUNC(ygv608_device::crtc_w));
//  47-48 ROM transfer control - DMA source address
//  49 ROM transfer control - DMA size
}

/***************************************
 *
 * Port Interface map
 *
 ***************************************/

void ygv608_device::port_map(address_map &map)
{
	map(0x00, 0x00).rw(FUNC(ygv608_device::pattern_name_table_r), FUNC(ygv608_device::pattern_name_table_w));
	map(0x01, 0x01).rw(FUNC(ygv608_device::sprite_data_r), FUNC(ygv608_device::sprite_data_w));
	map(0x02, 0x02).rw(FUNC(ygv608_device::scroll_data_r), FUNC(ygv608_device::scroll_data_w));
	map(0x03, 0x03).rw(FUNC(ygv608_device::palette_data_r), FUNC(ygv608_device::palette_data_w));
	map(0x04, 0x04).rw(FUNC(ygv608_device::register_data_r), FUNC(ygv608_device::register_data_w));
	map(0x05, 0x05).nopr().w(FUNC(ygv608_device::register_select_w));
	map(0x06, 0x06).rw(FUNC(ygv608_device::status_port_r), FUNC(ygv608_device::status_port_w));
	map(0x07, 0x07).rw(FUNC(ygv608_device::system_control_r), FUNC(ygv608_device::system_control_w));
}


//-------------------------------------------------
//  ygv608_device - constructor
//-------------------------------------------------

ygv608_device::ygv608_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock )
	: device_t(mconfig, YGV608, tag, owner, clock),
	  device_gfx_interface(mconfig, *this, gfx_ygv608, DEVICE_SELF),
	  device_memory_interface(mconfig, *this),
	  device_palette_interface(mconfig, *this),
	  device_video_interface(mconfig, *this),
	  m_io_space_config("io", ENDIANNESS_BIG, 8, 6, 0, address_map_constructor(FUNC(ygv608_device::regs_map), this)),
	  m_namcond1_gfxbank(0),
	  m_tilemap_A(nullptr),
	  m_tilemap_B(nullptr),
	  m_work_bitmap(0),
	  m_bits16(0),
	  m_page_x(0),
	  m_page_y(0),
	  m_pny_shift(0),
	  m_na8_mask(0),
	  m_col_shift(0),
	  m_base_y_shift(0),
	  m_screen_resize(false),
	  m_tilemap_resize(false),
	  m_color_state_r(0),
	  m_color_state_w(0),
	  m_p0_state(0),
	  m_pattern_name_base_r(0),
	  m_pattern_name_base_w(0),
	  m_screen_status(0),
	  m_dma_status(0),
	  m_register_address(0),
	  m_register_autoinc_r(false),
	  m_register_autoinc_w(false),
	  m_raster_irq_mask(false),
	  m_vblank_irq_mask(false),
	  m_raster_irq_hpos(0),
	  m_raster_irq_vpos(0),
	  m_raster_irq_mode(false),
	  m_scroll_address(0),
	  m_palette_address(0),
	  m_sprite_address(0),
	  m_sprite_bank(0),
	  m_xtile_ptr(0),
	  m_ytile_ptr(0),
	  m_xtile_autoinc(false),
	  m_ytile_autoinc(false),
	  m_plane_select_access(false),
	  m_mosaic_aplane(0),
	  m_mosaic_bplane(0),
	  m_sprite_disable(0),
	  m_sprite_aux_mode(0),
	  m_sprite_aux_reg(0),
	  m_border_color(0),
	  m_saar(false),
	  m_saaw(false),
	  m_scar(false),
	  m_scaw(false),
	  m_cpar(false),
	  m_cpaw(false),
	  m_ba_plane_scroll_select(false),
	  m_dspe(false),
	  m_md(0),
	  m_zron(false),
	  m_flip(false),
	  m_dckm(false),
	  m_page_size(false),
	  m_h_display_size(0),
	  m_v_display_size(0),
	  m_roz_wrap_disable(false),
	  m_scroll_wrap_disable(false),
	  m_pattern_size(0),
	  m_h_div_size(0),
	  m_v_div_size(0),
	  m_planeA_trans_enable(false),
	  m_planeB_trans_enable(false),
	  m_priority_mode(0),
	  m_cbdr(false),
	  m_yse(false),
	  m_scm(0),
	  m_planeA_color_fetch(0),
	  m_planeB_color_fetch(0),
	  m_sprite_color_fetch(0),
	  m_vblank_handler(*this),
	  m_raster_handler(*this),
	  m_vblank_timer(nullptr),
	  m_raster_timer(nullptr),
	  m_ax(0),
	  m_dx(0),
	  m_dxy(0),
	  m_ay(0),
	  m_dy(0),
	  m_dyx(0),
	  m_raw_ax(0),
	  m_raw_dx(0),
	  m_raw_dxy(0),
	  m_raw_ay(0),
	  m_raw_dy(0),
	  m_raw_dyx(0)
{
	std::fill(std::begin(m_pattern_name_table), std::end(m_pattern_name_table), 0);
	std::fill(std::begin(m_tilemap_A_cache_8), std::end(m_tilemap_A_cache_8), nullptr);
	std::fill(std::begin(m_tilemap_A_cache_16), std::end(m_tilemap_A_cache_16), nullptr);
	std::fill(std::begin(m_tilemap_B_cache_8), std::end(m_tilemap_B_cache_8), nullptr);
	std::fill(std::begin(m_tilemap_B_cache_16), std::end(m_tilemap_B_cache_16), nullptr);

	for (int i = 0; i < 2; i++)
	{
		std::fill(std::begin(m_scroll_data_table[i]), std::end(m_scroll_data_table[i]), 0);
		std::fill(std::begin(m_base_addr[i]), std::end(m_base_addr[i]), 0);
	}

	for (int i = 0; i < 256; i++)
		std::fill(std::begin(m_colour_palette[i]), std::end(m_colour_palette[i]), 0);
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------
void ygv608_device::device_start()
{
//  memset(&m_ports, 0, sizeof(m_ports));
//  memset(&m_regs, 0, sizeof(m_regs));
	memset(&m_pattern_name_table, 0, sizeof(m_pattern_name_table));
	memset(&m_sprite_attribute_table, 0, sizeof(m_sprite_attribute_table));

	memset(&m_scroll_data_table, 0, sizeof(m_scroll_data_table));
	memset(&m_colour_palette, 0, sizeof(m_colour_palette));

	m_bits16 = 0;
	m_page_x = 0;
	m_page_y = 0;
	m_pny_shift = 0;
	m_na8_mask = 0;
	m_col_shift = 0;

	m_ax = 0; m_dx = 0; m_dxy = 0; m_ay = 0; m_dy = 0; m_dyx = 0;

	memset(&m_base_addr, 0, sizeof(m_base_addr));
	m_base_y_shift = 0;

	// flag rebuild of the tilemaps
	m_screen_resize = true;
	m_tilemap_resize = true;
	m_namcond1_gfxbank = 0;
	save_item(NAME(m_namcond1_gfxbank));

	/* create tilemaps of all sizes and combinations */
	m_tilemap_A_cache_8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 32,32);
	m_tilemap_A_cache_8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 64,32);
	m_tilemap_A_cache_8[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 32,64);

	m_tilemap_A_cache_16[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 32,32);
	m_tilemap_A_cache_16[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 64,32);
	m_tilemap_A_cache_16[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_A_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 32,64);

	m_tilemap_B_cache_8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 32,32);
	m_tilemap_B_cache_8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 64,32);
	m_tilemap_B_cache_8[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_8)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  8,8, 32,64);

	m_tilemap_B_cache_16[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 32,32);
	m_tilemap_B_cache_16[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 64,32);
	m_tilemap_B_cache_16[2] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(ygv608_device::get_tile_info_B_16)), tilemap_mapper_delegate(*this, FUNC(ygv608_device::get_tile_offset)),  16,16, 32,64);

	m_tilemap_A = nullptr;
	m_tilemap_B = nullptr;

	m_iospace = &space(AS_IO);

	// TODO: tagging configuration
	m_vblank_handler.resolve();
	m_raster_handler.resolve();
	m_vblank_timer = timer_alloc(VBLANK_TIMER);
	m_raster_timer = timer_alloc(RASTER_TIMER);

	register_state_save();
}

//-------------------------------------------------
//  memory_space_config - return a description of
//  any address spaces owned by this device
//-------------------------------------------------

device_memory_interface::space_config_vector ygv608_device::memory_space_config() const
{
	return space_config_vector {
		std::make_pair(AS_IO, &m_io_space_config)
	};
}

inline void ygv608_device::vblank_irq_check()
{
	if(m_vblank_irq_mask == true && m_screen_status & 8)
		m_vblank_handler(ASSERT_LINE);
}

inline void ygv608_device::raster_irq_check()
{
	if(m_raster_irq_mask == true && m_screen_status & 0x10)
		m_raster_handler(ASSERT_LINE);
}


void ygv608_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch(id)
	{
		case VBLANK_TIMER:
		{
			m_screen_status |= 8; // FV
			vblank_irq_check();
			break;
		}
		case RASTER_TIMER:
		{
			m_screen_status |= 0x10; // FP
			raster_irq_check();

			// adjust for next one shot
			m_raster_timer->reset();
			m_raster_timer->adjust(raster_sync_offset(), 0);
			break;
		}
	}
}


void ygv608_device::set_gfxbank(uint8_t gfxbank)
{
	m_namcond1_gfxbank = gfxbank;
	m_tilemap_resize = true;
}

inline int ygv608_device::get_col_division(int raw_col)
{
	if((m_v_div_size & 4) == 0)
		return 0;

	return ((raw_col >> m_col_shift) * 2) & 0x7f;
}

inline int ygv608_device::get_row_division(int raw_row)
{
	if(m_h_div_size == 0)
		return 0;

	return (raw_row & (m_page_y/2 - 1)) * 2;
}

TILEMAP_MAPPER_MEMBER( ygv608_device::get_tile_offset )
{
	// this optimisation is not much good to us,
	// since we really need row,col in the get_tile_info() routines
	// - so just pack them into a uint32_t

	return( ( col << 6 ) | row );
}

#define layout_total(x) \
(gfx(x)->elements())

TILE_GET_INFO_MEMBER( ygv608_device::get_tile_info_A_8 )
{
	// extract row,col packed into tile_index
	int             col = tile_index >> 6;
	int             row = tile_index & 0x3f;
	int translated_column = get_col_division(col);

	uint8_t   attr = 0;
	int             pattern_name_base = 0;
	int             set = (m_md == MD_1PLANE_256COLOUR
						? GFX_8X8_8BIT : GFX_8X8_4BIT );
	int             base = row >> m_base_y_shift;

	if( col >= m_page_x )
	{
		SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else if( row >= m_page_y )
	{
		SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else
	{
		int sx, sy, page;
		int i = pattern_name_base + (((row << m_pny_shift) + col) << m_bits16);
		int j = m_pattern_name_table[i];
		int f = 0;

		if( m_bits16 )
		{
			j += ((int)(m_pattern_name_table[i+1] & m_na8_mask )) << 8;
			// attribute only valid in 16 color mode
			if (set == GFX_8X8_4BIT)
				attr = m_pattern_name_table[i+1] >> 4;

			if (m_flip == true)
			{
				if (m_pattern_name_table[i+1] & (1<<3)) f |= TILE_FLIPX;
				if (m_pattern_name_table[i+1] & (1<<2)) f |= TILE_FLIPY;
			}
		}

		/* calculate page according to scroll data */
		/* - assuming full-screen scroll only for now... */
		if (m_v_div_size) {
			page = 0;
		}
		else {
			sy = (int)m_scroll_data_table[0][translated_column] +
			   (((int)m_scroll_data_table[0][translated_column+1] & 0x0f ) << 8);
			sx = (int)m_scroll_data_table[0][0x80] +
			   (((int)m_scroll_data_table[0][0x81] & 0x0f ) << 8);

			if (m_md == MD_2PLANE_16BIT)
			{
				page = ( ( sx + col * 8 ) % 1024 ) / 256;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 256 ) * 4;
			}
			else if (m_page_size)
			{
				page = ( ( sx + col * 8 ) % 2048 ) / 512;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 256 ) * 4;
			}
			else
			{
				page = ( ( sx + col * 8 ) % 2048 ) / 256;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 512 ) * 8;
			}
		}

		page &= 0x1f;

		/* add page, base address to pattern name */
		j += ( (int)m_scroll_data_table[0][0xc0+page] << 10 );
		j += ( m_base_addr[0][base] << 8 );

		if( j >= layout_total(set) )
		{
			logerror( "A_8X8: tilemap=%d\n", j );
			j = 0;
		}
		if (m_planeA_color_fetch != 0)
		{
			// attribute only valid in 16 color mode
			if( set == GFX_8X8_4BIT )
				attr = ( j >> ( (m_planeA_color_fetch - 1 ) * 2 ) ) & 0x0f;
		}
		// banking
		if (set == GFX_8X8_4BIT)
		{
			j += m_namcond1_gfxbank * 0x10000;
		}
		else // 8x8x8
		{
			j += m_namcond1_gfxbank * 0x8000;
		}

		SET_TILE_INFO_MEMBER(set, j, attr & 0x0F, f );
	}
}

TILE_GET_INFO_MEMBER( ygv608_device::get_tile_info_B_8 )
{
	// extract row,col packed into tile_index
	int             col = tile_index >> 6;
	int             row = tile_index & 0x3f;
	int translated_column = get_col_division(col);

	uint8_t   attr = 0;
	int             pattern_name_base = ( ( m_page_y << m_pny_shift )
						<< m_bits16 );
	int             set = GFX_8X8_4BIT;
	int             base = row >> m_base_y_shift;

	if (m_md & MD_1PLANE )
	{
		SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else if (col >= m_page_x)
	{
		SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else if (row >= m_page_y)
	{
		SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else
	{
		int sx, sy, page;
		int i = pattern_name_base + (((row << m_pny_shift) + col) << m_bits16);
		int j = m_pattern_name_table[i];
		int f = 0;

		if (m_bits16)
		{
			j += ((int)(m_pattern_name_table[i+1] & m_na8_mask )) << 8;
			attr = m_pattern_name_table[i+1] >> 4; /*& 0x00; 0xf0;*/

			if (m_flip == true)
			{
				if (m_pattern_name_table[i+1] & (1<<3)) f |= TILE_FLIPX;
				if (m_pattern_name_table[i+1] & (1<<2)) f |= TILE_FLIPY;
			}
		}

		/* calculate page according to scroll data */
		/* - assuming full-screen scroll only for now... */
		if (m_v_div_size) {
			page = 0;
		}
		else {
			sy = (int)m_scroll_data_table[1][translated_column] +
			   (((int)m_scroll_data_table[1][translated_column+1] & 0x0f ) << 8);
			sx = (int)m_scroll_data_table[1][0x80] +
			   (((int)m_scroll_data_table[1][0x81] & 0x0f ) << 8);

			if (m_md == MD_2PLANE_16BIT)
			{
				page = ( ( sx + col * 8 ) % 1024 ) / 256;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 256 ) * 4;
			}
			else if (m_page_size)
			{
				page = ( ( sx + col * 8 ) % 2048 ) / 512;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 256 ) * 4;
			}
			else
			{
				page = ( ( sx + col * 8 ) % 2048 ) / 256;
				page += ( ( ( sy + row * 8 ) % 2048 ) / 512 ) * 8;
			}
		}

		page &= 0x1f;

		/* add page, base address to pattern name */
		j += ( (int)m_scroll_data_table[1][0xc0+page] << 10 );
		j += ( m_base_addr[1][base] << 8 );

		if( j >= layout_total(set) )
		{
			logerror( "B_8X8: tilemap=%d\n", j );
			j = 0;
		}
		if (m_planeB_color_fetch != 0)
		{
			uint8_t color = (m_planeB_color_fetch);

			/* assume 16 colour mode for now... */
			attr = ( j >> ( (color - 1 ) * 2 ) ) & 0x0f;
		}

		// banking
		if (set == GFX_8X8_4BIT)
		{
			j += m_namcond1_gfxbank * 0x10000;
		}
		else // 8x8x8
		{
			j += m_namcond1_gfxbank * 0x8000;
		}

		SET_TILE_INFO_MEMBER(set, j, attr, f );
	}
}

TILE_GET_INFO_MEMBER( ygv608_device::get_tile_info_A_16 )
{
	// extract row,col packed into tile_index
	int             col = tile_index >> 6;
	int             row = tile_index & 0x3f;
	int translated_column = get_col_division(col);

	uint8_t   attr = 0;
	int             pattern_name_base = 0;
	int             set = (m_md == MD_1PLANE_256COLOUR
						? GFX_16X16_8BIT : GFX_16X16_4BIT );
	int             base = row >> m_base_y_shift;

	if( col >= m_page_x ) {
	SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else if( row >= m_page_y ) {
	SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else {
	int sx, sy, page;
	int j;
	int i = ( ( ( row << m_pny_shift ) + col ) << m_bits16 );
	int f = 0;
	i += pattern_name_base;

	j = m_pattern_name_table[i];
	if( m_bits16 ) {
		j += ((int)(m_pattern_name_table[i+1] & m_na8_mask )) << 8;
		// attribute only valid in 16 color mode
		if( set == GFX_16X16_4BIT )
			attr = m_pattern_name_table[i+1] >> 4;

		if (m_flip == true)
		{
		if (m_pattern_name_table[i+1] & (1<<3)) f |= TILE_FLIPX;
		if (m_pattern_name_table[i+1] & (1<<2)) f |= TILE_FLIPY;
		}
	}

	/* calculate page according to scroll data */
	/* - assuming full-screen scroll only for now... */
	if (m_v_div_size) {
		page = 0;
	}
	else {
		sy = (int)m_scroll_data_table[0][translated_column] +
		   (((int)m_scroll_data_table[0][translated_column+1] & 0x0f ) << 8);
		sx = (int)m_scroll_data_table[0][0x80] +
		   (((int)m_scroll_data_table[0][0x81] & 0x0f ) << 8);

		if (m_md == MD_2PLANE_16BIT) {
			page = ( ( sx + col * 16 ) % 2048 ) / 512;
			page += ( ( sy + row * 16 ) / 512 ) * 4;
		}
		else if (m_page_size) {
			page = ( sx + col * 16 ) / 512;
			page += ( ( sy + row * 16 ) / 1024 ) * 8;
		}
		else {
			page = ( sx + col * 16 ) / 1024;
			page += ( ( sy + row * 16 ) / 512 ) * 4;
		}
	}

	page &= 0x1f;

	/* add page, base address to pattern name */
	j += ( (int)m_scroll_data_table[0][0xc0+page] << 8 );
	j += ( m_base_addr[0][base] << 8 );

	if( j >= layout_total(set) ) {
	logerror( "A_16X16: tilemap=%d\n", j );
		j = 0;
	}

	if (m_planeA_color_fetch != 0)
	{
		// attribute only valid in 16 color mode
		if( set == GFX_16X16_4BIT )
			attr = ( j >> ( m_planeA_color_fetch * 2 ) ) & 0x0f;
	}

	// banking
	if (set == GFX_16X16_4BIT)
	{
		j += m_namcond1_gfxbank * 0x4000;
	}
	else // 8x8x8
	{
		j += m_namcond1_gfxbank * 0x2000;
	}


	SET_TILE_INFO_MEMBER(set, j, attr, f );
	}
}

TILE_GET_INFO_MEMBER( ygv608_device::get_tile_info_B_16 )
{
	// extract row,col packed into tile_index
	int             col = tile_index >> 6;
	int             row = tile_index & 0x3f;
	int translated_column = get_col_division(col);

	uint8_t   attr = 0;
	int             pattern_name_base = ( ( m_page_y << m_pny_shift )
					<< m_bits16 );
	int             set = GFX_16X16_4BIT;
	int             base = row >> m_base_y_shift;

	if(m_md & MD_1PLANE ) {
	SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	if( col >= m_page_x ) {
	SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else if( row >= m_page_y ) {
	SET_TILE_INFO_MEMBER(set, 0, 0, 0 );
	}
	else {
	int sx, sy, page;
	int j;
	int i = ( ( ( row << m_pny_shift ) + col ) << m_bits16 );
	int f = 0;
	i += pattern_name_base;

	j = m_pattern_name_table[i];
	if( m_bits16 ) {
		j += ((int)(m_pattern_name_table[i+1] & m_na8_mask )) << 8;
		attr = m_pattern_name_table[i+1] >> 4; /*& 0x00; 0xf0;*/

		if (m_flip == true)
		{
			if (m_pattern_name_table[i+1] & (1<<3)) f |= TILE_FLIPX;
			if (m_pattern_name_table[i+1] & (1<<2)) f |= TILE_FLIPY;
		}
	}

	/* calculate page according to scroll data */
	/* - assuming full-screen scroll only for now... */
	if (m_v_div_size) {
		page = 0;
	}
	else {
		sy = (int)m_scroll_data_table[1][translated_column] +
		   (((int)m_scroll_data_table[1][translated_column+1] & 0x0f ) << 8);
		sx = (int)m_scroll_data_table[1][0x80] +
		   (((int)m_scroll_data_table[1][0x81] & 0x0f ) << 8);

		if (m_md == MD_2PLANE_16BIT) {
			page = ( ( sx + col * 16 ) % 2048 ) / 512;
			page += ( ( sy + row * 16 ) / 512 ) * 4;
		}
		else if (m_page_size) {
			page = ( sx + col * 16 ) / 512;
			page += ( ( sy + row * 16 ) / 1024 ) * 8;
		}
		else {
			page = ( sx + col * 16 ) / 1024;
			page += ( ( sy + row * 16 ) / 512 ) * 4;
		}
	}

	page &= 0x1f;

	/* add page, base address to pattern name */
	j += ( (int)m_scroll_data_table[1][0xc0+page] << 8 );
	j += ( m_base_addr[1][base] << 8 );

	if( j >= layout_total(set) ) {
	logerror( "B_16X16: tilemap=%d\n", j );
		j = 0;
	}

	if (m_planeB_color_fetch != 0)
	{
		uint8_t color = (m_planeB_color_fetch);

		/* assume 16 colour mode for now... */
		attr = ( j >> (color * 2)) & 0x0f;
	}

	// banking
	if (set == GFX_16X16_4BIT)
	{
		j += m_namcond1_gfxbank * 0x4000;
	}
	else // 8x8x8
	{
		j += m_namcond1_gfxbank * 0x2000;
	}

	SET_TILE_INFO_MEMBER(set, j, attr, f );
	}
}

void ygv608_device::device_post_load()
{
	m_screen_resize = true;
	m_tilemap_resize = true;
}

void ygv608_device::register_state_save()
{
//  save_item(NAME(m_ports.b));
//  save_item(NAME(m_regs.b));
	save_item(NAME(m_pattern_name_table));
	save_item(NAME(m_sprite_attribute_table.b));
	save_item(NAME(m_scroll_data_table));
	save_item(NAME(m_colour_palette));
	save_item(NAME(m_color_state_r));
	save_item(NAME(m_color_state_w));
	save_item(NAME(m_bits16));
	save_item(NAME(m_page_x));
	save_item(NAME(m_page_y));
	save_item(NAME(m_pny_shift));
	save_item(NAME(m_na8_mask));
	save_item(NAME(m_col_shift));
	save_item(NAME(m_base_addr));
	save_item(NAME(m_base_y_shift));
	save_item(NAME(m_screen_resize));
	save_item(NAME(m_tilemap_resize));
	save_item(NAME(m_p0_state));
	save_item(NAME(m_pattern_name_base_r));
	save_item(NAME(m_pattern_name_base_w));
	save_item(NAME(m_screen_status));
	save_item(NAME(m_dma_status));
	save_item(NAME(m_register_address));
	save_item(NAME(m_register_autoinc_r));
	save_item(NAME(m_register_autoinc_w));
	save_item(NAME(m_raster_irq_mask));
	save_item(NAME(m_vblank_irq_mask));
	save_item(NAME(m_raster_irq_hpos));
	save_item(NAME(m_raster_irq_vpos));
	save_item(NAME(m_raster_irq_mode));
	save_item(NAME(m_scroll_address));
	save_item(NAME(m_palette_address));
	save_item(NAME(m_sprite_address));
	save_item(NAME(m_sprite_bank));
	save_item(NAME(m_xtile_ptr));
	save_item(NAME(m_ytile_ptr));
	save_item(NAME(m_xtile_autoinc));
	save_item(NAME(m_ytile_autoinc));
	save_item(NAME(m_plane_select_access));
	save_item(NAME(m_mosaic_aplane));
	save_item(NAME(m_mosaic_bplane));
	save_item(NAME(m_sprite_disable));
	save_item(NAME(m_sprite_aux_mode));
	save_item(NAME(m_sprite_aux_reg));
	save_item(NAME(m_border_color));
	save_item(NAME(m_saar));
	save_item(NAME(m_saaw));
	save_item(NAME(m_scar));
	save_item(NAME(m_scaw));
	save_item(NAME(m_cpar));
	save_item(NAME(m_cpaw));
	save_item(NAME(m_ba_plane_scroll_select));
	save_item(NAME(m_dspe));
	save_item(NAME(m_md));
	save_item(NAME(m_zron));
	save_item(NAME(m_flip));
	save_item(NAME(m_dckm));
	save_item(NAME(m_page_size));
	save_item(NAME(m_h_display_size));
	save_item(NAME(m_v_display_size));
	save_item(NAME(m_roz_wrap_disable));
	save_item(NAME(m_scroll_wrap_disable));
	save_item(NAME(m_pattern_size));
	save_item(NAME(m_h_div_size));
	save_item(NAME(m_v_div_size));
	save_item(NAME(m_planeA_trans_enable));
	save_item(NAME(m_planeB_trans_enable));
	save_item(NAME(m_priority_mode));
	save_item(NAME(m_cbdr));
	save_item(NAME(m_yse));
	save_item(NAME(m_scm));
	save_item(NAME(m_planeA_color_fetch));
	save_item(NAME(m_planeB_color_fetch));
	save_item(NAME(m_sprite_color_fetch));
	save_item(NAME(m_crtc.htotal));
	save_item(NAME(m_crtc.vtotal));
	save_item(NAME(m_crtc.display_hstart));
	save_item(NAME(m_crtc.display_vstart));
	save_item(NAME(m_crtc.display_width));
	save_item(NAME(m_crtc.display_height));
	save_item(NAME(m_crtc.display_hsync));
	save_item(NAME(m_crtc.display_vsync));
	save_item(NAME(m_crtc.border_width));
	save_item(NAME(m_crtc.border_height));
	save_item(NAME(m_ax));
	save_item(NAME(m_dx));
	save_item(NAME(m_dxy));
	save_item(NAME(m_ay));
	save_item(NAME(m_dy));
	save_item(NAME(m_dyx));
	save_item(NAME(m_raw_ax));
	save_item(NAME(m_raw_dx));
	save_item(NAME(m_raw_dxy));
	save_item(NAME(m_raw_ay));
	save_item(NAME(m_raw_dy));
	save_item(NAME(m_raw_dyx));
}


void ygv608_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
#ifdef _ENABLE_SPRITES
	const int sprite_limits[4] = { 512-8, 512-16, 512-32, 512-64 };
	const uint32_t spritebank_size[4] = { 0x10000, 0x4000, 0x1000, 0x400 };
	const int sprite_shift[4] = { 8, 6, 4, 2 };
	const int sprite_mask[4] = { 0xff, 0xfc, 0xf0, 0xc0 };
	const int spf_shift[4] = { -1, 0, +1, +2 };
	// sprites are always clipped to 512x512
	// - regardless of the visible display dimensions
	rectangle spriteClip(0, 512, 0, 512);

	SPRITE_ATTR *sa;
	int flipx = 0, flipy = 0;
	int i;

	/* ensure that sprites are enabled */
	if( (m_dspe == false ) || (m_sprite_disable == true) )
		return;

	/* draw sprites */
	spriteClip &= cliprect;
	sa = &m_sprite_attribute_table.s[MAX_SPRITES-1];
	for( i=0; i<MAX_SPRITES; i++, sa-- )
	{
		int code, color, sx, sy, size, attr, g_attr, spf;

		color = (sa->attr >> 4) & 0x0f;
		sx = ( (int)(sa->attr & 0x02) << 7 ) | (int)sa->sx;
		sy = ( ( ( (int)(sa->attr & 0x01) << 8 ) | (int)sa->sy ) + 1 ) & 0x1ff;
		attr = (sa->attr & 0x0c) >> 2;
		g_attr = m_sprite_aux_reg & 3;
		spf = m_sprite_color_fetch;

		if (m_sprite_aux_mode == SPAS_SPRITESIZE )
		{
			size = g_attr;
			flipx = (attr & SZ_HORIZREVERSE) != 0;
			flipy = (attr & SZ_VERTREVERSE) != 0;
		}
		else
		{
			size = attr;
			flipx = (g_attr & SZ_HORIZREVERSE) != 0;
			flipy = (g_attr & SZ_VERTREVERSE) != 0;
		}

		// calculate code and apply sprite base address
		code = ( (int)(m_sprite_bank & sprite_mask[size]) << sprite_shift[size] ) | (int)sa->sn;
		// apply spf to color (invalidates individual attribute bits for color)
		if (spf != 0)
			color = ( code >> ( (spf + spf_shift[size]) * 2 ) ) & 0x0f;
		// check code boundary (TODO: do we really need this?)
		if( code >= layout_total(size) )
		{
			logerror( "SZ_%d: sprite=%d\n", size, code );
			code = 0;
		}
		// draw the sprite
		gfx(size)->transpen(bitmap,spriteClip,
			code+m_namcond1_gfxbank*spritebank_size[size],
			color,
			flipx,flipy,
			sx,sy,0x00);
		// draw with wraparound
		if(sx > sprite_limits[size] || sy > sprite_limits[size] )
		{
			gfx(size)->transpen(bitmap,spriteClip,
				code+m_namcond1_gfxbank*spritebank_size[size],
				color,
				flipx,flipy,
				sx-512,sy,0x00);
			gfx(size)->transpen(bitmap,spriteClip,
				code+m_namcond1_gfxbank*spritebank_size[size],
				color,
				flipx,flipy,
				sx,sy-512,0x00);
			gfx(size)->transpen(bitmap,spriteClip,
				code+m_namcond1_gfxbank*spritebank_size[size],
				color,
				flipx,flipy,
				sx-512,sy-512,0x00);
		}

	}

#endif
}

#ifdef _SHOW_VIDEO_DEBUG
static const char *const mode[] = {
	"2PLANE_8BIT",
	"2PLANE_16BIT",
	"1PLANE_16COLORS",
	"1PLANE_256COLORS"
};

static const char *const psize[] = { "8x8", "16x16", "32x32", "64x64" };
#endif

inline void ygv608_device::draw_layer_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t *source_tilemap)
{
	//int xc, yc;
	//double r, alpha, sin_theta, cos_theta;
	//const rectangle &visarea = screen.visible_area();
	uint32_t sx, sy;

	int ba_select = (source_tilemap == m_tilemap_A) ? 0 : 1;

	sy = (int)m_scroll_data_table[ba_select][0x00] +
	   (((int)m_scroll_data_table[ba_select][0x01] & 0x0f ) << 8);
	sx = (int)m_scroll_data_table[ba_select][0x80] +
	   (((int)m_scroll_data_table[ba_select][0x81] & 0x0f ) << 8);

	if( m_zron == true )
	{
		// old code, for reference.
		//xc = m_ax >> 16;
		//yc = m_ay >> 16;
		//r = sqrt( (double)( xc * xc + yc * yc ) );
		//alpha = atan( (double)xc / (double)yc );
		//sin_theta = (double)m_dyx / (double)0x10000;
		//cos_theta = (double)m_dx / (double)0x10000;

		if (m_v_div_size) {
			sx = (sx & 0x1FF) ? (sx - 0x200) : 0;
			sy = (sy & 0x1FF) ? (sy - 0x200) : 0;
		}
		source_tilemap->draw_roz(screen, bitmap, cliprect,
				m_ax + (sx << 16), m_ay + (sy << 16),
				m_dx, m_dyx, m_dxy, m_dy, m_roz_wrap_disable == false, 0, 0 );
	}
	else
		source_tilemap->draw(screen, bitmap, cliprect, 0, 0 );
}

void ygv608_device::ygv608_draw_mosaic(bitmap_ind16 &bitmap, const rectangle &cliprect, int n)
{
	int x, y, mask;

	if (n <= 0)
	{
		return;
	}

	// mask to drop the lowest n-bits
	mask = ~((1 << n) - 1);

	for (y = cliprect.min_y; y <= cliprect.max_y; y++)
	{
		for (x = cliprect.min_x; x <= cliprect.max_x; x++)
		{
			bitmap.pix16(y, x) = bitmap.pix16(y & mask, x & mask);
		}
	}
}

uint32_t ygv608_device::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
#ifdef _SHOW_VIDEO_DEBUG
	char buffer[64];
#endif
#ifdef _ENABLE_SCROLLY
	int col;
#endif
#ifdef _ENABLE_SCROLLX
	int row;
#endif
	rectangle finalclip;
	const rectangle &visarea = screen.visible_area();

	// clip to the current bitmap
	finalclip.set(0, screen.width() - 1, 0, screen.height() - 1);
	finalclip &= cliprect;
	// TODO: black/transparent pen if CBDR is 1 and border color is 0
	bitmap.fill(m_border_color, visarea );

	// punt if not initialized
	if (m_page_x == 0 || m_page_y == 0)
	{
		return 0;
	}

	if( m_screen_resize )
	{
		m_work_bitmap.resize(screen.width(), screen.height());

		// reset resize flag
		m_screen_resize = false;
	}

	if( m_tilemap_resize )
	{
		int index;

		/* based on the page sizes, pick an index */
		if (m_page_x == 64)
			index = 1;
		else if (m_page_y == 64)
			index = 2;
		else
			index = 0;

		if (m_pattern_size == PTS_8X8 )
			m_tilemap_A = m_tilemap_A_cache_8[index];
		else
			m_tilemap_A = m_tilemap_A_cache_16[index];
		m_tilemap_A->mark_all_dirty();

		m_tilemap_A->set_transparent_pen(m_border_color);

		if (m_h_div_size == 0) {
			m_tilemap_A->set_scroll_cols(m_page_x);
			m_tilemap_A->set_scroll_rows(1);
		}
		else {
			m_tilemap_A->set_scroll_cols(1);
			m_tilemap_A->set_scroll_rows(m_page_y);
		}

		if (m_pattern_size == PTS_8X8 )
			m_tilemap_B = m_tilemap_B_cache_8[index];
		else
			m_tilemap_B = m_tilemap_B_cache_16[index];
		m_tilemap_B->mark_all_dirty();

		if (m_h_div_size == 0) {
			m_tilemap_B->set_scroll_cols(m_page_x);
			m_tilemap_B->set_scroll_rows(1);
		}
		else {
			m_tilemap_B->set_scroll_cols(1);
			m_tilemap_B->set_scroll_rows(m_page_y);
		}

		// now clear the screen in case we change to 1-plane mode
		m_work_bitmap.fill(0, finalclip );

		// reset resize flag
		m_tilemap_resize = false;
	}

#ifdef _ENABLE_SCROLLY

	for( col=0; col<m_page_x; col++ )
	{
		int translated_column = get_col_division(col);

		m_tilemap_B->set_scrolly(col,
			( (int)m_scroll_data_table[1][translated_column] +
			( (int)m_scroll_data_table[1][translated_column+1] << 8 ) ) );

		m_tilemap_A->set_scrolly(col,
			( (int)m_scroll_data_table[0][translated_column] +
			( (int)m_scroll_data_table[0][translated_column+1] << 8 ) ) );
	}

#endif

#ifdef _ENABLE_SCROLLX

	for( row=0; row<m_page_y; row++ )
	{
		int translated_row = get_row_division(row);

		m_tilemap_B->set_scrollx(row,
			( (int)m_scroll_data_table[1][translated_row+0x80] +
			( (int)m_scroll_data_table[1][translated_row+0x81] << 8 ) ) );

		m_tilemap_A->set_scrollx(row,
			( (int)m_scroll_data_table[0][translated_row+0x80] +
			( (int)m_scroll_data_table[0][translated_row+0x81] << 8 ) ) );
	}

#endif

	m_tilemap_A->enable(m_dspe == true);
	if(m_md & MD_1PLANE )
		m_tilemap_B->enable(0);
	else
		m_tilemap_B->enable(m_dspe == true);

	m_tilemap_A->mark_all_dirty();
	m_tilemap_B->mark_all_dirty();


	/*
	 *    now we can render the screen
	 */

	// LBO - need to implement proper pen marking for sprites as well as set aside a non-transparent
	// pen to be used for background fills when plane B is disabled.
	if (m_md & MD_1PLANE)
	{
		// If the background tilemap is disabled, we need to clear the bitmap to black
		m_work_bitmap.fill(0, finalclip);
//      m_work_bitmap.fill(1, *visarea);
	}
	else
	{
		draw_layer_roz(screen, m_work_bitmap, finalclip, m_tilemap_B);
		if(m_mosaic_bplane > 0)
			ygv608_draw_mosaic(m_work_bitmap, finalclip, m_mosaic_bplane);

		if(m_planeB_trans_enable == true)
			copybitmap_trans( bitmap, m_work_bitmap, 0, 0, 0, 0, finalclip, 0);
		else
			copybitmap( bitmap, m_work_bitmap, 0, 0, 0, 0, finalclip);
	}

	// for some reason we can't use an opaque m_tilemap_A
	// so use a transparent but clear the work bitmap first
	// - look at why this is the case?!?
	m_work_bitmap.fill(0, visarea );

	if (m_priority_mode == PRM_ASBDEX ||
		m_priority_mode == PRM_ASEBDX )
		draw_sprites(bitmap, finalclip);

	draw_layer_roz(screen, m_work_bitmap, finalclip, m_tilemap_A);
	if(m_mosaic_aplane > 0)
		ygv608_draw_mosaic(m_work_bitmap, finalclip, m_mosaic_aplane);

	if(m_planeA_trans_enable == true)
		copybitmap_trans( bitmap, m_work_bitmap, 0, 0, 0, 0, finalclip, 0);
	else
		copybitmap( bitmap, m_work_bitmap, 0, 0, 0, 0, finalclip);

	if (m_priority_mode == PRM_SABDEX ||
		m_priority_mode == PRM_SEABDX)
		draw_sprites(bitmap,finalclip );


#ifdef _SHOW_VIDEO_DEBUG
	/* show screen control information */
	ui_draw_text( mode[m_md], 0, 0 );
	sprintf( buffer, "%02ux%02u", m_page_x, m_page_y );
	ui_draw_text( buffer, 0, 16 );
	ui_draw_text( psize[m_pattern_size], 0, 32 );
	sprintf( buffer, "A: SX:%d SY:%d",
		(int)m_scroll_data_table[0][0x80] +
		( ( (int)m_scroll_data_table[0][0x81] & 0x0f ) << 8 ),
		(int)m_scroll_data_table[0][0x00] +
		( ( (int)m_scroll_data_table[0][0x01] & 0x0f ) << 8 ) );
	ui_draw_text( buffer, 0, 48 );
	sprintf( buffer, "B: SX:%d SY:%d",
		(int)m_scroll_data_table[1][0x80] +
		( ( (int)m_scroll_data_table[1][0x81] & 0x0f ) << 8 ),
		(int)m_scroll_data_table[1][0x00] +
		( ( (int)m_scroll_data_table[1][0x01] & 0x0f ) << 8 ) );
	ui_draw_text( buffer, 0, 64 );
#endif
	return 0;
}

/***************************************
 *
 * Port Interface routines
 *
 ****************************************/

 // P#0R - pattern name table data port
READ8_MEMBER( ygv608_device::pattern_name_table_r )
{
	int pn = 0;

	switch (m_p0_state)
	{
		case 0:
			/* Are we reading from plane B? */
			if (!(m_md & MD_1PLANE) && (m_plane_select_access == true))
				m_pattern_name_base_r = ((m_page_y << m_pny_shift) << m_bits16);

			/* read character from ram */
			pn = m_pattern_name_base_r + (((m_ytile_ptr << m_pny_shift) + m_xtile_ptr) << m_bits16);
			break;

		case 1:
			/* read character from ram */
			pn = m_pattern_name_base_r + (((m_ytile_ptr << m_pny_shift) + m_xtile_ptr) << m_bits16) + 1;
			break;
	}

	if (pn > 4095)
	{
		logerror( "attempt (%d) to read pattern name %d\n"
			"mode = %d, pgs = %d (%dx%d)\n"
			"m_pattern_name_base_r = %d\n"
			"pnx = %d, pny = %d, pny_shift = %d, bits16 = %d\n",
			m_p0_state,
			pn, m_md, m_page_size,
			m_page_x, m_page_y,
			m_pattern_name_base_r,
			m_xtile_ptr, m_ytile_ptr, m_pny_shift,
			m_bits16 );
		pn = 0;
	}

	m_p0_state++;
	if (m_md == MD_2PLANE_8BIT )
		m_p0_state++;

	if (m_p0_state == 2)
	{
		pattern_name_autoinc_check();
		m_p0_state = 0;
		m_pattern_name_base_r = 0;
	}

	return m_pattern_name_table[pn];
}

// P#1R - sprite data port
READ8_MEMBER( ygv608_device::sprite_data_r )
{
	uint8_t res = m_sprite_attribute_table.b[m_sprite_address];

	if (m_saar == true)
		m_sprite_address++;

	return res;
}

// P#2R - scroll data port
READ8_MEMBER( ygv608_device::scroll_data_r )
{
	uint8_t res = m_scroll_data_table[m_ba_plane_scroll_select][m_scroll_address];

	if (m_scar == true)
	{
		m_scroll_address++;
		/* handle wrap to next plane */
		if (m_scroll_address == 0)
			m_ba_plane_scroll_select ^= 1;
	}

	return res;
}

// P#3 - color palette data port
READ8_MEMBER( ygv608_device::palette_data_r )
{
	uint8_t res = m_colour_palette[m_palette_address][m_color_state_r];

	if( ++m_color_state_r == 3 )
	{
		m_color_state_r = 0;

		if(m_cpar == true)
			m_palette_address++;
	}

	return res;
}

// P#4R - register data port
READ8_MEMBER(ygv608_device::register_data_r)
{
	int regNum = m_register_address & 0x3f;
	uint8_t res = m_iospace->read_byte(regNum);


	if (m_register_autoinc_r == true)
	{
		m_register_address ++;
		m_register_address &= 0x3f;
		#if 0
		// we'll catch this in the logerror anyway
		if (regNum == 50)
		{
			regNum = 0;
			logerror( "warning: rn=50 after read increment\n" );
		}
		#endif
	}

	return res;
}

// P#6R - status port
/***
 * ---x ---- FP Specified display position flag (R#15 & 16), reset by writing '1'
 * ---- x--- FV Vertical border interval start, reset by writing '1'
 * ---- -x-- FC Sprite collision flag, reset by writing '1'
 * ---- --x- HB 1 when horizontal border or retrace is in progress (read only)
 * ---- ---x VB 1 when vertical border or retrace is in progress (read only)
 ***/
READ8_MEMBER( ygv608_device::status_port_r )
{
	// TODO: we need to use h/vpos in case of border support instead due of how MAME framework works here.
	return (m_screen_status & 0x1c) | (screen().hblank()<<1) | screen().vblank();
}

// P#7R - system control port
READ8_MEMBER( ygv608_device::system_control_r )
{
	return m_dma_status;
}

// P#0W - pattern name table data write
WRITE8_MEMBER(ygv608_device::pattern_name_table_w)
{
	int pn = 0;

	switch (m_p0_state)
	{
		case 0:
			/* Are we reading from plane B? */
			if (!(m_md & MD_1PLANE) && (m_plane_select_access == true))
				m_pattern_name_base_w = ((m_page_y << m_pny_shift) << m_bits16);

			/* read character from ram */
			pn = m_pattern_name_base_w + (((m_ytile_ptr << m_pny_shift) + m_xtile_ptr) << m_bits16);
			break;

		case 1:
			/* read character from ram */
			pn = m_pattern_name_base_w + (((m_ytile_ptr << m_pny_shift) + m_xtile_ptr) << m_bits16) + 1;
			break;
	}

	if (pn > 4095)
	{
		logerror( "attempt (%d) to write pattern name %d\n"
			"mode = %d, pgs = %d (%dx%d)\n"
			"m_pattern_name_base_w = %d\n"
			"pnx = %d, pny = %d, pny_shift = %d, bits16 = %d\n",
			m_p0_state,
			pn, m_md, m_page_size,
			m_page_x, m_page_y,
			m_pattern_name_base_w,
			m_xtile_ptr, m_ytile_ptr, m_pny_shift,
			m_bits16 );
		pn = 0;
	}

	m_pattern_name_table[pn] = data;

	m_p0_state++;
	if (m_md == MD_2PLANE_8BIT )
		m_p0_state++;

	if (m_p0_state == 2)
	{
		pattern_name_autoinc_check();
		m_p0_state = 0;
		m_pattern_name_base_w = 0;
	}
}

inline void ygv608_device::pattern_name_autoinc_check()
{
	uint8_t xTile = m_xtile_ptr;
	uint8_t yTile = m_ytile_ptr;

	if (m_ytile_autoinc == true)
	{
		// we are incrementing in Y direction
		if (yTile++ == (m_page_y - 1))
		{
			yTile = 0;
			if (xTile++ == (m_page_x - 1))
			{
				xTile = 0;
				m_plane_select_access ^= 1; // flip A/B plane
			}
		}
		m_ytile_ptr = yTile;
		m_xtile_ptr = xTile;
	}
	else if (m_xtile_autoinc == true)
	{
		// we are incrementing in X direction
		if (xTile++ == (m_page_x - 1))
		{
			xTile = 0;
			if (yTile++ == (m_page_y - 1))
			{
				yTile = 0;
				m_plane_select_access ^= 1; // flip A/B plane
			}
		}
		m_ytile_ptr = yTile;
		m_xtile_ptr = xTile;
	}
}

// P#1W - sprite data port
WRITE8_MEMBER( ygv608_device::sprite_data_w )
{
	m_sprite_attribute_table.b[m_sprite_address] = data;

	if( m_saaw == true)
		m_sprite_address++;
}

// P#2W - scroll data port
WRITE8_MEMBER( ygv608_device::scroll_data_w )
{
	m_scroll_data_table[m_ba_plane_scroll_select][m_scroll_address] = data;

	if (m_scaw == true)
	{
		m_scroll_address++;
		/* handle wrap to next plane */
		if (m_scroll_address == 0)
			m_ba_plane_scroll_select ^= 1;
	}
}

// P#3W - colour palette data port
WRITE8_MEMBER( ygv608_device::palette_data_w )
{
	m_colour_palette[m_palette_address][m_color_state_w] = data;
	if (++m_color_state_w == 3)
	{
		m_color_state_w = 0;
//      if(m_colour_palette[m_palette_address][0] & 0x80) // Transparency designation, none of the Namco games enables it?

		set_pen_color(m_palette_address,
			pal6bit( m_colour_palette[m_palette_address][0] ),
			pal6bit( m_colour_palette[m_palette_address][1] ),
			pal6bit( m_colour_palette[m_palette_address][2] ));

		if(m_cpaw == true)
			m_palette_address++;
	}
}

// P#4W - register data port
WRITE8_MEMBER( ygv608_device::register_data_w )
{
	uint8_t regNum = m_register_address & 0x3f;
	//logerror( "R#%d = $%02X\n", regNum, data );

	m_iospace->write_byte(regNum, data);

	if (m_register_autoinc_w == true)
	{
		m_register_address ++;
		m_register_address &= 0x3f;

		#if 0
		// we'll catch this in the logerror anyway
		if (regNum == 50)
		{
			regNum = 0;
			logerror( "warning: rn=50 after write increment\n" );
		}
		#endif
	}
}

// P#5W - register select port
WRITE8_MEMBER( ygv608_device::register_select_w )
{
	m_register_address = data & 0x3f;
	m_register_autoinc_r = BIT(data,6);
	m_register_autoinc_w = BIT(data,7);
}

// P#6W - status port
WRITE8_MEMBER( ygv608_device::status_port_w )
{
	/* writing a '1' resets that bit */
	m_screen_status &= ~data;

	// send an irq ack to the delegates accordingly
	if(data & 8)
		m_vblank_handler(CLEAR_LINE);
	if(data & 0x10)
		m_raster_handler(CLEAR_LINE);
}

// P#7W - system control port
WRITE8_MEMBER( ygv608_device::system_control_w )
{
	m_dma_status = data;
	if (m_dma_status & 0x3e)
		HandleRomTransfers(data & 0x3e);
	if (m_dma_status & 0x01)
		HandleReset();
}


// TODO: actual timing of this
void ygv608_device::HandleReset()
{
	int i;
	/* Clear ports #0-7 */
	//memset( &m_ports.b[0], 0, 8 );
	// most likely variables to be reset here from ports, there might be more
	m_pattern_name_base_w = 0;
	m_pattern_name_base_r = 0;
	m_register_address = 0;
	m_register_autoinc_r = false;
	m_register_autoinc_w = false;

	/* Clear registers #0-38, #47-49 */
	for(i=0;i<39;i++)
		m_iospace->write_byte(i, 0x00);
	for(i=47;i<50;i++)
		m_iospace->write_byte(i, 0x00);

//  memset( &m_regs.b[0], 0, 39 );
//  memset( &m_regs.b[47], 0, 3 );

	/* Clear internal ram */
	memset( m_pattern_name_table, 0, 4096 );
	memset( m_sprite_attribute_table.b, 0,
			SPRITE_ATTR_TABLE_SIZE );
	memset( m_scroll_data_table, 0, 2*256 );
	memset( m_colour_palette, 0, 256*3 );
}

/*
    The YGV608 has a function to block-move data from the rom into
    internal tables. This function is not used in NCV1, but I used
    it for testing trojan ROM software.
    - So leave it in!
 */
void ygv608_device::HandleRomTransfers(uint8_t type)
{
	popmessage("ROM DMA used %02x",type);

#if 0
	// TODO: eventually update this code to latest
	static uint8_t *sdt = (uint8_t *)m_scroll_data_table;
	static uint8_t *sat = (uint8_t *)m_sprite_attribute_table.b;

	/* fudge copy from sprite data for now... */
	uint8_t *RAM = machine.memory_region[0];
	int i;

	int src = ( ( (int)m_regs.s.tb13 << 8 ) +
			(int)m_regs.s.tb5 ) << 5;
	int bytes = (int)m_regs.s.tn4 << 4;

	logerror( "Transferring data from rom...\n" );

	/* pattern name table */
	if( m_ports.s.tn ) {
	}

	/* scroll table */
	if( m_ports.s.tl ) {
	int dest = (int)m_regs.s.sca;
	if( m_regs.s.p2_b_a )
		dest += 0x100;

	/* fudge a transfer for now... */
	for( i=0; i<bytes; i++ ) {
		sdt[(dest+i)%512] = RAM[src+(i^0x01)];

	}

	/* flag as finished */
	m_ports.s.tl = 0;
	}

	/* sprite attribute table */
	if( m_ports.s.ts ) {
	int dest = (int)m_sprite_address;

	/* fudge a transfer for now... */
	for( i=0; i<bytes; i++ ) {
		sat[(dest+i)%256] = RAM[src+(i^0x01)];

	}

	/* flag as finished */
	m_ports.s.ts = 0;
	}
#endif
}

/***************************************
 *
 * Register Interface routines
 *
 ****************************************/

 // R#0R - Pattern Name Table Access pointer Y
READ8_MEMBER( ygv608_device::pattern_name_table_y_r )
{
	return (m_ytile_autoinc << 7) | (m_plane_select_access << 6) | m_ytile_ptr;
}

 // R#0W - Pattern Name Table Access pointer Y
WRITE8_MEMBER( ygv608_device::pattern_name_table_y_w )
{
	m_ytile_ptr = data & 0x3f;
	//if (yTile >= m_page_y)
	//  logerror ("%s:setting pny(%d) >= page_y(%d)\n", machine().describe_context(),
	//      yTile, m_page_y );
	m_ytile_ptr &= m_page_y -1;
	m_ytile_autoinc = BIT(data,7);
	m_plane_select_access = BIT(data,6);
	// TODO: done by Dig Dug Original
	if(m_ytile_autoinc == true && m_xtile_autoinc == true)
		logerror("%s: Warning both X/Y Tiles autoinc enabled!\n",this->tag());
}

 // R#1R - Pattern Name Table Access pointer X
READ8_MEMBER( ygv608_device::pattern_name_table_x_r )
{
	return (m_xtile_autoinc << 7) | m_xtile_ptr;
}

 // R#1W - Pattern Name Table Access pointer X
WRITE8_MEMBER( ygv608_device::pattern_name_table_x_w )
{
	m_xtile_ptr = data & 0x3f;
	//if (xTile >= m_page_x)
	//  logerror ("%s:setting pnx(%d) >= page_x(%d)\n", machine().describe_context(),
	//      xTile, m_page_x );
	m_xtile_ptr &= m_page_x -1;
	m_xtile_autoinc = BIT(data,7);
	// TODO: done by Dig Dug Original
	if(m_ytile_autoinc == true && m_xtile_autoinc == true)
		logerror("%s: Warning both X/Y Tiles autoinc enabled!\n",this->tag());
}

// R#2R - Built in RAM access control
/***
 * x--- ---- CPAW Address autoincrements after color palette write
 * -x-- ---- CPAR Address autoincrements after color palette read
 * ---x ---- B/(A) P#2 plane access select (1=B Plane)
 * ---- x--- SCAW Address autoincrements after scroll data write
 * ---- -x-- SCAR Address autoincrements after scroll data read
 * ---- --x- SAAW Address autoincrements after sprite attribute table write
 * ---- ---x SAAR Address autoincrements after sprite attribute table read
 ***/
READ8_MEMBER( ygv608_device::ram_access_ctrl_r )
{
	return (m_cpaw<<7) | (m_cpar<<6) |
		   (m_ba_plane_scroll_select<<4) |
		   (m_scaw<<3) | (m_scar<<2) | (m_saaw<<1) | (m_saar<<0);
}

// R#2W - Built in RAM access control
WRITE8_MEMBER( ygv608_device::ram_access_ctrl_w )
{
	m_saar = BIT(data,0);
	m_saaw = BIT(data,1);
	m_scar = BIT(data,2);
	m_scaw = BIT(data,3);
	m_ba_plane_scroll_select = BIT(data,4);
	m_cpar = BIT(data,6);
	m_cpaw = BIT(data,7);
}


// R#3R - sprite attribute table access pointer
READ8_MEMBER( ygv608_device::sprite_address_r )
{
	return m_sprite_address;
}

// R#3W - sprite attribute table access pointer
WRITE8_MEMBER( ygv608_device::sprite_address_w )
{
	m_sprite_address = data;
}


 // R#4R - scroll table access pointer
READ8_MEMBER( ygv608_device::scroll_address_r )
{
	return m_scroll_address;
}

 // R#4W - scroll table access pointer
WRITE8_MEMBER( ygv608_device::scroll_address_w )
{
	m_scroll_address = data;
}

 // R#5R - color palette access pointer
READ8_MEMBER( ygv608_device::palette_address_r )
{
	return m_palette_address;
}

 // R#5W - color palette access pointer
WRITE8_MEMBER( ygv608_device::palette_address_w )
{
	m_palette_address = data;
}

// R#6R - sprite generator base address
READ8_MEMBER( ygv608_device::sprite_bank_r )
{
	return m_sprite_bank;
}

// R#6W - sprite generator base address
WRITE8_MEMBER( ygv608_device::sprite_bank_w )
{
	m_sprite_bank = data;
}

// R#7R - screen control 7
/***
 * x--- ---- DCKM dot clock frequency (0 = 1/2 1 = 1/4)
 * -x-- ---- FLIP reverse display in pattern name
 * ---- x--- ZRON enables ROZ features
 * ---- -xx- MDx  planes display mode
 * ---- -11-      1 plane/256 colors (16 bits)
 * ---- -10-      1 plane/16 colors (16 bits)
 * ---- -01-      2 planes/16 bits
 * ---- -00-      2 planes/8 bits
 * ---- ---x DSPE display permission of pattern planes (screen blanked if 0)
 ***/
READ8_MEMBER( ygv608_device::screen_ctrl_7_r )
{
	return (m_dckm<<7)|(m_flip<<6)|
		   (m_zron<<3)|((m_md & 3)<<1)|(m_dspe<<0);
}

// R#7W - screen control 7
WRITE8_MEMBER( ygv608_device::screen_ctrl_7_w )
{
	uint8_t new_md = (data >> 1) & 3;
	if( new_md != m_md)
		m_tilemap_resize = true;

	m_dckm = BIT(data,7);
	m_flip = BIT(data,6);
	m_zron = BIT(data,3);
	m_md = new_md;
	m_dspe = BIT(data,0);

	m_na8_mask = ((m_flip == true) ? 0x03 : 0x0f );

	// changing mode resets the pattern name table states (Mappy Arrange)
	m_p0_state = 0;
	pattern_mode_setup();
// TODO: add dot clock into CRTC
//  screen_configure();
}

inline void ygv608_device::pattern_mode_setup()
{
	m_bits16 = (m_md == MD_2PLANE_8BIT ? 0 : 1 );

	if(m_md == MD_2PLANE_16BIT )
		m_page_x = m_page_y = 32;
	else
	{
		if (m_page_size == false )
		{
			m_page_x = 64;
			m_page_y = 32;
		}
		else
		{
			m_page_x = 32;
			m_page_y = 64;
		}
	}
	m_pny_shift = ( m_page_x == 32 ? 5 : 6 );

	/* bits to shift pattern y coordinate to extract base */
	m_base_y_shift = ( m_page_y == 32 ? 2 : 3 );
}

// R#8R - screen control 8
/***
 * xx-- ---- HDS horizontal display domain size (0=4096, 3=512)
 * --xx ---- VDS vertical display domain size (0=4096, 3=512)
 * ---- x--- RLRT ROZ wraparound disable
 * ---- -x-- RLSC scroll wraparound disable
 * ---- ---x PGS page size (0=64x32, 1=32x64; Mode 2=32x32)
 ***/
READ8_MEMBER( ygv608_device::screen_ctrl_8_r )
{
	return (m_h_display_size<<6)|(m_v_display_size<<4)|
		   (m_roz_wrap_disable<<3)|(m_scroll_wrap_disable<<2)|
		   (m_page_size<<0);
}

// R#8W - screen control 8
WRITE8_MEMBER( ygv608_device::screen_ctrl_8_w )
{
	if( (data & 1) != m_page_size)
		m_tilemap_resize = true;

/**/m_h_display_size = (data >> 6) & 3;
/**/m_v_display_size = (data >> 4) & 3;
	m_roz_wrap_disable = BIT(data,3);
/**/m_scroll_wrap_disable = BIT(data,2);
	m_page_size = BIT(data,0);

	pattern_mode_setup();
}

// R#9R - screen control 9
/***
 * xx-- ---- PTS: pattern size in pattern planes (8x8, 16x16, 32x32, 64x64)
 * --xx x--- SLH: size of horizontal division in screen division scrolling
 * ---- -xxx SLV: size of vertical division in screen division scrolling
 * ---- -111 64 dots division
 * ---- -110 32 dots division
 * ---- -101 16 dots division
 * ---- -100 8 dots division
 * ---- -000 entire screen
 ***/
READ8_MEMBER( ygv608_device::screen_ctrl_9_r )
{
	return (m_pattern_size<<6)|
		   (m_h_div_size<<3)|(m_v_div_size<<0);
}

WRITE8_MEMBER( ygv608_device::screen_ctrl_9_w )
{
	uint8_t new_pts = (data >> 6) & 3;

	if(new_pts != m_pattern_size)
		m_tilemap_resize = true;

	m_pattern_size = new_pts;
/**/m_h_div_size = (data >> 3) & 7;
	m_v_div_size = (data >> 0) & 7;

	//popmessage("%02x %02x",m_h_div_size,m_v_div_size);

	// TODO: this code is garbage ...
	if(m_v_div_size == 0)
		m_col_shift = 8;
	else
	{
		if (m_pattern_size == PTS_8X8 )
			m_col_shift = (m_v_div_size) - 4;
		else
			m_col_shift = (m_v_div_size) - 5;
		if( m_col_shift < 0 )
		{
			// we can't handle certain conditions
			logerror( "Unhandled slv condition (pts=$%X,slv=$%X)\n",
						m_pattern_size, m_v_div_size);
			m_col_shift = 8;
		}
	}
}

// R#10R - screen control 10: mosaic & sprite
/***
 * xx-- ---- SPAx: Auxiliary bits of sprite attribute table (0=8x8 or no flip, 1=16x16 or flipy, 2=32x32 or flipx, 3=64x64 or flipx & y )
 * --x- ---- SPAS: Auxiliary function select (0=SPAx selects sprite size, 1=SPAx selects flipping)
 * ---x ---- SPRD: Sprite display disable
 * ---- xx-- MCBx: Mosaic enable on plane B
 * ---- --xx MCAx: Mosaic enable on plane A
 ***/
READ8_MEMBER( ygv608_device::screen_ctrl_10_r )
{
	return (m_sprite_aux_reg << 6) | ((m_sprite_aux_mode == true) << 5) | ((m_sprite_disable == true) << 4)
								   | (m_mosaic_bplane << 2) | (m_mosaic_aplane & 3);
}

// R#10W - screen control: mosaic & sprite
WRITE8_MEMBER( ygv608_device::screen_ctrl_10_w )
{
	m_sprite_aux_reg = (data & 0xc0) >> 6;
	m_sprite_aux_mode = BIT(data, 5);
	m_sprite_disable = BIT(data, 4);

	// check mosaic
	m_mosaic_bplane = (data & 0xc) >> 2;
	m_mosaic_aplane = data & 3;
//  if(m_mosaic_aplane || m_mosaic_bplane)
//      popmessage("Mosaic effect %02x %02x",m_mosaic_aplane,m_mosaic_bplane);
}

// R#11R - screen control 11
READ8_MEMBER( ygv608_device::screen_ctrl_11_r )
{
	return (m_scm<<6)|(m_yse<<5)|(m_cbdr<<4)|
		   (m_priority_mode<<2)|(m_planeB_trans_enable<<1)|(m_planeA_trans_enable<<0);
}

// R#11W - screen control 11
WRITE8_MEMBER( ygv608_device::screen_ctrl_11_w )
{
/**/m_scm = (data >> 6) & 3;
/**/m_yse = BIT(data,5);
/**/m_cbdr = BIT(data,4);
	m_priority_mode = (data >> 2) & 3;
	m_planeB_trans_enable = BIT(data,1);
	m_planeA_trans_enable = BIT(data,0);
}

// R#12R - screen control 12: color fetch modes
READ8_MEMBER( ygv608_device::screen_ctrl_12_r )
{
	return (m_sprite_color_fetch<<6)|(m_planeB_color_fetch<<3)|(m_planeA_color_fetch<<0);
}

// R#12W - screen control 12: color fetch modes
WRITE8_MEMBER( ygv608_device::screen_ctrl_12_w )
{
	m_sprite_color_fetch = (data >> 6) & 3;
	m_planeB_color_fetch = (data >> 3) & 7;
	m_planeA_color_fetch = (data >> 0) & 7;
}

// R#13W - border color
WRITE8_MEMBER( ygv608_device::border_color_w )
{
	m_border_color = data;
}

// R#14R interrupt mask control
READ8_MEMBER( ygv608_device::irq_mask_r )
{
	return (m_raster_irq_mask << 1) | (m_vblank_irq_mask << 0);
}

// R#14W interrupt mask control
WRITE8_MEMBER( ygv608_device::irq_mask_w )
{
	m_vblank_irq_mask = BIT(data, 0);
	m_raster_irq_mask = BIT(data, 1);

	// check if we have an irq in the queue
	vblank_irq_check();
	raster_irq_check();
}

// R#15R / R#16R raster interrupt control
READ8_MEMBER( ygv608_device::irq_ctrl_r )
{
	uint8_t res;

	if(offset == 0) // R#15
		res = m_raster_irq_vpos & 0xff;
	else // R#16
	{
		res = (m_raster_irq_mode << 7);

		res|= (BIT(m_raster_irq_vpos, 8) << 6);

		res|= (m_raster_irq_hpos / 32) & 0x1f;
	}

	return res;
}

// R#15W / R#16W raster interrupt control
WRITE8_MEMBER( ygv608_device::irq_ctrl_w )
{
	if(offset == 0) // R#15
	{
		m_raster_irq_vpos &= ~0xff;
		m_raster_irq_vpos |= data & 0xff;
	}
	else // R#16
	{
		m_raster_irq_mode = BIT(data,7);

		m_raster_irq_vpos &= ~0x100;
		m_raster_irq_vpos |= BIT(data,6) << 8;

		m_raster_irq_hpos = (data & 0x1f) * 32;
	}

	// reset raster timer
	m_raster_timer->reset();
	m_raster_timer->adjust(raster_sync_offset(), 0);

	//printf("%d %d %d %d %d\n",m_raster_irq_hpos,m_raster_irq_vpos,m_raster_irq_mode,m_crtc.htotal,m_crtc.vtotal);
}

// helper for validating and convert to screen position
attotime ygv608_device::raster_sync_offset()
{

	// don't care if h/v pos is higher than CRTC params (NCV2 POST)
	if(m_raster_irq_hpos >  m_crtc.htotal || m_raster_irq_vpos > m_crtc.vtotal )
		return attotime::never;

	// bail out and throw an error if this happens to be used someday
	if(m_raster_irq_mode == true)
	{
		popmessage("Raster IRQ used with mode = true");
		return attotime::never;
	}

	// TODO: actual sync not taken into account, needs a better test than NCV2 limited case
	return screen().time_until_pos(m_raster_irq_vpos,m_raster_irq_hpos);
}

// R#17 / R#24 - base address
/*
 * offset & 4 selects plane B
 * -xxx ---- write to base address + 1
 * ---- -xxx write to base address
 */
WRITE8_MEMBER( ygv608_device::base_address_w )
{
	int plane = offset >> 2;
	int addr = ( offset << 1 ) & 0x07;
	m_base_addr[plane][addr] = data & 0x07;
	m_base_addr[plane][addr+1] = (data >> 4) & 0x7;

	m_tilemap_resize = true;
}

// R#25W - R#27W - X coordinate of initial value
WRITE8_MEMBER( ygv608_device::roz_ax_w )  { m_ax = roz_convert_raw24(&m_raw_ax,offset,data); }

// R#28W - R#29W - increment of coordinate in X direction
WRITE8_MEMBER( ygv608_device::roz_dx_w )  { m_dx = roz_convert_raw16(&m_raw_dx,offset,data); }

// R#30W - R#31W - increment of coordinate in X direction in movement toward Y direction
WRITE8_MEMBER( ygv608_device::roz_dxy_w ) { m_dxy = roz_convert_raw16(&m_raw_dxy,offset,data); }

// R#32W - R#34W - Y coordinate of initial value
WRITE8_MEMBER( ygv608_device::roz_ay_w )  { m_ay = roz_convert_raw24(&m_raw_ay,offset,data); }

// R#35W - R#36W - increment of coordinate in Y direction
WRITE8_MEMBER( ygv608_device::roz_dy_w )  { m_dy = roz_convert_raw16(&m_raw_dy,offset,data); }

// R#37W - R#38W - increment of coordinate in Y direction in movement toward X direction
WRITE8_MEMBER( ygv608_device::roz_dyx_w ) { m_dyx = roz_convert_raw16(&m_raw_dyx,offset,data); }

// ROZ assign helpers
inline uint32_t ygv608_device::roz_convert_raw24(uint32_t *raw_reg, uint8_t offset, uint8_t data)
{
	const uint32_t roz_data_mask24 = 0x1fffff;
	const uint32_t mem_mask = (0xff << offset*8) ^ ~0;
	uint32_t res;

	// substitute the new byte value into the raw register
	*raw_reg &= mem_mask;
	*raw_reg |= data << offset*8;

	// convert raw to the given register
	res = *raw_reg & roz_data_mask24;
	res <<= 7;
	if( res & 0x08000000 ) res |= 0xf8000000;   // 2s complement

	return res;
}

inline uint32_t ygv608_device::roz_convert_raw16(uint16_t *raw_reg, uint8_t offset, uint8_t data)
{
	const uint16_t roz_data_mask16 = 0x1fff;
	const uint16_t mem_mask = (0xff << offset*8) ^ ~0;
	uint32_t res;

	// substitute the new byte value into the raw register
	*raw_reg &= mem_mask;
	*raw_reg |= data << offset*8;

	// convert raw to the given register
	res = *raw_reg & roz_data_mask16;
	res <<= 7;
	if( res & 0x00080000 ) res |= 0xfff80000;   // 2s complement

	return res;
}

// R#39W - R#46W display scan control write
WRITE8_MEMBER( ygv608_device::crtc_w )
{
	//printf("[%d] <- %02x\n",offset+39,data);

	switch(offset+39)
	{
		case 39:
		{
			m_crtc.display_hsync = ((data >> 5) & 7) * 16;
			m_crtc.border_width = (data & 0x1f) * 16;
			break;
		}

		case 40:
		{
			int new_display_width = (data & 0x3f) * 16;

			m_crtc.htotal &= ~0x600;
			m_crtc.htotal |= ((data & 0xc0) << 3);

			if(new_display_width != m_crtc.display_width)
				m_screen_resize = true;

			m_crtc.display_width = new_display_width;
			break;
		}

		case 41:
		{
			m_crtc.display_hstart &= ~0x1fe;
			m_crtc.display_hstart |= (data & 0xff) << 1;
			break;
		}

		case 42:
		{
			m_crtc.htotal &= ~0x1fe;
			m_crtc.htotal |= ((data & 0xff) << 1);

			//printf("H %d %d %d %d %d\n",m_crtc.htotal,m_crtc.display_hstart,m_crtc.display_width,m_crtc.display_hsync,m_crtc.border_width);
			break;
		}

		case 43:
		{
			m_crtc.display_vsync = (data >> 5) & 7;
			m_crtc.border_height = (data & 0x1f) * 8;
			break;
		}

		case 44:
		{
			int new_display_height = (data & 0x3f) * 8;

			// TODO: VSLS, bit 6
			if(new_display_height != m_crtc.display_height)
				m_screen_resize = true;

			m_crtc.display_height = new_display_height;
			break;
		}

		case 45:
		{
			m_crtc.vtotal &= ~0x100;
			m_crtc.vtotal |= BIT(data,7) << 8;

			// TODO: TRES, bit 6

			m_crtc.display_vstart = data & 0x3f;
			break;
		}

		case 46:
		{
			m_crtc.vtotal &= ~0xff;
			m_crtc.vtotal |= data & 0xff;

			// TODO: call it for all mods in the CRTC, add sanity checks
			screen_configure();

			//printf("V %d %d %d %d %d\n",m_crtc.vtotal,m_crtc.display_vstart,m_crtc.display_height,m_crtc.display_vsync,m_crtc.border_height);
			break;
		}
	}
}

// TODO: all horizontal values needs to be divided by 2, presumably some other register?
// TODO: h/vstart not taken into account (needs video mods)
void ygv608_device::screen_configure()
{
//  int display_hend = (m_crtc.display_hstart + (m_crtc.display_width / 2)) - 1;
	int display_hend = (m_crtc.display_width / 2) - 1;
//  int display_vend = (m_crtc.display_vstart + m_crtc.display_height) - 1;
	int display_vend = (m_crtc.display_height) - 1;

	//rectangle visarea(m_crtc.display_hstart, display_hend, m_crtc.display_vstart, display_vend);
	rectangle visarea(0, display_hend, 0, display_vend);

	// TODO: Dig Dug Original wants this to be 60.60 Hz (like original Namco HW), lets compensate somehow
	//      (clock is really 6144000 x 8 = 49152000, so it must have same parameters in practice)
	attoseconds_t period = HZ_TO_ATTOSECONDS(screen().clock()) * (m_crtc.vtotal + m_crtc.display_vsync) * ((m_crtc.htotal + 12 - m_crtc.display_hsync) / 2);

	screen().configure(m_crtc.htotal / 2, m_crtc.vtotal, visarea, period );

	// reset vblank timer
	m_vblank_timer->reset();
	//m_vblank_timer->adjust(screen().time_until_pos(m_crtc.display_vstart+m_crtc.display_height,0), 0, screen().frame_period());
	m_vblank_timer->adjust(screen().time_until_pos(m_crtc.display_height,0), 0, screen().frame_period());
}