summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/seibuspi.c
blob: 35654476592fcd27f17191c0b72c3e78c72b1a3f (plain) (tree)
1
2
3
4
5
6
7
8
                
                              
 


                                  
                                                                               
                                   



                                   
                                                                               
                                             
 



                                                        

              


                                                        


         
                                                             
 
                                                                      
                                                       
         

                                                                  

         
                                                       
         

                                                                 

         
                                                       
         

                                                                  





                                    
                                                                               
                                     




                                     
                                                                               



                                                                                            



                                      
                                                                               
                                            

                      
                                                                     
 
                                                     


                                                     




                                                                                                    




                                                   
                                                                                                     



                                                     




                                                                                                    




                                                   
                                                                                                      



                                                     




                                                                                                   




                                                  
                                                                                                      



                                                      




                                                                                                    







                                                     




                                                                                                    





                                                     




                                                                                                    





                                                     




                                                                                                   





                                                      




                                                                                                    








                                        
                                                                               
                                            

                      
                                                                           
                 




                                                                                                                                                                                                               






                                     
                                                                               
                                            
         
                                                                                                                                         




                                     
                                                                               
                                                   



                                      
                                                                               
                                                    

 
                                                                                                                                                               
 

                                                                             
                        













































































                                                                 
                                             



                                
                                                        
                                                                 





                                             
                                             
                         

                                                                                      

                                          
                                                                                             


                                    
                                                                






                                   
                                      



                                                           
                                      




                                                           
                                                                                                             
 
                                                                      






                                   
                                                
 
                                          

                       


                                                                         




                                            
                                                                   


                                          
                                                          

                                       
                                                                  

                                       
                                                            
 



                                                                        













                                                      
                                                                                                                                                                        


                                                                           
                                                                                                                                                                                      









                                           
                                                                      
                                  
                                                                                                                       








                                          
                                                                      
                                  
                                                                                          



                                       
                                        






                                         
                                                                      
                                  
                                                                                                                      




                                       
                                        






                                              
                                                                      
                                  
                                                                                                                       


                                       
                                                
 
                                        

                               
                                                          





                                             
                                                                      


                          



                                                                                                                 
 


                                                             
 


                                                                                 
 

                                            
 



                                                                 
                                                              

                  





                                                                                           

                    


                                                                                        
                     

                                                                                        
                     

                                                                      
 
                                                        


                                      
                                                         


                                           
                                                         


            
                                                         



                      
                                                                    
 
                                                                      
              

                                                                






                                                           
                                                    
 
                                                                      

                                                                





                                         
                                                                                                                                                               
 
                                                                      

                  
                  
                 
                                          

                               





                                                  







                                                              
                                                
                                                                       
                                                                        




                                                                                                            
                                                                        

                                          
                                                                                          


                                    
                                                               








                                 
                    
 
                                                                                
                                                               



                                                                       





                                       
                                         
                                                 
 

                                                                                                                                                                                             
 
                                                             

                                                                             
                                           
                                                                     
 

                                                                                                                                                                                           

                                                                             
                                          
                                                                     
 
                                                             
 

                                                                                                                                                                                             
 
                                                             
 
                                                                                                 

                 


                       
                                                                      

              

                                                                                 
 


                                            




                                                                 
                                                              

 
                         

                                         



                                                             

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


READ32_HANDLER( spi_layer_bank_r )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	return state->m_layer_bank;
}

WRITE32_HANDLER( spi_layer_bank_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	COMBINE_DATA( &state->m_layer_bank );

	if (state->m_layer_bank & 0x80000000) {
		state->m_fore_layer_offset = 0x1000 / 4;
		state->m_mid_layer_offset = 0x2000 / 4;
		state->m_text_layer_offset = 0x3000 / 4;
	}
	else {
		state->m_fore_layer_offset = 0x800 / 4;
		state->m_mid_layer_offset = 0x1000 / 4;
		state->m_text_layer_offset = 0x1800 / 4;
	}
}

void rf2_set_layer_banks(running_machine &machine, int banks)
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	if (state->m_rf2_layer_bank[0] != BIT(banks,0))
	{
		state->m_rf2_layer_bank[0] = BIT(banks,0);
		tilemap_mark_all_tiles_dirty(state->m_back_layer);
	}

	if (state->m_rf2_layer_bank[1] != BIT(banks,1))
	{
		state->m_rf2_layer_bank[1] = BIT(banks,1);
		tilemap_mark_all_tiles_dirty(state->m_mid_layer);
	}

	if (state->m_rf2_layer_bank[2] != BIT(banks,2))
	{
		state->m_rf2_layer_bank[2] = BIT(banks,2);
		tilemap_mark_all_tiles_dirty(state->m_fore_layer);
	}
}

#ifdef UNUSED_FUNCTION
READ32_HANDLER( spi_layer_enable_r )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	return state->m_layer_enable;
}
#endif

WRITE32_HANDLER( spi_layer_enable_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	COMBINE_DATA( &state->m_layer_enable );
	tilemap_set_enable(state->m_back_layer, (state->m_layer_enable & 0x1) ^ 0x1);
	tilemap_set_enable(state->m_mid_layer, ((state->m_layer_enable >> 1) & 0x1) ^ 0x1);
	tilemap_set_enable(state->m_fore_layer, ((state->m_layer_enable >> 2) & 0x1) ^ 0x1);
}

WRITE32_HANDLER( tilemap_dma_start_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	if (state->m_video_dma_address != 0)
	{
		int i;
		int index = (state->m_video_dma_address / 4) - 0x200;

		if (state->m_layer_bank & 0x80000000)
		{
			/* back layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i] != tile) {
					state->m_tilemap_ram[i] = tile;
					tilemap_mark_tile_dirty( state->m_back_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_back_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* back layer row scroll */
			memcpy(&state->m_tilemap_ram[0x800/4], &state->m_spimainram[index], 0x800/4);
			index += 0x800/4;

			/* fore layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_fore_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_fore_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_fore_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_fore_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* fore layer row scroll */
			memcpy(&state->m_tilemap_ram[0x1800/4], &state->m_spimainram[index], 0x800/4);
			index += 0x800/4;

			/* mid layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_mid_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_mid_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_mid_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_mid_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* mid layer row scroll */
			memcpy(&state->m_tilemap_ram[0x1800/4], &state->m_spimainram[index], 0x800/4);
			index += 0x800/4;

			/* text layer */
			for (i=0; i < 0x1000/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_text_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_text_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_text_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_text_layer, (i * 2) + 1 );
				}
				index++;
			}
		}
		else
		{
			/* back layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i] != tile) {
					state->m_tilemap_ram[i] = tile;
					tilemap_mark_tile_dirty( state->m_back_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_back_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* fore layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_fore_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_fore_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_fore_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_fore_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* mid layer */
			for (i=0; i < 0x800/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_mid_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_mid_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_mid_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_mid_layer, (i * 2) + 1 );
				}
				index++;
			}

			/* text layer */
			for (i=0; i < 0x1000/4; i++) {
				UINT32 tile = state->m_spimainram[index];
				if (state->m_tilemap_ram[i+state->m_text_layer_offset] != tile) {
					state->m_tilemap_ram[i+state->m_text_layer_offset] = tile;
					tilemap_mark_tile_dirty( state->m_text_layer, (i * 2) );
					tilemap_mark_tile_dirty( state->m_text_layer, (i * 2) + 1 );
				}
				index++;
			}
		}
	}
}

WRITE32_HANDLER( palette_dma_start_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	if (state->m_video_dma_address != 0)
	{
		int i;
		for (i=0; i < ((state->m_video_dma_length+1) * 2) / 4; i++)
		{
			UINT32 color = state->m_spimainram[(state->m_video_dma_address / 4) + i - 0x200];
			if (state->m_palette_ram[i] != color) {
				state->m_palette_ram[i] = color;
				palette_set_color_rgb( space->machine(), (i * 2), pal5bit(state->m_palette_ram[i] >> 0), pal5bit(state->m_palette_ram[i] >> 5), pal5bit(state->m_palette_ram[i] >> 10) );
				palette_set_color_rgb( space->machine(), (i * 2) + 1, pal5bit(state->m_palette_ram[i] >> 16), pal5bit(state->m_palette_ram[i] >> 21), pal5bit(state->m_palette_ram[i] >> 26) );
			}
		}
	}
}

WRITE32_HANDLER( sprite_dma_start_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	if (state->m_video_dma_address != 0)
	{
		memcpy( state->m_sprite_ram, &state->m_spimainram[(state->m_video_dma_address / 4) - 0x200], state->m_sprite_dma_length);
	}
}

WRITE32_HANDLER( video_dma_length_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	COMBINE_DATA( &state->m_video_dma_length );
}

WRITE32_HANDLER( video_dma_address_w )
{
	seibuspi_state *state = space->machine().driver_data<seibuspi_state>();
	COMBINE_DATA( &state->m_video_dma_address );
}

static void drawgfx_blend(bitmap_t *bitmap, const rectangle *cliprect, const gfx_element *gfx, UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy)
{
	seibuspi_state *state = gfx->machine().driver_data<seibuspi_state>();
	const pen_t *pens = &gfx->machine().pens[gfx->color_base];
	const UINT8 *dp;
	int i, j;
	int x1, x2;
	int y1, y2;
	int px, py;
	int xd = 1, yd = 1;

	int width = gfx->width;
	int height = gfx->height;

	x1 = sx;
	x2 = sx + width - 1;
	y1 = sy;
	y2 = sy + height - 1;

	if (x1 > cliprect->max_x || x2 < cliprect->min_x)
	{
		return;
	}
	if (y1 > cliprect->max_y || y2 < cliprect->min_y)
	{
		return;
	}

	px = 0;
	py = 0;

	if (flipx)
	{
		xd = -xd;
		px = width - 1;
	}
	if (flipy)
	{
		yd = -yd;
		py = height - 1;
	}

	// clip x
	if (x1 < cliprect->min_x)
	{
		if (flipx)
		{
			px = width - (cliprect->min_x - x1) - 1;
		}
		else
		{
			px = (cliprect->min_x - x1);
		}
		x1 = cliprect->min_x;
	}
	if (x2 > cliprect->max_x)
	{
		x2 = cliprect->max_x;
	}

	// clip y
	if (y1 < cliprect->min_y)
	{
		if (flipy)
		{
			py = height - (cliprect->min_y - y1) - 1;
		}
		else
		{
			py = (cliprect->min_y - y1);
		}
		y1 = cliprect->min_y;
	}
	if (y2 > cliprect->max_y)
	{
		y2 = cliprect->max_y;
	}

	if (gfx->total_elements <= 0x10000)
	{
		code &= 0xffff;
	}

	dp = gfx_element_get_data(gfx, code);

	// draw
	for (j=y1; j <= y2; j++)
	{
		UINT32 *p = BITMAP_ADDR32(bitmap, j, 0);
		UINT8 trans_pen = (1 << state->m_sprite_bpp) - 1;
		int dp_i = (py * width) + px;
		py += yd;

		for (i=x1; i <= x2; i++)
		{
			UINT8 pen = dp[dp_i];
			if (pen != trans_pen)
			{
				int global_pen = pen + (color << state->m_sprite_bpp);
				UINT8 alpha = state->m_alpha_table[global_pen];
				if (alpha)
				{
					p[i] = alpha_blend_r32(p[i], pens[global_pen], 0x7f);
				}
				else
				{
					p[i] = pens[global_pen];
				}
			}
			dp_i += xd;
		}
	}
}

static const int sprite_xtable[2][8] =
{
	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
	{ 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 }
};
static const int sprite_ytable[2][8] =
{
	{ 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 },
	{ 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 }
};

static void draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int pri_mask)
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	INT16 xpos, ypos;
	int tile_num, color;
	int width, height;
	int flip_x = 0, flip_y = 0;
	int a;
	int priority;
	int x,y, x1, y1;
	const gfx_element *gfx = machine.gfx[2];

	if( state->m_layer_enable & 0x10 )
		return;

	for( a = (state->m_sprite_dma_length / 4) - 2; a >= 0; a -= 2 ) {
		tile_num = (state->m_sprite_ram[a + 0] >> 16) & 0xffff;
		if( state->m_sprite_ram[a + 1] & 0x1000 )
			tile_num |= 0x10000;

		if( !tile_num )
			continue;

		priority = (state->m_sprite_ram[a + 0] >> 6) & 0x3;
		if( pri_mask != priority )
			continue;

		xpos = state->m_sprite_ram[a + 1] & 0x3ff;
		if( xpos & 0x200 )
			xpos |= 0xfc00;
		ypos = (state->m_sprite_ram[a + 1] >> 16) & 0x1ff;
		if( ypos & 0x100 )
			ypos |= 0xfe00;
		color = (state->m_sprite_ram[a + 0] & 0x3f);

		width = ((state->m_sprite_ram[a + 0] >> 8) & 0x7) + 1;
		height = ((state->m_sprite_ram[a + 0] >> 12) & 0x7) + 1;
		flip_x = (state->m_sprite_ram[a + 0] >> 11) & 0x1;
		flip_y = (state->m_sprite_ram[a + 0] >> 15) & 0x1;
		x1 = 0;
		y1 = 0;

		if( flip_x ) {
			x1 = 8 - width;
			width = width + x1;
		}
		if( flip_y ) {
			y1 = 8 - height;
			height = height + y1;
		}

		for( x=x1; x < width; x++ ) {
			for( y=y1; y < height; y++ ) {
				drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y]);

				/* xpos seems to wrap-around to 0 at 512 */
				if( (xpos + (16 * x) + 16) >= 512 ) {
					drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos - 512 + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y]);
				}

				tile_num++;
			}
		}
	}
}

static TILE_GET_INFO( get_text_tile_info )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int offs = tile_index / 2;
	int tile = (state->m_tilemap_ram[offs + state->m_text_layer_offset] >> ((tile_index & 0x1) ? 16 : 0)) & 0xffff;
	int color = (tile >> 12) & 0xf;

	tile &= 0xfff;

	SET_TILE_INFO(0, tile, color, 0);
}

static TILE_GET_INFO( get_back_tile_info )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int offs = tile_index / 2;
	int tile = (state->m_tilemap_ram[offs] >> ((tile_index & 0x1) ? 16 : 0)) & 0xffff;
	int color = (tile >> 13) & 0x7;

	tile &= 0x1fff;

	if( state->m_rf2_layer_bank[0] )
		tile |= 0x4000;

	SET_TILE_INFO(1, tile, color, 0);
}

static TILE_GET_INFO( get_mid_tile_info )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int offs = tile_index / 2;
	int tile = (state->m_tilemap_ram[offs + state->m_mid_layer_offset] >> ((tile_index & 0x1) ? 16 : 0)) & 0xffff;
	int color = (tile >> 13) & 0x7;

	tile &= 0x1fff;
	tile |= 0x2000;

	if( state->m_rf2_layer_bank[1] )
		tile |= 0x4000;

	SET_TILE_INFO(1, tile, color + 16, 0);
}

static TILE_GET_INFO( get_fore_tile_info )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int offs = tile_index / 2;
	int tile = (state->m_tilemap_ram[offs + state->m_fore_layer_offset] >> ((tile_index & 0x1) ? 16 : 0)) & 0xffff;
	int color = (tile >> 13) & 0x7;

	tile &= 0x1fff;
	tile |= state->m_bg_fore_layer_position;

	if( state->m_rf2_layer_bank[2] )
		tile |= 0x4000;

	tile |= ((state->m_layer_bank >> 27) & 0x1) << 13;

	SET_TILE_INFO(1, tile, color + 8, 0);
}

VIDEO_START( spi )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int i;
	int region_length;

	state->m_text_layer	= tilemap_create( machine, get_text_tile_info, tilemap_scan_rows,  8,8,64,32 );
	state->m_back_layer	= tilemap_create( machine, get_back_tile_info, tilemap_scan_cols,  16,16,32,32 );
	state->m_mid_layer	= tilemap_create( machine, get_mid_tile_info, tilemap_scan_cols,  16,16,32,32 );
	state->m_fore_layer	= tilemap_create( machine, get_fore_tile_info, tilemap_scan_cols,  16,16,32,32 );

	tilemap_set_transparent_pen(state->m_text_layer, 31);
	tilemap_set_transparent_pen(state->m_mid_layer, 63);
	tilemap_set_transparent_pen(state->m_fore_layer, 63);

	state->m_tilemap_ram = auto_alloc_array_clear(machine, UINT32, 0x4000/4);
	state->m_palette_ram = auto_alloc_array_clear(machine, UINT32, 0x3000/4);
	state->m_sprite_ram = auto_alloc_array_clear(machine, UINT32, 0x1000/4);

	state->m_sprite_bpp = 6;
	state->m_sprite_dma_length = 0x1000;

	for (i=0; i < 6144; i++) {
		palette_set_color(machine, i, MAKE_RGB(0, 0, 0));
	}

	memset(state->m_alpha_table, 0, 6144 * sizeof(UINT8));

	// sprites
	//for (i = 1792; i < 1808; i++) { state->m_alpha_table[i] = 1; } // breaks rdft
	for (i = 1840; i < 1856; i++) { state->m_alpha_table[i] = 1; }
	for (i = 1920; i < 1952; i++) { state->m_alpha_table[i] = 1; }
	//for (i = 1984; i < 2048; i++) { state->m_alpha_table[i] = 1; } // breaks batlball
	//for (i = 3840; i < 3904; i++) { state->m_alpha_table[i] = 1; } // breaks rdft
	for (i = 4032; i < 4096; i++) { state->m_alpha_table[i] = 1; }

	// mid layer
	for (i = 4960; i < 4992; i++) { state->m_alpha_table[i] = 1; }	// breaks ejanhs
	for (i = 5040; i < 5056; i++) { state->m_alpha_table[i] = 1; }	// breaks ejanhs
	for (i = 5104; i < 5120; i++) { state->m_alpha_table[i] = 1; }
	// fore layer
	for (i = 5552; i < 5568; i++) { state->m_alpha_table[i] = 1; }	// breaks ejanhs
	for (i = 5616; i < 5632; i++) { state->m_alpha_table[i] = 1; }	// breaks ejanhs
	// text layer
	for (i = 6000; i < 6016; i++) { state->m_alpha_table[i] = 1; }
	for (i = 6128; i < 6144; i++) { state->m_alpha_table[i] = 1; }

	region_length = machine.region("gfx2")->bytes();

	if (region_length <= 0x300000)
	{
		state->m_bg_fore_layer_position = 0x2000;
	}
	else if (region_length <= 0x600000)
	{
		state->m_bg_fore_layer_position = 0x4000;
	}
	else
	{
		state->m_bg_fore_layer_position = 0x8000;
	}
}

#ifdef UNUSED_FUNCTION
static void set_rowscroll(tilemap_t *layer, int scroll, INT16* rows)
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int i;
	int x = state->m_spi_scrollram[scroll] & 0xffff;
	int y = (state->m_spi_scrollram[scroll] >> 16) & 0xffff;
	tilemap_set_scroll_rows(layer, 512);
	for( i=0; i < 512; i++ ) {
		tilemap_set_scrollx(layer, i, x + rows[i]);
	}
	tilemap_set_scrolly(layer, 0, y);
}

static void set_scroll(tilemap_t *layer, int scroll)
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int x = state->m_spi_scrollram[scroll] & 0xffff;
	int y = (state->m_spi_scrollram[scroll] >> 16) & 0xffff;
	tilemap_set_scrollx(layer, 0, x);
	tilemap_set_scrolly(layer, 0, y);
}
#endif


static void combine_tilemap(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, tilemap_t *tile, int x, int y, int opaque, INT16 *rowscroll)
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int i,j;
	UINT16 *s;
	UINT32 *d;
	UINT8 *t;
	UINT32 xscroll_mask, yscroll_mask;
	bitmap_t *pen_bitmap;
	bitmap_t *flags_bitmap;

	pen_bitmap = tilemap_get_pixmap(tile);
	flags_bitmap = tilemap_get_flagsmap(tile);
	xscroll_mask = pen_bitmap->width - 1;
	yscroll_mask = pen_bitmap->height - 1;

	for (j=cliprect->min_y; j <= cliprect->max_y; j++)
	{
		int rx = x;
		if (rowscroll)
		{
			rx += rowscroll[(j+y) & yscroll_mask];
		}

		d = BITMAP_ADDR32(bitmap, j, 0);
		s = BITMAP_ADDR16(pen_bitmap, (j+y) & yscroll_mask, 0);
		t = BITMAP_ADDR8(flags_bitmap, (j+y) & yscroll_mask, 0);
		for (i=cliprect->min_x+rx; i <= cliprect->max_x+rx; i++)
		{
			if (opaque || (t[i & xscroll_mask] & (TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1)))
			{
				UINT16 pen = s[i & xscroll_mask];
				UINT8 alpha = state->m_alpha_table[pen];
				if (alpha)
				{
					*d = alpha_blend_r32(*d, machine.pens[pen], 0x7f);
				}
				else
				{
					*d = machine.pens[pen];
				}
			}
			++d;
		}
	}
}



SCREEN_UPDATE( spi )
{
	seibuspi_state *state = screen->machine().driver_data<seibuspi_state>();
	INT16 *back_rowscroll, *mid_rowscroll, *fore_rowscroll;
	if( state->m_layer_bank & 0x80000000 ) {
		back_rowscroll	= (INT16*)&state->m_tilemap_ram[0x200];
		mid_rowscroll	= (INT16*)&state->m_tilemap_ram[0x600];
		fore_rowscroll	= (INT16*)&state->m_tilemap_ram[0xa00];
	} else {
		back_rowscroll	= NULL;
		mid_rowscroll	= NULL;
		fore_rowscroll	= NULL;
	}

	if( state->m_layer_enable & 0x1 )
		bitmap_fill(bitmap, cliprect, 0);

	if (!(state->m_layer_enable & 0x1))
		combine_tilemap(screen->machine(), bitmap, cliprect, state->m_back_layer, state->m_spi_scrollram[0] & 0xffff, (state->m_spi_scrollram[0] >> 16) & 0xffff, 1, back_rowscroll);

	draw_sprites(screen->machine(), bitmap, cliprect, 0);

	// if fore layer is enabled, draw priority 1 sprites behind mid layer
	if (!(state->m_layer_enable & 0x4))
		draw_sprites(screen->machine(), bitmap, cliprect, 1);

	if (!(state->m_layer_enable & 0x2))
		combine_tilemap(screen->machine(), bitmap, cliprect, state->m_mid_layer, state->m_spi_scrollram[1] & 0xffff, (state->m_spi_scrollram[1] >> 16) & 0xffff, 0, mid_rowscroll);

	// if fore layer is disabled, draw priority 1 sprites above mid layer
	if ((state->m_layer_enable & 0x4))
		draw_sprites(screen->machine(), bitmap, cliprect, 1);

	draw_sprites(screen->machine(), bitmap, cliprect, 2);

	if (!(state->m_layer_enable & 0x4))
		combine_tilemap(screen->machine(), bitmap, cliprect, state->m_fore_layer, state->m_spi_scrollram[2] & 0xffff, (state->m_spi_scrollram[2] >> 16) & 0xffff, 0, fore_rowscroll);

	draw_sprites(screen->machine(), bitmap, cliprect, 3);

	combine_tilemap(screen->machine(), bitmap, cliprect, state->m_text_layer, 0, 0, 0, NULL);
	return 0;
}

VIDEO_START( sys386f2 )
{
	seibuspi_state *state = machine.driver_data<seibuspi_state>();
	int i;

	state->m_palette_ram = auto_alloc_array_clear(machine, UINT32, 0x4000/4);
	state->m_sprite_ram = auto_alloc_array_clear(machine, UINT32, 0x2000/4);

	state->m_sprite_bpp = 8;
	state->m_sprite_dma_length = 0x2000;
	state->m_layer_enable = 0;

	for (i=0; i < 8192; i++) {
		palette_set_color(machine, i, MAKE_RGB(0, 0, 0));
	}

	memset(state->m_alpha_table, 0, 8192 * sizeof(UINT8));
}

SCREEN_UPDATE( sys386f2 )
{
	bitmap_fill(bitmap, cliprect, 0);
	draw_sprites(screen->machine(), bitmap, cliprect, 0);
	draw_sprites(screen->machine(), bitmap, cliprect, 1);
	draw_sprites(screen->machine(), bitmap, cliprect, 2);
	draw_sprites(screen->machine(), bitmap, cliprect, 3);
	return 0;
}