summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/k001604.cpp
blob: c949edd67f656d4b4acd039884800ad56d01f752 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

                                  











                                                                             

                                             
 
                                                                                             
 
                                                                                                               
                                                        
                                                      


                            
                            
                             

                            
                      
 


                                                   

                                                   
 
                                   
 


                                                    




















                                                                                                                                         
 

                          


                                                                 





                                            

                                                                                                                                                                                                                                             
 
                                                                                                                                                                                                                                                               


            

                                                                                                                                                                                                                                             
 
                                                                                                                                                                                                                                                               




                                               

                                                                                                                                                         
 


                                                     
 

 




                                                   
 


                                              





                                                                              


                                                                                                                          
                                                             
 
                                                
                                                    

 
                                                             
 
                                                
                                                    

 
                                                             
 
                                                
                                                         

 
                                                             
 
                                                
                                                         

 
                                                         
 
                                                
                                                    

 
                                                         
 
                                                
                                                          

 
                                                         
 
                                              








                                       
                                                    

 
                                                         
 
                                              

                                       
                                                               





                                    
                                            
 
                                                             


 
                                                                                       
 

                                 
                                                

                       
                                            
 





                                                             
 

                                                             







                                                
                                                     






                                   
                                                                  


                                                           
                                                
 

                                                          
            
                                                          







                                                                    
                                                                                              









                                           

                                     
 
                                                     



















                                                                                                                                   
                                                                                                               
 








                                                             
 

















                                                                  
 



                                           
 
 






























                                                                                                                                    

 
                                       
 
                                  

 
                                       
 
                      
                      
 
                                                           

                
                                                    
            
                                               


                                                       
                                

 
                                      
 

                       

                                                                                 

         
                             

 
                                        
 
                     
                                                
 
                         









                                     
                         


                           
                                                                


                                 
                                                                


                    
                                                             





                           
                                                                


                    
                                                                

                 
                                                     


         
                                        
 
                      
                      
 
                                                         

                
                                                    
            
                                               


                                                       
                                              
 

                                       

 
                                       
 
                                           











                                                                                                       
                                                                                                                        

         
// license:BSD-3-Clause
// copyright-holders:David Haywood

#include "emu.h"
#include "k001604.h"


/***************************************************************************/
/*                                                                         */
/*                                  001604                                 */
/*                                                                         */
/***************************************************************************/


#define K001604_NUM_TILES_LAYER0        16384
#define K001604_NUM_TILES_LAYER1        4096

DEFINE_DEVICE_TYPE(K001604, k001604_device, "k001604_device", "K001604 2D tilemaps + 2x ROZ")

k001604_device::k001604_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, K001604, tag, owner, clock),
	device_gfx_interface(mconfig, *this, nullptr),
	m_layer_size(0),
	m_roz_size(0),
	m_txt_mem_offset(0),
	m_roz_mem_offset(0),
	m_layer_roz(nullptr),
	m_tile_ram(nullptr),
	m_char_ram(nullptr),
	m_reg(nullptr)
{
}

//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void k001604_device::device_start()
{
	if (!palette().device().started())
		throw device_missing_dependencies();

	static const gfx_layout k001604_char_layout_layer_8x8 =
	{
		8, 8,
		K001604_NUM_TILES_LAYER0,
		8,
		{ 8,9,10,11,12,13,14,15 },
		{ 1*16, 0*16, 3*16, 2*16, 5*16, 4*16, 7*16, 6*16 },
		{ 0*128, 1*128, 2*128, 3*128, 4*128, 5*128, 6*128, 7*128 },
		8*128
	};

	static const gfx_layout k001604_char_layout_layer_16x16 =
	{
		16, 16,
		K001604_NUM_TILES_LAYER1,
		8,
		{ 8,9,10,11,12,13,14,15 },
		{ 1*16, 0*16, 3*16, 2*16, 5*16, 4*16, 7*16, 6*16, 9*16, 8*16, 11*16, 10*16, 13*16, 12*16, 15*16, 14*16 },
		{ 0*256, 1*256, 2*256, 3*256, 4*256, 5*256, 6*256, 7*256, 8*256, 9*256, 10*256, 11*256, 12*256, 13*256, 14*256, 15*256 },
		16*256
	};

	int roz_tile_size;

	m_char_ram = make_unique_clear<uint32_t[]>(0x200000 / 4);
	m_tile_ram = make_unique_clear<uint32_t[]>(0x20000 / 4);
	m_reg = make_unique_clear<uint32_t[]>(0x400 / 4);

	/* create tilemaps */
	roz_tile_size = m_roz_size ? 16 : 8;

	if (m_layer_size)
	{
		m_layer_8x8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_0_size1)), 8, 8, 64, 64);
		m_layer_8x8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_1_size1)), 8, 8, 64, 64);

		m_layer_roz = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_roz)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_roz_256)), roz_tile_size, roz_tile_size, 128, 64);
	}
	else
	{
		m_layer_8x8[0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_0_size0)), 8, 8, 64, 64);
		m_layer_8x8[1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_8x8)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_8x8_1_size0)), 8, 8, 64, 64);

		m_layer_roz = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(k001604_device::tile_info_layer_roz)), tilemap_mapper_delegate(*this, FUNC(k001604_device::scan_layer_roz_128)), roz_tile_size, roz_tile_size, 128, 64);
	}

	m_layer_8x8[0]->set_transparent_pen(0);
	m_layer_8x8[1]->set_transparent_pen(0);

	set_gfx(0, std::make_unique<gfx_element>(&palette(), k001604_char_layout_layer_8x8, (uint8_t*)&m_char_ram[0], 0, palette().entries() / 16, 0));
	set_gfx(1, std::make_unique<gfx_element>(&palette(), k001604_char_layout_layer_16x16, (uint8_t*)&m_char_ram[0], 0, palette().entries() / 16, 0));

	save_pointer(NAME(m_reg), 0x400 / 4);
	save_pointer(NAME(m_char_ram), 0x200000 / 4);
	save_pointer(NAME(m_tile_ram), 0x20000 / 4);

}

//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void k001604_device::device_reset()
{
	memset(m_char_ram.get(), 0, 0x200000);
	memset(m_tile_ram.get(), 0, 0x10000);
	memset(m_reg.get(), 0, 0x400);
}

/*****************************************************************************
    DEVICE HANDLERS
*****************************************************************************/

/* FIXME: The TILEMAP_MAPPER below depends on parameters passed by the device interface (being game dependent).
we might simplify the code, by passing the whole TILEMAP_MAPPER as a callback in the interface, but is it really worth? */

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_0_size0)
{
	/* logical (col,row) -> memory offset */
	return (row * 128) + col + m_txt_mem_offset;
}

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_0_size1)
{
	/* logical (col,row) -> memory offset */
	return (row * 256) + col + m_txt_mem_offset;
}

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_1_size0)
{
	/* logical (col,row) -> memory offset */
	return (row * 128) + col + 64 + m_txt_mem_offset;
}

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_8x8_1_size1)
{
	/* logical (col,row) -> memory offset */
	return (row * 256) + col + 64 + m_txt_mem_offset;
}

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_roz_128)
{
	/* logical (col,row) -> memory offset */
	return (row * 128) + col + m_roz_mem_offset;
}

TILEMAP_MAPPER_MEMBER(k001604_device::scan_layer_roz_256)
{
	/* logical (col,row) -> memory offset */
	return (row * 256) + col + 128 + m_roz_mem_offset;
}

TILE_GET_INFO_MEMBER(k001604_device::tile_info_layer_8x8)
{
	uint32_t val = m_tile_ram[tile_index];
	int color = (val >> 17) & 0x1f;
	int tile = (val & 0x7fff);
	int flags = 0;

	if (val & 0x400000)
		flags |= TILE_FLIPX;
	if (val & 0x800000)
		flags |= TILE_FLIPY;

	SET_TILE_INFO_MEMBER(0, tile, color, flags);
}

TILE_GET_INFO_MEMBER(k001604_device::tile_info_layer_roz)
{
	uint32_t val = m_tile_ram[tile_index];
	int flags = 0;
	int color = (val >> 17) & 0x1f;
	int tile = m_roz_size ? (val & 0x7ff) : (val & 0x1fff);

	if (val & 0x400000)
		flags |= TILE_FLIPX;
	if (val & 0x800000)
		flags |= TILE_FLIPY;

	tile += m_roz_size ? 0x800 : 0x2000;

	SET_TILE_INFO_MEMBER(m_roz_size, tile, color, flags);
}


void k001604_device::draw_back_layer( bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
	bitmap.fill(0, cliprect);

	if ((m_reg[0x60 / 4] & 0x40000000) == 0)
		return;

	int tile_size = m_roz_size ? 16 : 8;

	int32_t x  = (int16_t)((m_reg[0x08] >> 16) & 0xffff);
	int32_t y  = (int16_t)((m_reg[0x08] >>  0) & 0xffff);
	int32_t xx = (int16_t)((m_reg[0x09] >>  0) & 0xffff);
	int32_t xy = (int16_t)((m_reg[0x09] >> 16) & 0xffff);
	int32_t yx = (int16_t)((m_reg[0x0a] >>  0) & 0xffff);
	int32_t yy = (int16_t)((m_reg[0x0a] >> 16) & 0xffff);

	int pivotx = (int16_t)((m_reg[0x00] >> 16) & 0xffff);
	int pivoty = (int16_t)((m_reg[0x00] >>  0) & 0xffff);

	int startx  = ((x - pivotx) * 256) * 32;
	int starty  = ((y - pivoty) * 256) * 32;
	int incxx = (xx) * 32;
	int incxy = (-xy) * 32;
	int incyx = (-yx) * 32;
	int incyy = (yy) * 32;

	bitmap_ind16& pixmap = m_layer_roz->pixmap();

	// extract start/end points
	int sx = cliprect.min_x;
	int sy = cliprect.min_y;
	int ex = cliprect.max_x;
	int ey = cliprect.max_y;

	const rgb_t *clut = palette().palette()->entry_list_raw();

	int window_x, window_y, window_xmask, window_ymask;

	int layer_size = (m_reg[0x1b] >> 9) & 3;

	if (m_roz_size)
		window_x = ((m_reg[0x1b] >> 1) & 3) * 512;
	else
		window_x = ((m_reg[0x1b] >> 1) & 1) * 512;

	window_y = 0;

	switch (layer_size)
	{
		case 0: window_xmask = (128 * tile_size) - 1; break;
		case 2: window_xmask = (64 * tile_size) - 1; break;
		case 3: window_xmask = (32 * tile_size) - 1; break;
		default: fatalerror("k001604_draw_back_layer(): layer_size %d\n", layer_size);
	}

	window_ymask = pixmap.height() - 1;


	// loop over rows
	while (sy <= ey)
	{
		// initialize X counters
		int x = sx;
		uint32_t cx = startx;
		uint32_t cy = starty;

		uint32_t *dest = &bitmap.pix(sy, sx);

		// loop over columns
		while (x <= ex)
		{
			*dest = clut[pixmap.pix16(((cy >> 16) & window_ymask) + window_y, ((cx >> 16) & window_xmask) + window_x)];

			// advance in X
			cx += incxx;
			cy += incxy;
			x++;
			dest++;
		}

		// advance in Y
		startx += incyx;
		starty += incyy;
		sy++;
	}
}

void k001604_device::draw_front_layer( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
	int32_t x = (int16_t)((m_reg[0x00] >> 16) & 0xffff);
	int32_t y = (int16_t)((m_reg[0x00] >> 0) & 0xffff);
	int32_t yy = (int16_t)((m_reg[0x01] >> 0) & 0xffff);
	int32_t xy = (int16_t)((m_reg[0x01] >> 16) & 0xffff);
	int32_t yx = (int16_t)((m_reg[0x02] >> 0) & 0xffff);
	int32_t xx = (int16_t)((m_reg[0x02] >> 16) & 0xffff);

	int pivotx = (int16_t)(0xfec0);
	int pivoty = (int16_t)(0xff28);

	int startx = ((x - pivotx) * 256) * 32;
	int starty = ((y - pivoty) * 256) * 32;
	int incxx = (xx) * 32;
	int incxy = (-xy) * 32;
	int incyx = (-yx) * 32;
	int incyy = (yy) * 32;

	bitmap_ind16& pixmap = m_layer_8x8[0]->pixmap();

	// extract start/end points
	int sx = cliprect.min_x;
	int sy = cliprect.min_y;
	int ex = cliprect.max_x;
	int ey = cliprect.max_y;

	const rgb_t *clut = palette().palette()->entry_list_raw();

	int window_x, window_y, window_xmask, window_ymask;

	window_x = 0;
	window_y = 0;
	window_xmask = pixmap.width() - 1;
	window_ymask = pixmap.height() - 1;


	// loop over rows
	while (sy <= ey)
	{
		// initialize X counters
		int x = sx;
		uint32_t cx = startx;
		uint32_t cy = starty;

		uint32_t *dest = &bitmap.pix(sy, sx);

		// loop over columns
		while (x <= ex)
		{
			uint16_t pix = pixmap.pix16(((cy >> 16) & window_ymask) + window_y, ((cx >> 16) & window_xmask) + window_x);
			if ((pix & 0xff) != 0)
			{
				*dest = clut[pix];
			}

			// advance in X
			cx += incxx;
			cy += incxy;
			x++;
			dest++;
		}

		// advance in Y
		startx += incyx;
		starty += incyy;
		sy++;
	}
}

READ32_MEMBER( k001604_device::tile_r )
{
	return m_tile_ram[offset];
}

READ32_MEMBER( k001604_device::char_r )
{
	int set, bank;
	uint32_t addr;

	set = (m_reg[0x60 / 4] & 0x1000000) ? 0x100000 : 0;

	if (set)
		bank = (m_reg[0x60 / 4] >> 8) & 0x3;
	else
		bank = (m_reg[0x60 / 4] & 0x3);

	addr = offset + ((set + (bank * 0x40000)) / 4);

	return m_char_ram[addr];
}

READ32_MEMBER( k001604_device::reg_r )
{
	switch (offset)
	{
		case 0x54/4:    return machine().rand() << 16;
		case 0x5c/4:    return machine().rand() << 16 | machine().rand();
	}

	return m_reg[offset];
}

WRITE32_MEMBER( k001604_device::tile_w )
{
	int x/*, y*/;
	COMBINE_DATA(m_tile_ram.get() + offset);

	if (m_layer_size)
	{
		x = offset & 0xff;
		/*y = offset / 256;*/
	}
	else
	{
		x = offset & 0x7f;
		/*y = offset / 128;*/
	}

	if (m_layer_size)
	{
		if (x < 64)
		{
			m_layer_8x8[0]->mark_tile_dirty(offset);
		}
		else if (x < 128)
		{
			m_layer_8x8[1]->mark_tile_dirty(offset);
		}
		else
		{
			m_layer_roz->mark_tile_dirty(offset);
		}
	}
	else
	{
		if (x < 64)
		{
			m_layer_8x8[0]->mark_tile_dirty(offset);
		}
		else
		{
			m_layer_8x8[1]->mark_tile_dirty(offset);
		}

		m_layer_roz->mark_tile_dirty(offset);
	}
}

WRITE32_MEMBER( k001604_device::char_w )
{
	int set, bank;
	uint32_t addr;

	set = (m_reg[0x60/4] & 0x1000000) ? 0x100000 : 0;

	if (set)
		bank = (m_reg[0x60 / 4] >> 8) & 0x3;
	else
		bank = (m_reg[0x60 / 4] & 0x3);

	addr = offset + ((set + (bank * 0x40000)) / 4);

	COMBINE_DATA(m_char_ram.get() + addr);

	gfx(0)->mark_dirty(addr / 32);
	gfx(1)->mark_dirty(addr / 128);
}

WRITE32_MEMBER( k001604_device::reg_w )
{
	COMBINE_DATA(m_reg.get() + offset);

	switch (offset)
	{
		case 0x8:
		case 0x9:
		case 0xa:
			//printf("K001604_reg_w %02X, %08X, %08X\n", offset, data, mem_mask);
			break;
	}

	if (offset != 0x08 && offset != 0x09 && offset != 0x0a /*&& offset != 0x17 && offset != 0x18*/)
	{
		//printf("K001604_reg_w (%d), %02X, %08X, %08X at %s\n", chip, offset, data, mem_mask, m_maincpu->pc());
	}
}