summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/namcona1.cpp
blob: b8fead106892b1bbb9914fdf34135df06462273c (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                                     

                                        
  
      
                                                                                                                             

                                                      


                                                                                                                      
                                                                         



                                                                                                 

  
                
                              
 
 
                                      
                            
                       
                                         
                           
 

                                                

                                                           
 
                           
         
                                                                        


            

                                                         


                        
                                                       
 
                                                                                   

 
                                                       
 
                                                                                   

 
                                                       
 
                                                                                   

 
                                                       
 
                                                                                   
 
 
                                                  

                                                                    
                                                     

                                
                                                                                                                 
                                                 


                                                           

                           
                                                                        


            

                                                         


                    

                                                                           
                                          
 
                                            

                             
                                                                           


                                  
                                                  
         
                  
 

                                                                           
                                                
 
                                                                     
           




                                                                                      


                                                                        
                                                         
 
                                                                                                      
 
 
                                            
 
                                              
                            
                                                            
                                        


            
                                       


         
 
                                       
 
                                       



                                   

                                                                                



                               
                                       

                      
                
 
                                        
 

                                       




                                   





                                                                  



                               


                                                 
                 

                                                                     

                 
                
 
                                  
 
                          



                                                                                                                                                                            
 
                      
                                                                                                                                                                       
 
                                  
 
                                                        
 

                                            
 








                                                                                                        


                                                                           
                                
                                      
                                       
                                      
                              



                                     
                            

                                
 

                                                        
 
                                                                                       

                                                                             
 

                                                                      

                                                        
         
                                                               

                                                                  







                                                 
                 


                                                                  

                    












                                                              





















                                                          






                                                                
                         



                                                                                                        


                                                              
                                 
                                                     
                                         


                                                                                    
                                                                               


                                                              


                                            

                                                                                 
                                                 
                                                                               
                                                         

                                                                                            
                                                                                                                                          
                                                                             
                                                                 
                                                                                                                 
                                                                                                                    
                                                                         
                                                                                                                                        


                                                                                                                        

                                                                                                                
                                                                         
                                                                 

                                                                    
                                                                                               
                                                                 
                                                         
                                                                      
                                                 


                                                      
                                 

                                              
                         
                 
         
                  
 
                                                                                                         

                  


                                             





                         
                                        



                                                                              
                                 



                                                                                                                                           
 
                                     




                                            










                                                                                   










                                                       

                                              










                                                              
                                                       
 
                                                  








                                                                    
 





                                        
                                                                                                                                          

              
                                
         
                                           

                                 



                                                                  


                       
                                                                                                                                     
 
                      
         
                                                      





                                                         

                                                    

                                                                  
                                                                   










                                                                                      
                                                                    

                                             
                                      


                                                       
                 



                                                           
 
                                   
                         
                                                           



                                                                                                 
                         

                                          
                         





                                                                                                   
                                                                         
                                                     
                                 
                                                                                                                                  

                                                               



                                                                                                                                                                            
                                                                                      


                                                                                              


                                    


                                                                                                        
                                 




                         







                                                              
 

                                           
 





                                           
                                                                                                              


                     
                                       





                                                                                                                                        
 
                                                    
 

                                             
                                                                                      
                                                         

                                                             
                                                                    

                                 
                                        



                                                                                    
                                                       
                         
                                               
                 
 

                                                                                                      
 
                                                                                  
 

                                                           
                                                         
                         


                                              
                                                                   


                                    
                                                                       
                                 
                                                     
                                 
                                                                                                   


                                            
 
                                                         


                           

  

                                  






                                                   

                                                   
                                                   



                                                                                        
 






                                                                 
// license:BSD-3-Clause
// copyright-holders:Phil Stroffolino
/*  Namco System NA1/2 Video Hardware */

/*
Notes:
- fa/fghtatck: Global screen window effect cut one line from top/bottom of screen, especially noticeable with credit display.
  It's a btanb according to a PCB video I've seen -AS.

TODO:
- background color currently follows what xday2 tries to set up, it's not sure if this is correct for everything else.
  Maybe there's a setting that actually switches between that and black pen?
- non-shadow pixels for sprites flagged to enable shadows have bad colors
- xday2: after choosing life (right) mode and set up date of birth, a joystick screen shows up.
  Bottom yellow frame doesn't show up correctly.
- xday2: at the end of life event, there's an unemulated screen shutdown event (might be posirq?)

*/

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


void namcona1_state::tilemap_get_info(
	tile_data &tileinfo,
	int tile_index,
	const uint16_t *tilemap_videoram,
	bool use_4bpp_gfx )
{
	int data = tilemap_videoram[tile_index];
	int tile = data&0xfff;
	int gfx = use_4bpp_gfx ? 1 : 0;
	int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;

	if( data & 0x8000 )
	{
		SET_TILE_INFO_MEMBER(gfx,tile,color,TILE_FORCE_LAYER0 );
	}
	else
	{
		SET_TILE_INFO_MEMBER(gfx,tile,color,0 );
		tileinfo.mask_data = &m_shaperam[tile*8];
	}
} /* tilemap_get_info */

TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info0)
{
	tilemap_get_info(tileinfo,tile_index,0*0x1000+m_videoram,m_vreg[0xbc/2]&1);
}

TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info1)
{
	tilemap_get_info(tileinfo,tile_index,1*0x1000+m_videoram,m_vreg[0xbc/2]&2);
}

TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info2)
{
	tilemap_get_info(tileinfo,tile_index,2*0x1000+m_videoram,m_vreg[0xbc/2]&4);
}

TILE_GET_INFO_MEMBER(namcona1_state::tilemap_get_info3)
{
	tilemap_get_info(tileinfo,tile_index,3*0x1000+m_videoram,m_vreg[0xbc/2]&8);
}

TILE_GET_INFO_MEMBER(namcona1_state::roz_get_info)
{
	/* each logical tile is constructed from 4*4 normal tiles */
	int use_4bpp_gfx = m_vreg[0xbc/2]&16; /* ? */
	int c = tile_index%0x40;
	int r = tile_index/0x40;
	int data = m_videoram[0x8000/2+(r/4)*0x40+c/4]&0xfbf; /* mask out bit 0x40 - patch for Emeraldia Japan */
	int tile = (data+(c%4)+(r%4)*0x40)&0xfff;
	int gfx = use_4bpp_gfx ? 1 : 0;
	int color = use_4bpp_gfx ? (data & 0x7000)>>12 : 0;

	if( data & 0x8000 )
	{
		SET_TILE_INFO_MEMBER(gfx,tile,color,TILE_FORCE_LAYER0 );
	}
	else
	{
		SET_TILE_INFO_MEMBER(gfx,tile,color,0 );
		tileinfo.mask_data = &m_shaperam[tile*8];
	}
} /* roz_get_info */

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

WRITE16_MEMBER(namcona1_state::videoram_w)
{
	COMBINE_DATA( &m_videoram[offset] );
	if( offset<0x8000/2 )
	{
		m_bg_tilemap[offset/0x1000]->mark_tile_dirty(offset&0xfff);
	}
	else if( offset<0xa000/2 )
	{
		m_bg_tilemap[4]->mark_all_dirty();
	}
} /* videoram_w */

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

void namcona1_state::UpdatePalette( int offset )
{
	uint16_t data = m_paletteram[offset]; /* -RRRRRGG GGGBBBBB */
	/**
	 * sprites can be configured to use an alternate interpretation of palette ram
	 * (used in-game in Emeraldia)
	 *
	 * RRRGGGBB RRRGGGBB
	 */
	int r = (((data&0x00e0)>>5)+((data&0xe000)>>13)*2)*0xff/(0x7*3);
	int g = (((data&0x001c)>>2)+((data&0x1c00)>>10)*2)*0xff/(0x7*3);
	int b = (((data&0x0003)>>0)+((data&0x0300)>>8)*2)*0xff/(0x3*3);
	m_palette->set_pen_color(offset+0x1000, r, g, b);

	m_palette->set_pen_color(offset, pal5bit(data >> 10), pal5bit(data >> 5), pal5bit(data >> 0));
}

WRITE16_MEMBER(namcona1_state::paletteram_w)
{
	COMBINE_DATA( &m_paletteram[offset] );
	if( m_vreg[0x8e/2] )
	{ /* graphics enabled; update palette immediately */
		UpdatePalette( offset );
	}
	else
	{
		m_palette_is_dirty = 1;
	}
}


READ16_MEMBER(namcona1_state::gfxram_r)
{
	uint16_t type = m_vreg[0x0c/2];
	if( type == 0x03 )
	{
		if( offset<0x4000 )
		{
			offset *= 2;
			return (m_shaperam[offset] << 8) | m_shaperam[offset+1];
		}
	}
	else if( type == 0x02 )
	{
		return m_cgram[offset];
	}
	return 0x0000;
} /* gfxram_r */

WRITE16_MEMBER(namcona1_state::gfxram_w)
{
	uint16_t type = m_vreg[0x0c/2];
	uint16_t old_word;

	if( type == 0x03 )
	{
		if( offset<0x4000 )
		{
			offset *= 2;
			if (ACCESSING_BITS_8_15)
				m_shaperam[offset] = data >> 8;
			if (ACCESSING_BITS_0_7)
				m_shaperam[offset+1] = data;
			m_gfxdecode->gfx(2)->mark_dirty(offset/8);
		}
	}
	else if( type == 0x02 )
	{
		old_word = m_cgram[offset];
		COMBINE_DATA( &m_cgram[offset] );
		if( m_cgram[offset]!=old_word )
		{
			m_gfxdecode->gfx(0)->mark_dirty(offset/0x20);
			m_gfxdecode->gfx(1)->mark_dirty(offset/0x20);
		}
	}
} /* gfxram_w */

void namcona1_state::video_start()
{
	// normal tilemaps
	m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info0),this), TILEMAP_SCAN_ROWS, 8,8,64,64 );
	m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info1),this), TILEMAP_SCAN_ROWS, 8,8,64,64 );
	m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info2),this), TILEMAP_SCAN_ROWS, 8,8,64,64 );
	m_bg_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::tilemap_get_info3),this), TILEMAP_SCAN_ROWS, 8,8,64,64 );

	// roz tilemap
	m_bg_tilemap[4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcona1_state::roz_get_info),this), TILEMAP_SCAN_ROWS, 8,8,64,64 );

	m_shaperam.resize(0x8000);

	m_gfxdecode->gfx(2)->set_source(&m_shaperam[0]);

	save_item(NAME(m_shaperam));
	save_item(NAME(m_palette_is_dirty));

	machine().save().register_postload(save_prepost_delegate(FUNC(namcona1_state::postload), this));
} /* video_start */

void namcona1_state::postload()
{
	for (int i = 0; i < 3; i++)
		m_gfxdecode->gfx(i)->mark_all_dirty();
}


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

void namcona1_state::pdraw_tile(
		screen_device &screen,
		bitmap_ind16 &dest_bmp,
		const rectangle &clip,
		uint32_t code,
		int color,
		int sx, int sy,
		int flipx, int flipy,
		int priority,
		int bShadow,
		int bOpaque,
		int gfx_region )
{
	gfx_element *gfx = m_gfxdecode->gfx(gfx_region);
	gfx_element *mask = m_gfxdecode->gfx(2);

	int pal_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
	const uint8_t *source_base = gfx->get_data((code % gfx->elements()));
	const uint8_t *mask_base = mask->get_data((code % mask->elements()));

	int sprite_screen_height = ((1<<16)*gfx->height()+0x8000)>>16;
	int sprite_screen_width  = ((1<<16)*gfx->width()+0x8000)>>16;

	if (sprite_screen_width && sprite_screen_height)
	{
		/* compute sprite increment per screen pixel */
		int dx = (gfx->width()<<16)/sprite_screen_width;
		int dy = (gfx->height()<<16)/sprite_screen_height;

		int ex = sx+sprite_screen_width;
		int ey = sy+sprite_screen_height;

		int x_index_base;
		int y_index;

		if( flipx )
		{
			x_index_base = (sprite_screen_width-1)*dx;
			dx = -dx;
		}
		else
		{
			x_index_base = 0;
		}

		if( flipy )
		{
			y_index = (sprite_screen_height-1)*dy;
			dy = -dy;
		}
		else
		{
			y_index = 0;
		}

		if( sx < clip.min_x)
		{ /* clip left */
			int pixels = clip.min_x-sx;
			sx += pixels;
			x_index_base += pixels*dx;
		}
		if( sy < clip.min_y )
		{ /* clip top */
			int pixels = clip.min_y-sy;
			sy += pixels;
			y_index += pixels*dy;
		}
		/* NS 980211 - fixed incorrect clipping */
		if( ex > clip.max_x+1 )
		{ /* clip right */
			int pixels = ex-clip.max_x-1;
			ex -= pixels;
		}
		if( ey > clip.max_y+1 )
		{ /* clip bottom */
			int pixels = ey-clip.max_y-1;
			ey -= pixels;
		}

		if( ex>sx )
		{ /* skip if inner loop doesn't draw anything */
			int y;

			for( y=sy; y<ey; y++ )
			{
				const uint8_t *source = source_base + (y_index>>16) * gfx->rowbytes();
				const uint8_t *mask_addr = mask_base + (y_index>>16) * mask->rowbytes();
				uint16_t *dest = &dest_bmp.pix16(y);
				uint8_t *pri = &screen.priority().pix8(y);

				int x, x_index = x_index_base;
				for( x=sx; x<ex; x++ )
				{
					if( bOpaque )
					{
						if (pri[x] <= priority)
						{
							int c = source[x_index>>16];
							dest[x] = pal_base + c;
						}

						pri[x] = 0xff;
					}
					else
					{
						/* sprite pixel is opaque */
						if( mask_addr[x_index>>16] != 0 )
						{
							if (pri[x] <= priority)
							{
								int c = source[x_index>>16];

								/* render a shadow only if the sprites color is $F (8bpp) or $FF (4bpp) */
								if( bShadow )
								{
									if( (gfx_region == 0 && color == 0x0f) ||
										(gfx_region == 1 && color == 0xff) )
									{
										pen_t *palette_shadow_table = m_palette->shadow_table();
										dest[x] = palette_shadow_table[dest[x]];
									}
									else
									{
										dest[x] = pal_base + c + 0x1000;
									}
								}
								else
								{
									dest[x] = pal_base + c;
								}
							}
							pri[x] = 0xff;
						}
					}

					x_index += dx;
				}

				y_index += dy;
			}
		}
	}
} /* pdraw_tile */

void namcona1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int which;
	const uint16_t *source = m_spriteram;
	uint16_t sprite_control;
	uint16_t ypos,tile,color,xpos;
	int priority;
	int width,height;
	int flipy,flipx;
	int row,col;
	int sx,sy;

	sprite_control = m_vreg[0x22/2];
	if( sprite_control&1 ) source += 0x400; /* alternate spriteram bank */

	for( which=0; which<0x100; which++ )
	{ /* max 256 sprites */
		int bpp4,palbase;
		ypos    = source[0];    /* FHHH---Y YYYYYYYY    flipy, height, ypos */
		tile    = source[1];    /* O???TTTT TTTTTTTT    opaque tile */
		color   = source[2];    /* FSWWOOOO CCCCBPPP    flipx, shadow, width, color offset for 4bpp, color, 4bbp - 8bpp mode, pri*/
		xpos    = source[3];    /* -------X XXXXXXXX    xpos */

		priority = color&0x7;
		width = ((color>>12)&0x3)+1;
		height = ((ypos>>12)&0x7)+1;
		flipy = ypos&0x8000;
		flipx = color&0x8000;

		if( color&8 )
		{
			palbase = ((color>>4)&0xf) * 0x10 + ((color & 0xf00) >> 8);
			bpp4 = 1;
		}
		else
		{
			palbase = (color>>4)&0xf;
			bpp4 = 0;
		}

		for( row=0; row<height; row++ )
		{
			sy = (ypos&0x1ff)-30+32;
			if( flipy )
			{
				sy += (height-1-row)*8;
			}
			else
			{
				sy += row*8;
			}
			sy = ((sy+8)&0x1ff)-8;

			for( col=0; col<width; col++ )
			{
				sx = (xpos&0x1ff)-10;
				if( flipx )
				{
					sx += (width-1-col)*8;
				}
				else
				{
					sx+=col*8;
				}
				sx = ((sx+16)&0x1ff)-8;

				pdraw_tile(screen,
					bitmap,
					cliprect,
					(tile & 0xfff) + row*64+col,
					palbase,
					sx,sy,flipx,flipy,
					priority,
					color & 0x4000, /* shadow */
					tile & 0x8000, /* opaque */
					bpp4 );

			} /* next col */
		} /* next row */
		source += 4;
	}
} /* draw_sprites */

void namcona1_state::draw_pixel_line( const rectangle &cliprect, uint16_t *pDest, uint8_t *pPri, uint16_t *pSource, const pen_t *paldata )
{
	int x;
	for( x=0; x<38*8; x+=2 )
	{
		uint16_t data = *pSource++;
		pPri[x+0] = 0xff;
		pPri[x+1] = 0xff;
		if(x >= cliprect.min_x && x <= cliprect.max_x)
			pDest[x+0] = paldata[data>>8];
		if(x+1 >= cliprect.min_x && x+1 <= cliprect.max_x)
			pDest[x+1] = paldata[data&0xff];
	} /* next x */
} /* draw_pixel_line */

void namcona1_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which, int primask )
{
	if(which == 4)
	{
		/* draw the roz tilemap all at once */
		int incxx = ((int16_t)m_vreg[0xc0/2])<<8;
		int incxy = ((int16_t)m_vreg[0xc2/2])<<8;
		int incyx = ((int16_t)m_vreg[0xc4/2])<<8;
		int incyy = ((int16_t)m_vreg[0xc6/2])<<8;
		int16_t xoffset = m_vreg[0xc8/2];
		int16_t yoffset = m_vreg[0xca/2];
		int dx = 46; /* horizontal adjust */
		int dy = -8; /* vertical adjust */
		uint32_t startx = (xoffset<<12)+incxx*dx+incyx*dy;
		uint32_t starty = (yoffset<<12)+incxy*dx+incyy*dy;
		m_bg_tilemap[4]->draw_roz(screen, bitmap, cliprect,
			startx, starty, incxx, incxy, incyx, incyy, 0, 0, primask, 0);
	}
	else
	{
		/* draw one scanline at a time */
		/*          scrollx lineselect
		*  tmap0   ffe000  ffe200
		*  tmap1   ffe400  ffe600
		*  tmap2   ffe800  ffea00
		*  tmap3   ffec00  ffee00
		*/
		const uint16_t *scroll = &m_scroll[which * 0x400/2];
		rectangle clip = cliprect;
		int xadjust = 0x3a - which*2;
		int scrollx = xadjust;
		int scrolly = 0;

		for( int line = 0; line < 256; line++ )
		{
			clip.min_y = line;
			clip.max_y = line;
			int xdata = scroll[line];
			int ydata = scroll[line + 0x200/2];

			if( xdata )
			{
				/* screenwise linescroll */
				if(xdata & 0x4000) // resets current xscroll value (knuckle head)
					scrollx = xadjust+xdata;
				else
					scrollx += xdata & 0x1ff;
			}

			if( ydata&0x4000 )
			{
				/* line select: dword offset from 0xff000 or tilemap source line */
				scrolly = (ydata - line)&0x1ff;
			}

			if (line >= cliprect.min_y && line <= cliprect.max_y)
			{
				// TODO: not convinced about this trigger
				if( xdata == 0xc001 )
				{
				   /* This is a simplification, but produces the correct behavior for the only game that uses this
				    * feature, Numan Athletics.
				    */
					// TODO: with this it breaks colors in VS Express event, likely pal bank is somewhere else in this mode, assuming it has one anyway?
					//const pen_t *paldata = &m_palette->pen(m_bg_tilemap[which]->palette_offset());
					const pen_t *paldata = &m_palette->pen(0);

					draw_pixel_line(cliprect, &bitmap.pix16(line),
								&screen.priority().pix8(line),
								m_videoram + ydata + 25,
								paldata );
				}
				else
				{
					m_bg_tilemap[which]->set_scrollx(0, scrollx );
					m_bg_tilemap[which]->set_scrolly(0, scrolly );
					m_bg_tilemap[which]->draw(screen, bitmap, clip, 0, primask, 0 );
				}
			}
		}
	}
} /* draw_background */

// CRTC safety checks
bool namcona1_state::screen_enabled(const rectangle &cliprect)
{
	if(cliprect.min_x < 0)
		return false;

	if(cliprect.max_x < 0)
		return false;

	if(cliprect.min_x > cliprect.max_x)
		return false;

	if(cliprect.min_y > cliprect.max_y)
		return false;

	return true;
}

uint32_t namcona1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int which;
	int priority;
	// CRTC visible area parameters
	// (used mostly by Numan Athletics for global screen window effects, cfr. start of events/title screen to demo mode transitions)
	rectangle display_rect;
	display_rect.min_x = m_vreg[0x80/2]-0x48;
	display_rect.max_x = m_vreg[0x82/2]-0x48-1;
	display_rect.min_y = std::max((int)m_vreg[0x84/2],   cliprect.min_y);
	display_rect.max_y = std::min((int)m_vreg[0x86/2]-1, cliprect.max_y);

	/* int flipscreen = m_vreg[0x98/2]; (TBA) */

	screen.priority().fill(0, cliprect );

	// guess for X-Day 2 (flames in attract), seems wrong for Emeraldia but unsure
//  bitmap.fill(0xff, cliprect ); /* background color? */
	bitmap.fill((m_vreg[0xba/2] & 0xf) * 256, cliprect );

	if( m_vreg[0x8e/2] && screen_enabled(display_rect) == true )
	{
		/* gfx enabled */
		if( m_palette_is_dirty )
		{
			/* palette updates are delayed when graphics are disabled */
			for( which=0; which<0x1000; which++ )
			{
				UpdatePalette( which );
			}
			m_palette_is_dirty = 0;
		}

		for( which=0; which < 4; which++ )
			m_bg_tilemap[which]->set_palette_offset((m_vreg[0xb0/2 + which] & 0xf) * 256);

		m_bg_tilemap[4]->set_palette_offset((m_vreg[0xba/2] & 0xf) * 256);

		for( priority = 0; priority<8; priority++ )
		{
			for( which=4; which>=0; which-- )
			{
				int pri;
				if( which==4 )
				{
					pri = m_vreg[0xa0/2+5]&0x7;
				}
				else
				{
					pri = m_vreg[0xa0/2+which]&0x7;
				}
				if( pri == priority )
				{
					draw_background(screen,bitmap,display_rect,which,priority);
				}
			} /* next tilemap */
		} /* next priority level */

		draw_sprites(screen,bitmap,display_rect);
	} /* gfx enabled */
	return 0;
}

/*
roz bad in emeraldaj - blit param?

$efff20: sprite control: 0x3a,0x3e,0x3f
            bit 0x01 selects spriteram bank

               0    2    4    6    8    a    c    e
$efff00:    src0 src1 src2 dst0 dst1 dst2 BANK [src
$efff10:    src] [dst dst] #BYT BLIT eINT 001f 0001
$efff20:    003f 003f IACK ---- ---- ---- ---- ----
...
$efff80:    0050 0170 0020 0100 0170 POS? 0000 GFXE
$efff90:    0000 0001 0002 0003 FLIP ---- ---- ----
$efffa0:    PRI  PRI  PRI  PRI  ???? PRI  00c0 ----     priority (0..7)
$efffb0:    CLR  CLR  CLR  CLR  0001 CLR  BPP  ----     color (0..f), bpp flag per layer
$efffc0:    RZXX RZXY RZYX RZYY RZX0 RZY0 0044 ----     ROZ


Emeralda:   0048 0177 0020 0100 0000 00f0 0000 0001     in-game
            0050 0170 0020 0100 0000 00f0 0000 0001     self test

NumanAth:   0050 0170 0020 0100 0170 00d8 0000 0001     in-game


*/