summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/decocass.cpp
blob: a93edf2fbfca5af1c057df4c1648c7acfe1051f8 (plain) (tree)
1
2
3
4
5
6

                                                       



                                                                        






                                                                  

                                                                   

                                                                  


















                                                                  


                                                                 

                                                             

                                                                         
                                                               
                                                       
                                                   
                                                            
                                                                   
                   




                                                                
                                                               























                                                                       
                                                           

                                                          
                                                 






































                                                                     
 

                                                                         
                
                              
 
 
                                            




































                                                                                                                                                                                                        













                                                     





                                              
                                                            




                                                     
                                                            




                                                 
                                                        
 
                                                  
                               
                                                      
                                      
                           

                                                 

 
                                                         
 
                                                  
                               
                                                      
                                      
                                    

                                                 

 
                                                       
 

                                                
                               
                                                
                                                   






                                              
                                                                                                                  
 
                                      
 

                                                                         

                       
                                                                                           
 
                                         

                          
                                      
 







































                                                                                                                               

 
                                                                                 



                                
                                      
                           
                                      
                           
                                      
                           
                                      

                                                                              

                                                  

                               
                                                                             
                 
                                                                                                 
                                                         
                                                                                               
                                                                                             






                                              
                                                     

          


                                                                

                                    
                                    
                                                                                                                    

 
                                                  
 
                                 
                          
                                                             
                        
                                                              


 
                                                     
 

                                              

 
                                                   
 

                                              

 
                                                       
 

                                                

 
                                                  
 
                                 
                                            
                                                            
                                                              

                                           

 
                                                    
 
                                   
                              

                                           

 
                                                     
 

                                    


                                                              
                                                         

                                                            
                                       

 
                                                        

                                                           
                               

 
                                                         


                                                            



                                  
                                       


  

                 






                     
                                                   
 
                               






                                                                       
                                                                                  


                                                        
                          

 
                                                           
 
                                       
                       
                                                                                                             
          








                                
 
                                               
         

                                                 
         


                                               

 
                                                       
 
                                   

                                                          
                              

 
                                                        
 
                                    

                                                           
                               

 
                                                        
 
                                    

                                                           
                               

 
                                                       
 
                                    

                                                          
                              

 
                                                       
 
                                    

                                                          
                              

 
                                                               
 
                                           

                                                                  
                                      

 
                                                         

                                                            
                                





                                              
                                                                                                                    
                                                                                                     
                                                                                    
 
                              

                                                           
         
                                         



                                                   

                                                             



                                                    
                                  









                                                                    
                                                                   


                                                              
                                                            
 
                                                   

                              
                                                                   


                                                              
                                                            



         
                                                                                                          
                                                                                                       
                                                                                     
 
                       

                                                                           
                                                  
                                                                 
         
                           
 

                                                              
                                  




                                                                     
                                                                 

                                               
                                                                                 
                                 
                                                                                          

                                                                        


                                     

                                                              
                                  




                                                                     
                                                                 

                                               
                                                                                 
                                 
                                                                                                 

                                                                        




                                     






































                                                                                                       
                                                





                                                                                                                                       

                                                           


                                                     
                                       
 



                                                                                                                                                                      
                                                                                                     




                                                                                                                   
                                                   

                                                  
                                             




                 
 
                                  
 


                                                                                                                                                                                                                                       
 


                                               
 
                                                       
                                                
 
                                                       
                                            
 
                                                                        
                                 
                                                   
 



                                                     
 

                                                      

 
                                                                                                                       
 
                                                         
 
                                                                                   
                                                                       
 
                                          
                                             
                                        
                                             
 


                                                               

                 
                                                                   

                                       
                                                                                                                                 









                                                       


         


                                                  
 
                                                  
         

                                                     

         
                              
         
                                              


            
                                              
                                                          
                 

                                                              

                 


                                                     
                                                                                                 
                                                                                                                                             

                                                           
                              
                                                                                                          

                                   



                                                                            
 

                 
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, David Haywood
/***********************************************************************

    DECO Cassette System video

    The video system has clearly been designed for Highway Chase,
    which unsurprisingly is the first game on the system.  The
    background 'tilemap' is very much like the road layer on the
    standalone Highway Chase with a concept of left/right edges
    with semi-independent scrolling, and the ability to transition
    between scrolling different sections.

    Additionally it supports the headlight and tunnel effects also
    needed for a Highway Chase style game. These both produce a pen
    modification effect mapped to bit 4 of the palette, unless bit
    5 of the mode register is set.

    ---

    Notes with reference to video recordings.
    These video recordings should be from real hardware because
    they predate the emulation and include undumped games, so
    unless they're from some other private / unreleased emulator
    then they can't be anything else.

    Mirrored from NicoVideo
    -=====================-

    mamedev.emulab.it/haze/reference/sm18976245-DISCO_NO1.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm18976058-ASTRO_FANTASIA.mp4
        - different game revision to emulated version, main
          boss enemy shown at the top of the scoreboard differs
          so notes below could be invalid
        - bullets should be white, not black (OK)
        - BG layer changes to orange colours for first level, but
          reverts to red when player explodes

    mamedev.emulab.it/haze/reference/sm18975592-HWY_CHASE.mp4
        - road / bg colour should be darkish blue outside of tunnels (OK)
        - road / bg colour should be black in tunnels (OK)
        - headlight should be the same darkish blue as the road
          at all times, so only visible in tunnels (OK)
        - center line of road does not exist on hw!
        - enemies are hidden in tunnels (like madalien) (OK)
        - road / bg flashs regular blue when enemy is hit revealing
          them (OK)
        - some glitchy enemies visible even over tunnel bg for
          some frames
        - colours of BG tilemap are glitchy even on hardware eg.
          Pink desert after first tunnel, Green water after 2nd
          tunnel even when the right palettes exist!
        - player bullets are yellow, enemy bullets are red (OK)

    mamedev.emulab.it/haze/reference/sm17433759-PRO_BOWLING.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm17401258-GRAPLOP.mp4
        - different game revision to emulated version, this
          seems to be a more finished version of cgralop2, the
          emulated version lacks a title screen (the parent
          cgraplop has a cluster buster title, but that is
          again different)


    mamedev.emulab.it/haze/reference/sm17387280-BURNIN_RUBBER.mp4
        - seems to be the cburnrub2 set, or close to it, plain
          white title text

    mamedev.emulab.it/haze/reference/sm17370209-NIGHT_STAR.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm17203184-HAMBURGER.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm17202585-SUPER_DOUBLE_TENNIS.mp4
        - background colours during high-score / title ar shades of
          blue, not green as in previous emulation (OK now)

    mamedev.emulab.it/haze/reference/sm17202201-SKATER.mp4
        - the game turns on the 'cross' bit, why?

    mamedev.emulab.it/haze/reference/sm17201813-ZEROIZE.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm17183561-FISHING.mp4
        - first title screen has no background, this is not a bug in
          our emulation
        - can show glitchy tiles when constructing the background,
          this is not a bug in our emulation either

    mamedev.emulab.it/haze/reference/sm17181931-MISSION_X.mp4
        - no notes

    mamedev.emulab.it/haze/reference/sm17180950-DSTELEJAN.mp4
        - no notes

    Mirrored from YouTube
    -===================-

    mamedev.emulab.it/haze/reference/manhattan01-04.webm
    mamedev.emulab.it/haze/reference/manhattan05-08.webm
    mamedev.emulab.it/haze/reference/manhattan09-12.webm
        - the BG tilemap pen ordering changes between levels, most of
          the arrangements aren't supported by our current code, and
          I can't find the writes to change it!  Level 1 in the
          video uses what we have as palette 1, not 0.
          ToDo: list combinations

    mamedev.emulab.it/haze/reference/flashboy.webm
        - game is not emulated


    ---

    I'd quite like a reference video for the Cassette Pro Soccer,
    the game appears ugly (center circle vanishing as soon as you do
    a long ball etc.) but the ugly backwards scrolling after you kick
    the ball still happens even on the standalone version, so I'm
    wondering if it's just a glitchy game.

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

#include "emu.h"
#include "includes/decocass.h"


static const uint32_t tile_offset[32*32] = {
	0x078,0x079,0x07a,0x07b,0x07c,0x07d,0x07e,0x07f,0x0ff,0x0fe,0x0fd,0x0fc,0x0fb,0x0fa,0x0f9,0x0f8,0x278,0x279,0x27a,0x27b,0x27c,0x27d,0x27e,0x27f,0x2ff,0x2fe,0x2fd,0x2fc,0x2fb,0x2fa,0x2f9,0x2f8,
	0x070,0x071,0x072,0x073,0x074,0x075,0x076,0x077,0x0f7,0x0f6,0x0f5,0x0f4,0x0f3,0x0f2,0x0f1,0x0f0,0x270,0x271,0x272,0x273,0x274,0x275,0x276,0x277,0x2f7,0x2f6,0x2f5,0x2f4,0x2f3,0x2f2,0x2f1,0x2f0,
	0x068,0x069,0x06a,0x06b,0x06c,0x06d,0x06e,0x06f,0x0ef,0x0ee,0x0ed,0x0ec,0x0eb,0x0ea,0x0e9,0x0e8,0x268,0x269,0x26a,0x26b,0x26c,0x26d,0x26e,0x26f,0x2ef,0x2ee,0x2ed,0x2ec,0x2eb,0x2ea,0x2e9,0x2e8,
	0x060,0x061,0x062,0x063,0x064,0x065,0x066,0x067,0x0e7,0x0e6,0x0e5,0x0e4,0x0e3,0x0e2,0x0e1,0x0e0,0x260,0x261,0x262,0x263,0x264,0x265,0x266,0x267,0x2e7,0x2e6,0x2e5,0x2e4,0x2e3,0x2e2,0x2e1,0x2e0,
	0x058,0x059,0x05a,0x05b,0x05c,0x05d,0x05e,0x05f,0x0df,0x0de,0x0dd,0x0dc,0x0db,0x0da,0x0d9,0x0d8,0x258,0x259,0x25a,0x25b,0x25c,0x25d,0x25e,0x25f,0x2df,0x2de,0x2dd,0x2dc,0x2db,0x2da,0x2d9,0x2d8,
	0x050,0x051,0x052,0x053,0x054,0x055,0x056,0x057,0x0d7,0x0d6,0x0d5,0x0d4,0x0d3,0x0d2,0x0d1,0x0d0,0x250,0x251,0x252,0x253,0x254,0x255,0x256,0x257,0x2d7,0x2d6,0x2d5,0x2d4,0x2d3,0x2d2,0x2d1,0x2d0,
	0x048,0x049,0x04a,0x04b,0x04c,0x04d,0x04e,0x04f,0x0cf,0x0ce,0x0cd,0x0cc,0x0cb,0x0ca,0x0c9,0x0c8,0x248,0x249,0x24a,0x24b,0x24c,0x24d,0x24e,0x24f,0x2cf,0x2ce,0x2cd,0x2cc,0x2cb,0x2ca,0x2c9,0x2c8,
	0x040,0x041,0x042,0x043,0x044,0x045,0x046,0x047,0x0c7,0x0c6,0x0c5,0x0c4,0x0c3,0x0c2,0x0c1,0x0c0,0x240,0x241,0x242,0x243,0x244,0x245,0x246,0x247,0x2c7,0x2c6,0x2c5,0x2c4,0x2c3,0x2c2,0x2c1,0x2c0,
	0x038,0x039,0x03a,0x03b,0x03c,0x03d,0x03e,0x03f,0x0bf,0x0be,0x0bd,0x0bc,0x0bb,0x0ba,0x0b9,0x0b8,0x238,0x239,0x23a,0x23b,0x23c,0x23d,0x23e,0x23f,0x2bf,0x2be,0x2bd,0x2bc,0x2bb,0x2ba,0x2b9,0x2b8,
	0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x0b7,0x0b6,0x0b5,0x0b4,0x0b3,0x0b2,0x0b1,0x0b0,0x230,0x231,0x232,0x233,0x234,0x235,0x236,0x237,0x2b7,0x2b6,0x2b5,0x2b4,0x2b3,0x2b2,0x2b1,0x2b0,
	0x028,0x029,0x02a,0x02b,0x02c,0x02d,0x02e,0x02f,0x0af,0x0ae,0x0ad,0x0ac,0x0ab,0x0aa,0x0a9,0x0a8,0x228,0x229,0x22a,0x22b,0x22c,0x22d,0x22e,0x22f,0x2af,0x2ae,0x2ad,0x2ac,0x2ab,0x2aa,0x2a9,0x2a8,
	0x020,0x021,0x022,0x023,0x024,0x025,0x026,0x027,0x0a7,0x0a6,0x0a5,0x0a4,0x0a3,0x0a2,0x0a1,0x0a0,0x220,0x221,0x222,0x223,0x224,0x225,0x226,0x227,0x2a7,0x2a6,0x2a5,0x2a4,0x2a3,0x2a2,0x2a1,0x2a0,
	0x018,0x019,0x01a,0x01b,0x01c,0x01d,0x01e,0x01f,0x09f,0x09e,0x09d,0x09c,0x09b,0x09a,0x099,0x098,0x218,0x219,0x21a,0x21b,0x21c,0x21d,0x21e,0x21f,0x29f,0x29e,0x29d,0x29c,0x29b,0x29a,0x299,0x298,
	0x010,0x011,0x012,0x013,0x014,0x015,0x016,0x017,0x097,0x096,0x095,0x094,0x093,0x092,0x091,0x090,0x210,0x211,0x212,0x213,0x214,0x215,0x216,0x217,0x297,0x296,0x295,0x294,0x293,0x292,0x291,0x290,
	0x008,0x009,0x00a,0x00b,0x00c,0x00d,0x00e,0x00f,0x08f,0x08e,0x08d,0x08c,0x08b,0x08a,0x089,0x088,0x208,0x209,0x20a,0x20b,0x20c,0x20d,0x20e,0x20f,0x28f,0x28e,0x28d,0x28c,0x28b,0x28a,0x289,0x288,
	0x000,0x001,0x002,0x003,0x004,0x005,0x006,0x007,0x087,0x086,0x085,0x084,0x083,0x082,0x081,0x080,0x200,0x201,0x202,0x203,0x204,0x205,0x206,0x207,0x287,0x286,0x285,0x284,0x283,0x282,0x281,0x280,
	0x178,0x179,0x17a,0x17b,0x17c,0x17d,0x17e,0x17f,0x1ff,0x1fe,0x1fd,0x1fc,0x1fb,0x1fa,0x1f9,0x1f8,0x378,0x379,0x37a,0x37b,0x37c,0x37d,0x37e,0x37f,0x3ff,0x3fe,0x3fd,0x3fc,0x3fb,0x3fa,0x3f9,0x3f8,
	0x170,0x171,0x172,0x173,0x174,0x175,0x176,0x177,0x1f7,0x1f6,0x1f5,0x1f4,0x1f3,0x1f2,0x1f1,0x1f0,0x370,0x371,0x372,0x373,0x374,0x375,0x376,0x377,0x3f7,0x3f6,0x3f5,0x3f4,0x3f3,0x3f2,0x3f1,0x3f0,
	0x168,0x169,0x16a,0x16b,0x16c,0x16d,0x16e,0x16f,0x1ef,0x1ee,0x1ed,0x1ec,0x1eb,0x1ea,0x1e9,0x1e8,0x368,0x369,0x36a,0x36b,0x36c,0x36d,0x36e,0x36f,0x3ef,0x3ee,0x3ed,0x3ec,0x3eb,0x3ea,0x3e9,0x3e8,
	0x160,0x161,0x162,0x163,0x164,0x165,0x166,0x167,0x1e7,0x1e6,0x1e5,0x1e4,0x1e3,0x1e2,0x1e1,0x1e0,0x360,0x361,0x362,0x363,0x364,0x365,0x366,0x367,0x3e7,0x3e6,0x3e5,0x3e4,0x3e3,0x3e2,0x3e1,0x3e0,
	0x158,0x159,0x15a,0x15b,0x15c,0x15d,0x15e,0x15f,0x1df,0x1de,0x1dd,0x1dc,0x1db,0x1da,0x1d9,0x1d8,0x358,0x359,0x35a,0x35b,0x35c,0x35d,0x35e,0x35f,0x3df,0x3de,0x3dd,0x3dc,0x3db,0x3da,0x3d9,0x3d8,
	0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x1d7,0x1d6,0x1d5,0x1d4,0x1d3,0x1d2,0x1d1,0x1d0,0x350,0x351,0x352,0x353,0x354,0x355,0x356,0x357,0x3d7,0x3d6,0x3d5,0x3d4,0x3d3,0x3d2,0x3d1,0x3d0,
	0x148,0x149,0x14a,0x14b,0x14c,0x14d,0x14e,0x14f,0x1cf,0x1ce,0x1cd,0x1cc,0x1cb,0x1ca,0x1c9,0x1c8,0x348,0x349,0x34a,0x34b,0x34c,0x34d,0x34e,0x34f,0x3cf,0x3ce,0x3cd,0x3cc,0x3cb,0x3ca,0x3c9,0x3c8,
	0x140,0x141,0x142,0x143,0x144,0x145,0x146,0x147,0x1c7,0x1c6,0x1c5,0x1c4,0x1c3,0x1c2,0x1c1,0x1c0,0x340,0x341,0x342,0x343,0x344,0x345,0x346,0x347,0x3c7,0x3c6,0x3c5,0x3c4,0x3c3,0x3c2,0x3c1,0x3c0,
	0x138,0x139,0x13a,0x13b,0x13c,0x13d,0x13e,0x13f,0x1bf,0x1be,0x1bd,0x1bc,0x1bb,0x1ba,0x1b9,0x1b8,0x338,0x339,0x33a,0x33b,0x33c,0x33d,0x33e,0x33f,0x3bf,0x3be,0x3bd,0x3bc,0x3bb,0x3ba,0x3b9,0x3b8,
	0x130,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x1b7,0x1b6,0x1b5,0x1b4,0x1b3,0x1b2,0x1b1,0x1b0,0x330,0x331,0x332,0x333,0x334,0x335,0x336,0x337,0x3b7,0x3b6,0x3b5,0x3b4,0x3b3,0x3b2,0x3b1,0x3b0,
	0x128,0x129,0x12a,0x12b,0x12c,0x12d,0x12e,0x12f,0x1af,0x1ae,0x1ad,0x1ac,0x1ab,0x1aa,0x1a9,0x1a8,0x328,0x329,0x32a,0x32b,0x32c,0x32d,0x32e,0x32f,0x3af,0x3ae,0x3ad,0x3ac,0x3ab,0x3aa,0x3a9,0x3a8,
	0x120,0x121,0x122,0x123,0x124,0x125,0x126,0x127,0x1a7,0x1a6,0x1a5,0x1a4,0x1a3,0x1a2,0x1a1,0x1a0,0x320,0x321,0x322,0x323,0x324,0x325,0x326,0x327,0x3a7,0x3a6,0x3a5,0x3a4,0x3a3,0x3a2,0x3a1,0x3a0,
	0x118,0x119,0x11a,0x11b,0x11c,0x11d,0x11e,0x11f,0x19f,0x19e,0x19d,0x19c,0x19b,0x19a,0x199,0x198,0x318,0x319,0x31a,0x31b,0x31c,0x31d,0x31e,0x31f,0x39f,0x39e,0x39d,0x39c,0x39b,0x39a,0x399,0x398,
	0x110,0x111,0x112,0x113,0x114,0x115,0x116,0x117,0x197,0x196,0x195,0x194,0x193,0x192,0x191,0x190,0x310,0x311,0x312,0x313,0x314,0x315,0x316,0x317,0x397,0x396,0x395,0x394,0x393,0x392,0x391,0x390,
	0x108,0x109,0x10a,0x10b,0x10c,0x10d,0x10e,0x10f,0x18f,0x18e,0x18d,0x18c,0x18b,0x18a,0x189,0x188,0x308,0x309,0x30a,0x30b,0x30c,0x30d,0x30e,0x30f,0x38f,0x38e,0x38d,0x38c,0x38b,0x38a,0x389,0x388,
	0x100,0x101,0x102,0x103,0x104,0x105,0x106,0x107,0x187,0x186,0x185,0x184,0x183,0x182,0x181,0x180,0x300,0x301,0x302,0x303,0x304,0x305,0x306,0x307,0x387,0x386,0x385,0x384,0x383,0x382,0x381,0x380
};

/********************************************
    state saving setup
 ********************************************/
void decocass_state::decocass_video_state_save_init()
{
	save_item(NAME(m_watchdog_count));
	save_item(NAME(m_watchdog_flip));
	save_item(NAME(m_color_missiles));
	save_item(NAME(m_color_center_bot));
	save_item(NAME(m_mode_set));
	save_item(NAME(m_back_h_shift));
	save_item(NAME(m_back_vl_shift));
	save_item(NAME(m_back_vr_shift));
	save_item(NAME(m_part_h_shift));
	save_item(NAME(m_part_v_shift));
	save_item(NAME(m_center_h_shift_space));
	save_item(NAME(m_center_v_shift));
}

/********************************************
    tilemap callbacks
 ********************************************/

TILEMAP_MAPPER_MEMBER(decocass_state::fgvideoram_scan_cols )
{
	/* logical (col,row) -> memory offset */
	return (num_cols - 1 - col) * num_rows + row;
}

TILEMAP_MAPPER_MEMBER(decocass_state::bgvideoram_scan_cols )
{
	/* logical (col,row) -> memory offset */
	return tile_offset[col * num_rows + row];
}

TILE_GET_INFO_MEMBER(decocass_state::get_bg_l_tile_info)
{
	int color = (m_color_center_bot >> 7) & 1;
	SET_TILE_INFO_MEMBER(2,
			m_bgvideoram[tile_index] >> 4,
			color * 4 + 1,
			0);
	if (tile_index & 0x80)
		tileinfo.pen_data = m_empty_tile;
}

TILE_GET_INFO_MEMBER(decocass_state::get_bg_r_tile_info )
{
	int color = (m_color_center_bot >> 7) & 1;
	SET_TILE_INFO_MEMBER(2,
			m_bgvideoram[tile_index] >> 4,
			color * 4 + 1,
			TILE_FLIPY);
	if (!(tile_index & 0x80))
		tileinfo.pen_data = m_empty_tile;
}

TILE_GET_INFO_MEMBER(decocass_state::get_fg_tile_info )
{
	uint8_t code = m_fgvideoram[tile_index];
	uint8_t attr = m_colorram[tile_index];
	SET_TILE_INFO_MEMBER(0,
			256 * (attr & 3) + code,
			BIT(m_color_center_bot, 0),
			0);
}

/********************************************
    big object
 ********************************************/

void decocass_state::draw_special_priority(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect)
{
	int crossing = m_mode_set & 3;

	// in daylight or during explosion
	if ((crossing == 0 || BIT(m_mode_set, 6)) && !BIT(m_mode_set, 5))
		return;

	int color = (bitswap<8>(m_color_center_bot, 0, 1, 7, 2, 3, 4, 5, 6) & 0x27) | 0x08;

	int sy = 64 - m_part_v_shift + 1;
	if (sy < 0)
		sy += 256;
	int sx = m_part_h_shift - 128;

	const uint8_t *objdata0 = m_gfxdecode->gfx(3)->get_data(0);
	const uint8_t *objdata1 = m_gfxdecode->gfx(3)->get_data(1);
	assert(m_gfxdecode->gfx(3)->rowbytes() == 64);

	for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
	{
		const int dy = y - sy;
		for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
		{
			const int dx = x - sx;

			bool pri2 = false;
			int scroll = m_back_h_shift;

			switch (crossing)
			{
				case 0: pri2 = true; break; // outside tunnel (for reference; not usually handled in this loop)
				case 1: pri2 = (x >= scroll); break; // exiting tunnel
				case 2: break; // inside tunnel
				case 3: pri2 = (x < scroll); break; // entering tunnel
			}

			if (BIT(m_mode_set, 7))
			{
				// check coordinates against object data
				if ((dy >= -64 && dy < 0 && dx >= 64 && dx < 128 && objdata0[(-1 - dy) * 64 + dx - 64] != 0) ||
					(dy >= 0 && dy < 64 && dx >= 64 && dx < 128 && objdata0[dy * 64 + dx - 64] != 0) ||
					(dy >= -64 && dy < 0 && dx >= 0 && dx < 64 && objdata1[(-1 - dy) * 64 + dx] != 0) ||
					(dy >= 0 && dy < 64 && dx >= 0 && dx < 64 && objdata1[dy * 64 + dx] != 0))
				{
					pri2 = true;
					if (BIT(m_mode_set, 5) && priority.pix8(y, x) == 0) // least priority?
						bitmap.pix16(y, x) = color;
				}
			}

			if (!pri2)
				bitmap.pix16(y, x) |= 0x10;
		}
	}
}

void decocass_state::draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int sx, sy, x, y, color;

	color = 0;
	if (m_color_center_bot & 0x10)
		color |= 4;
	if (m_color_center_bot & 0x20)
		color |= 2;
	if (m_color_center_bot & 0x40)
		color |= 1;
	if (m_color_center_bot & 0x80)
		color = (color & 4) + ((color << 1) & 2) + ((color >> 1) & 1);

	sy = m_center_v_shift;
	sx = (m_center_h_shift_space >> 2) & 0x3c;

	for (y = 0; y < 4; y++)
		if ((sy + y) >= cliprect.min_y && (sy + y) <= cliprect.max_y)
		{
			if (((sy + y) & m_color_center_bot & 3) == (sy & m_color_center_bot & 3))
				for (x = 0; x < 256; x++)
					if (0 != (x & 16) || 0 != (m_center_h_shift_space & 1))
						bitmap.pix16(sy + y, (sx + x) & 255) = color;
		}
}

/********************************************
    memory handlers
 ********************************************/

WRITE8_MEMBER(decocass_state::decocass_paletteram_w )
{
	/*
	 * RGB output is inverted and A4 is inverted too
	 * (ME/ input on 1st paletteram, inverter -> ME/ on 2nd)
	 */
	m_paletteram[offset] = data;

	offset = (offset & 31) ^ 16;
	m_palette->set_indirect_color(offset, rgb_t(pal3bit(~data >> 0), pal3bit(~data >> 3), pal2bit(~data >> 6)));
}

WRITE8_MEMBER(decocass_state::decocass_charram_w )
{
	m_charram[offset] = data;
	/* dirty sprite */
	m_gfxdecode->gfx(1)->mark_dirty((offset >> 5) & 255);
	/* dirty char */
	m_gfxdecode->gfx(0)->mark_dirty((offset >> 3) & 1023);
}


WRITE8_MEMBER(decocass_state::decocass_fgvideoram_w )
{
	m_fgvideoram[offset] = data;
	m_fg_tilemap->mark_tile_dirty(offset);
}

WRITE8_MEMBER(decocass_state::decocass_colorram_w )
{
	m_colorram[offset] = data;
	m_fg_tilemap->mark_tile_dirty(offset);
}

void decocass_state::mark_bg_tile_dirty(offs_t offset )
{
	m_bg_tilemap_r->mark_tile_dirty(offset);
	m_bg_tilemap_l->mark_tile_dirty(offset);
}

WRITE8_MEMBER(decocass_state::decocass_tileram_w )
{
	m_tileram[offset] = data;
	/* dirty tile (64 bytes per tile) */
	m_gfxdecode->gfx(2)->mark_dirty((offset / 64) & 15);
	/* first 1KB of tile RAM is shared with tilemap RAM */
	if (offset < m_bgvideoram_size)
		mark_bg_tile_dirty(offset);
}

WRITE8_MEMBER(decocass_state::decocass_objectram_w )
{
	m_objectram[offset] = data;
	/* dirty the object */
	m_gfxdecode->gfx(3)->mark_dirty(0);
	m_gfxdecode->gfx(3)->mark_dirty(1);
}

WRITE8_MEMBER(decocass_state::decocass_bgvideoram_w )
{
	m_bgvideoram[offset] = data;
	mark_bg_tile_dirty(offset);
}

/* The watchdog is a 4bit counter counting down every frame */
WRITE8_MEMBER(decocass_state::decocass_watchdog_count_w )
{
	LOG(1,("decocass_watchdog_count_w: $%02x\n", data));
	m_watchdog_count = data & 0x0f;
}

WRITE8_MEMBER(decocass_state::decocass_watchdog_flip_w )
{
	LOG(1,("decocass_watchdog_flip_w: $%02x\n", data));
	m_watchdog_flip = data;
}

WRITE8_MEMBER(decocass_state::decocass_color_missiles_w )
{
	LOG(1,("decocass_color_missiles_w: $%02x\n", data));
	/* only bits D0-D2 and D4-D6 are connected to
	 * the color RAM demux:
	 * D0-D2 to the IC0 inputs
	 * D4-D6 to the IC1 inputs
	 */
	m_color_missiles = data & 0x77;
}

/*
 * D0 - bg paging
 * D1 - bg paging
 * D2 - ptn 1/2
 * D3 - BKG ena
 * D4 - center L on
 * D5 - cross on
 * D6 - tunnel
 * D7 - part h enable
 */
WRITE8_MEMBER(decocass_state::decocass_mode_set_w )
{
	if (data == m_mode_set)
		return;
	LOG(1,("decocass_mode_set_w: $%02x (%s%s%s%s%s%s%s%s)\n", data,
		(data & 0x01) ? "D0?" : "",
		(data & 0x02) ? " D1?" : "",
		(data & 0x04) ? " ptn1/2" : "",
		(data & 0x08) ? " bkg_ena" : "",
		(data & 0x10) ? " center_l_on" : "",
		(data & 0x20) ? " cross_on" : "",  /* skater enables this, why? */
		(data & 0x40) ? " tunnel" : "",
		(data & 0x80) ? " part_h_enable" : ""));

	m_mode_set = data;
}

WRITE8_MEMBER(decocass_state::decocass_color_center_bot_w )
{
	if (data == m_color_center_bot)
		return;
	LOG(1,("decocass_color_center_bot_w: $%02x (color:%d, center_bot:%d)\n", data, data & 3, data >> 4));
	/*
	 * D7   CL3/4 (swap 2+4)
	 * D6   CL1
	 * D5   CL2
	 * D4   CL4
	 * D3   nc
	 * D2   nc
	 * D1   CLD4
	 * D0   CLD3
	 */

	if ((m_color_center_bot ^ data) & 0x80)
	{
		m_bg_tilemap_r->mark_all_dirty();
		m_bg_tilemap_l->mark_all_dirty();
	}
	if ((m_color_center_bot ^ data) & 0x01)
		m_fg_tilemap->mark_all_dirty();
	m_color_center_bot = data;
}

WRITE8_MEMBER(decocass_state::decocass_back_h_shift_w )
{
	if (data == m_back_h_shift)
		return;
	LOG(1,("decocass_back_h_shift_w: $%02x\n", data));
	m_back_h_shift = data;
}

WRITE8_MEMBER(decocass_state::decocass_back_vl_shift_w )
{
	if (data == m_back_vl_shift)
		return;
	LOG(1,("decocass_back_vl_shift_w: $%02x\n", data));
	m_back_vl_shift = data;
}

WRITE8_MEMBER(decocass_state::decocass_back_vr_shift_w )
{
	if (data == m_back_vr_shift)
		return;
	LOG(1,("decocass_back_vr_shift_w: $%02x\n", data));
	m_back_vr_shift = data;
}

WRITE8_MEMBER(decocass_state::decocass_part_h_shift_w )
{
	if (data == m_part_h_shift )
		return;
	LOG(1,("decocass_part_h_shift_w: $%02x\n", data));
	m_part_h_shift = data;
}

WRITE8_MEMBER(decocass_state::decocass_part_v_shift_w )
{
	if (data == m_part_v_shift )
		return;
	LOG(1,("decocass_part_v_shift_w: $%02x\n", data));
	m_part_v_shift = data;
}

WRITE8_MEMBER(decocass_state::decocass_center_h_shift_space_w )
{
	if (data == m_center_h_shift_space)
		return;
	LOG(1,("decocass_center_h_shift_space_w: $%02x\n", data));
	m_center_h_shift_space = data;
}

WRITE8_MEMBER(decocass_state::decocass_center_v_shift_w )
{
	LOG(1,("decocass_center_v_shift_w: $%02x\n", data));
	m_center_v_shift = data;
}

/********************************************
    memory handlers
 ********************************************/

void decocass_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect, int color,
						int sprite_y_adjust, int sprite_y_adjust_flip_screen,
						uint8_t *sprite_ram, int interleave)
{
	/* Draw the sprites */
	int offs = 28 * interleave;
	for (int i = 0; i < 8; i++, offs -= 4 * interleave)
	{
		int sx, sy, flipx, flipy;

		if (!(sprite_ram[offs + 0] & 0x01))
			continue;

		sx = 240 - sprite_ram[offs + 3 * interleave];
		sy = 240 - sprite_ram[offs + 2 * interleave];

		flipx = sprite_ram[offs + 0] & 0x04;
		flipy = sprite_ram[offs + 0] & 0x02;

		if (flip_screen())
		{
			sx = 240 - sx;
			sy = 240 - sy + sprite_y_adjust_flip_screen;

			flipx = !flipx;
			flipy = !flipy;
		}

		sy -= sprite_y_adjust;

		m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect,
				sprite_ram[offs + interleave],
				color,
				flipx,flipy,
				sx,sy, priority, 1 << 1, 0);

		sy += (flip_screen() ? -256 : 256);

		// Wrap around
		m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect,
				sprite_ram[offs + interleave],
				color,
				flipx,flipy,
				sx,sy, priority, 1 << 1, 0);
	}
}


void decocass_state::draw_missiles(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect,
						int missile_y_adjust, int missile_y_adjust_flip_screen,
						uint8_t *missile_ram, int interleave)
{
	int i, offs, x;

	/* Draw the missiles (16 of them) seemingly with alternating colors
	 * from the E302 latch (color_missiles) */
	for (i = 0, offs = 0; i < 8; i++, offs += 4 * interleave)
	{
		int sx, sy;

		sy = 255 - missile_ram[offs + 0 * interleave];
		sx = 255 - missile_ram[offs + 2 * interleave];
		if (flip_screen())
		{
			sx = 240 - sx;
			sy = 240 - sy + missile_y_adjust_flip_screen;
		}
		sy -= missile_y_adjust;
		if (sy >= cliprect.min_y && sy <= cliprect.max_y)
			for (x = 0; x < 4; x++)
			{
				if (sx >= cliprect.min_x && sx <= cliprect.max_x)
				{
					bitmap.pix16(sy, sx) = (m_color_missiles & 7) | 8;
					priority.pix8(sy, sx) |= 1 << 2;
				}
				sx++;
			}

		sy = 255 - missile_ram[offs + 1 * interleave];
		sx = 255 - missile_ram[offs + 3 * interleave];
		if (flip_screen())
		{
			sx = 240 - sx;
			sy = 240 - sy + missile_y_adjust_flip_screen;
		}
		sy -= missile_y_adjust;
		if (sy >= cliprect.min_y && sy <= cliprect.max_y)
			for (x = 0; x < 4; x++)
			{
				if (sx >= cliprect.min_x && sx <= cliprect.max_x)
				{
					bitmap.pix16(sy, sx) = ((m_color_missiles >> 4) & 7) | 8;
					priority.pix8(sy, sx) |= 1 << 3;
				}
				sx++;
			}
	}
}

// we could still massively clean up the background tilemap handling, I have a feeling the
// code to ignore tiles with 0x80 set on the left tilemap etc. is just a convenient hack
// to stop garbage tiles appearing when scrolling due to the weird ram layout and clipping rules

// 0 is left edge, 1 is right edge
void decocass_state::draw_edge(bitmap_ind16 &bitmap, const rectangle &cliprect, int which, bool opaque)
{
	rectangle clip;
	bitmap_ind16* srcbitmap;

	int scrolly_l = m_back_vl_shift;
	int scrolly_r = 256 - m_back_vr_shift;

	// bit 0x04 of the mode select effectively selects between two banks of data
	if (0 == (m_mode_set & 0x04))
		scrolly_r += 256;
	else
		scrolly_l += 256;

	int scrollx = 256 - m_back_h_shift;
	int scrolly;

	if (which==0)
	{
		clip = m_bg_tilemap_l_clip;
		clip &= cliprect;
		scrolly = scrolly_l;
		srcbitmap = &m_bg_tilemap_l->pixmap();
	}
	else
	{
		clip = m_bg_tilemap_r_clip;
		clip &= cliprect;
		scrolly = scrolly_r;
		srcbitmap = &m_bg_tilemap_r->pixmap();
	}

	int y,x;

//  printf("m_mode_set %d\n", m_mode_set & 0x3);

	// technically our y drawing probably shouldn't wrap / mask, but simply draw the 128pixel high 'edge' at the requested position
	//  see note above this funciton
	for (y=clip.min_y; y<=clip.max_y;y++)
	{
		int srcline = (y + scrolly) & 0x1ff;
		uint16_t* src = &srcbitmap->pix16(srcline);
		uint16_t* dst = &bitmap.pix16(y);

		for (x=clip.min_x; x<=clip.max_x;x++)
		{
			int srccol = 0;

			// 2 bits control the x scroll mode, allowing it to wrap either half of the tilemap, or transition one way or the other between the two halves

			switch (m_mode_set & 3)
			{
				case 0x00: srccol = ((x + scrollx) & 0xff); break; // hwy normal case
				case 0x01: srccol = (x + scrollx + 0x100) & 0x1ff; break; // manhattan building top
				case 0x02: srccol = ((x + scrollx) & 0xff) + 0x100; break; // manhattan normal case
				case 0x03: srccol = (x + scrollx) & 0x1ff; break; // hwy, burnrub etc.
			}

			uint16_t pix = src[srccol];

			if ((pix & 0x3) || opaque)
				dst[x] = pix;
		}
	}

}


void decocass_state::video_start()
{
	m_bg_tilemap_l = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(decocass_state::get_bg_l_tile_info),this), tilemap_mapper_delegate(FUNC(decocass_state::bgvideoram_scan_cols),this), 16, 16, 32, 32);
	m_bg_tilemap_r = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(decocass_state::get_bg_r_tile_info),this), tilemap_mapper_delegate(FUNC(decocass_state::bgvideoram_scan_cols),this), 16, 16, 32, 32);
	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(decocass_state::get_fg_tile_info),this), tilemap_mapper_delegate(FUNC(decocass_state::fgvideoram_scan_cols),this), 8, 8, 32, 32);

	m_bg_tilemap_l->set_transparent_pen(0);
	m_bg_tilemap_r->set_transparent_pen(0);
	m_fg_tilemap->set_transparent_pen(0);

	m_bg_tilemap_l_clip = m_screen->visible_area();
	m_bg_tilemap_l_clip.max_y = 256 / 2 - 1;

	m_bg_tilemap_r_clip = m_screen->visible_area();
	m_bg_tilemap_r_clip.min_y = 256 / 2;

	/* background videoram bits D0-D3 are shared with the tileram */
	m_bgvideoram = m_tileram;
	m_bgvideoram_size = 0x0400; /* d000-d3ff */

	m_gfxdecode->gfx(0)->set_source(m_charram);
	m_gfxdecode->gfx(1)->set_source(m_charram);
	m_gfxdecode->gfx(2)->set_source(m_tileram);
	m_gfxdecode->gfx(3)->set_source(m_objectram);

	/* create an empty tile */
	memset(m_empty_tile, 0, sizeof(m_empty_tile));
}

uint32_t decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	/* THIS CODE SHOULD NOT BE IN SCREEN UPDATE !! */

	if (0xc0 != (ioport("IN2")->read() & 0xc0))  /* coin slots assert an NMI */
		m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);

	if (0 == (m_watchdog_flip & 0x04))
		m_watchdog->watchdog_reset();
	else if (m_watchdog_count-- > 0)
		m_watchdog->watchdog_reset();

	/* (end) THIS CODE SHOULD NOT BE IN SCREEN UPDATE !! */


#ifdef MAME_DEBUG
	{
		if (machine().input().code_pressed_once(KEYCODE_I))
			m_showmsg ^= 1;
		if (m_showmsg)
			popmessage("mode:$%02x cm:$%02x ccb:$%02x h:$%02x vl:$%02x vr:$%02x ph:$%02x pv:$%02x ch:$%02x cv:$%02x",
				m_mode_set,
				m_color_missiles,
				m_color_center_bot,
				m_back_h_shift,
				m_back_vl_shift,
				m_back_vr_shift,
				m_part_h_shift,
				m_part_v_shift,
				m_center_h_shift_space,
				m_center_v_shift);
	}
#endif

	bitmap_ind8 &priority = screen.priority();
	bitmap.fill(8, cliprect);
	priority.fill(0, cliprect);

	if (m_mode_set & 0x08)  /* bkg_ena on ? */
	{
		draw_edge(bitmap, cliprect, 0, true);
		draw_edge(bitmap, cliprect, 1, true);
	}

	if (m_mode_set & 0x20)
	{
		draw_center(bitmap, cliprect);
	}
	else
	{
		draw_center(bitmap, cliprect);
		if (m_mode_set & 0x08)  /* bkg_ena on ? */
		{
			draw_edge(bitmap, cliprect, 0, false);
			draw_edge(bitmap, cliprect, 1, false);
		}
	}

	// LS148 @ 2B (DSP-8 board) sets pen priority

	// priority 0: foreground - should be drawn last in some cases? what breaks with it here?
	// DSP-8 schematics indicate that this should be priority 4, but that breaks Tornado and Pro Tennis and Mission X (priority vs boats)
	m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	// priority 1: sprites
	draw_sprites(bitmap, priority, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20);

	// priority 2 & 3: missiles
	draw_missiles(bitmap, priority, cliprect, 1, 0, m_colorram, 0x20);

	// PRI1 & PRI2: special handling for 1bpp object and tunnel sections
	draw_special_priority(bitmap, priority, cliprect);

	return 0;
}