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







                                                                               
                
                              

 



                                                                               
                                             
 
                                     

 
                                              


                    
                                     




                                  


                                                      
 
                                                                                    

 
                                             
 
                                     

 
                                              


                    
                                     




                                      


                                                          
 
                                                                                       

 
                                             
 
                                     

 
                                              


                    
                                     




                                  


                                                      
 
                                                                                    

 
                                        
 
                         

 
                                    
 
                              

 
                                     
 
                                                                     





                                                                               
                                        


                       





                                                                                                    
                                                                               
                                                  
                                              
                                                                          


                                                                                      

                                                                        
                                              
                                  


         
                                                 


                       





                                                                                                


         
                                                 
 
              

 
                                                 
 
                                             
 
                    

 
                                             
 
                                               


                         






                                          




                     
                                                          
         
                           
         
                                                               
         
                           










                                 
                                                                  
                 





                                                               
                 
                                                                       
                 





                                                               
                 
                                                                       
                 





                                                               
                 
                                                                       
                 





                                                  

                 
                          

         

                                                          
                                                    
 
                      

 
                                        
 
                         

 
                                        

                                              
                                                                            
 
                      

 
                                       
 
                                                
                                 
 
                                                



                                                 
                                                   






                                                                               
                                       
 
                 

                               
 

                                        
 
                                                     
 
                                                              
 
                                          
         
                                           
                 



                                                                            


                 

                                        


 
                                                
 
                                                                 
                                         

 
                                                
 
                                                                 
                                                                  

 
                                                                                             
 


                           
                                          

                      
                                                                                   
         

 
                              
 
                                                 
                                      






                               
                                      
                            
 
                                  
 

                                                   
 
                                  
         
                                               



                          
                                        


                           
                                  
         
                                               



                          
                                        


                           
                                            
                                                               




                                                                             
                                                     



                                                                    
                                                        



                                               
                                                 
                                                                             
                         
                                                                         







                                                                                        


                                                  
                                           


                                               
                                                             



                                               
                                                             


                                        
                                          






                                             
                                                  











                                                             

                                                                            
 
                                                                 



                                                   

                                                                                  


                                                   

                                                                                  

                                 
                                                              

                                          
                                                  



                                                             

                                                                                          


                                                           

                                                                                          




                                                              



                                                                                  


                                 
                                                


                 
                                  
                                                                                   





                                                                               
                                             
 

                                        
 
                                                     
                                                       


                                                                  
                                                                         
                           
                             
 
                                                             
         






                                                          


                                             
 
                            

 
                                  
 

                                        
 
                                                     

                                                       





                                                                            
                           
                             
 
                            
                                                        

















                                               


                                                                                
                                          
 





                                                                                                        





                                                                               
                                                                                                              


                 
                             
         

                                             
 
                                     

                                                   
                                                    
 
                                   

                                                           
                                                            

         
                       
         
                            

                                                                        
 
                                   
                 

                                                                                                              

                    
                                                                                                  

            
                                  
 

                 
// license:BSD-3-Clause
// copyright-holders:Takahiro Nogi
/******************************************************************************

    Video Hardware for Nichibutsu Mahjong series.

    Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 1999/11/05 -

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

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


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


******************************************************************************/
READ8_MEMBER(nbmj8891_state::palette_type1_r)
{
	return m_palette_ptr[offset];
}

WRITE8_MEMBER(nbmj8891_state::palette_type1_w)
{
	int r, g, b;

	m_palette_ptr[offset] = data;

	if (!(offset & 1)) return;

	offset &= 0x1fe;

	r = ((m_palette_ptr[offset + 0] & 0x0f) >> 0);
	g = ((m_palette_ptr[offset + 1] & 0xf0) >> 4);
	b = ((m_palette_ptr[offset + 1] & 0x0f) >> 0);

	m_palette->set_pen_color((offset >> 1), pal4bit(r), pal4bit(g), pal4bit(b));
}

READ8_MEMBER(nbmj8891_state::palette_type2_r)
{
	return m_palette_ptr[offset];
}

WRITE8_MEMBER(nbmj8891_state::palette_type2_w)
{
	int r, g, b;

	m_palette_ptr[offset] = data;

	if (!(offset & 0x100)) return;

	offset &= 0x0ff;

	r = ((m_palette_ptr[offset + 0x000] & 0x0f) >> 0);
	g = ((m_palette_ptr[offset + 0x000] & 0xf0) >> 4);
	b = ((m_palette_ptr[offset + 0x100] & 0x0f) >> 0);

	m_palette->set_pen_color((offset & 0x0ff), pal4bit(r), pal4bit(g), pal4bit(b));
}

READ8_MEMBER(nbmj8891_state::palette_type3_r)
{
	return m_palette_ptr[offset];
}

WRITE8_MEMBER(nbmj8891_state::palette_type3_w)
{
	int r, g, b;

	m_palette_ptr[offset] = data;

	if (!(offset & 1)) return;

	offset &= 0x1fe;

	r = ((m_palette_ptr[offset + 1] & 0x0f) >> 0);
	g = ((m_palette_ptr[offset + 0] & 0xf0) >> 4);
	b = ((m_palette_ptr[offset + 0] & 0x0f) >> 0);

	m_palette->set_pen_color((offset >> 1), pal4bit(r), pal4bit(g), pal4bit(b));
}

WRITE8_MEMBER(nbmj8891_state::clutsel_w)
{
	m_clutsel = data;
}

READ8_MEMBER(nbmj8891_state::clut_r)
{
	return m_clut[offset];
}

WRITE8_MEMBER(nbmj8891_state::clut_w)
{
	m_clut[((m_clutsel & 0x7f) * 0x10) + (offset & 0x0f)] = data;
}

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


******************************************************************************/
WRITE8_MEMBER(nbmj8891_state::blitter_w)
{
	switch (offset)
	{
		case 0x00:  m_blitter_src_addr = (m_blitter_src_addr & 0xff00) | data; break;
		case 0x01:  m_blitter_src_addr = (m_blitter_src_addr & 0x00ff) | (data << 8); break;
		case 0x02:  m_blitter_destx = data; break;
		case 0x03:  m_blitter_desty = data; break;
		case 0x04:  m_blitter_sizex = data; break;
		case 0x05:  m_blitter_sizey = data;
					/* writing here also starts the blit */
					gfxdraw();
					break;
		case 0x06:  m_blitter_direction_x = (data & 0x01) ? 1 : 0;
					m_blitter_direction_y = (data & 0x02) ? 1 : 0;
					m_flipscreen = (data & 0x04) ? 1 : 0;
					m_dispflag = (data & 0x08) ? 0 : 1;
					if (m_gfxdraw_mode) vramflip(1);
					vramflip(0);
					break;
		case 0x07:  break;
	}
}

WRITE8_MEMBER(nbmj8891_state::taiwanmb_blitter_w)
{
	switch (offset)
	{
		case 0: m_blitter_src_addr = (m_blitter_src_addr & 0xff00) | data; break;
		case 1: m_blitter_src_addr = (m_blitter_src_addr & 0x00ff) | (data << 8); break;
		case 2: m_blitter_destx = data; break;
		case 3: m_blitter_desty = data; break;
		case 4: m_blitter_sizex = (data - 1) & 0xff; break;
		case 5: m_blitter_sizey = (data - 1) & 0xff; break;
	}
}

WRITE8_MEMBER(nbmj8891_state::taiwanmb_gfxdraw_w)
{
//  gfxdraw();
}

WRITE8_MEMBER(nbmj8891_state::taiwanmb_gfxflag_w)
{
	m_flipscreen = (data & 0x04) ? 1 : 0;

	vramflip(0);
}

WRITE8_MEMBER(nbmj8891_state::taiwanmb_mcu_w)
{
	m_param_old[m_param_cnt & 0x0f] = data;

	if (data == 0x00)
	{
		m_blitter_direction_x = 0;
		m_blitter_direction_y = 0;
		m_blitter_destx = 0;
		m_blitter_desty = 0;
		m_blitter_sizex = 0;
		m_blitter_sizey = 0;
		m_dispflag = 0;
	}

/*
    if (data == 0x02)
    {
        if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x18)
        {
            m_dispflag = 1;
        }
        else if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x1a)
        {
            m_dispflag = 0;
        }
    }
*/

	if (data == 0x04)
	{
		// CLUT Transfer?
	}

	if (data == 0x12)
	{
		if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x08)
		{
			m_blitter_direction_x = 1;
			m_blitter_direction_y = 0;
			m_blitter_destx += m_blitter_sizex + 1;
			m_blitter_desty += 0;
			m_blitter_sizex ^= 0xff;
			m_blitter_sizey ^= 0x00;
		}
		else if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x0a)
		{
			m_blitter_direction_x = 0;
			m_blitter_direction_y = 1;
			m_blitter_destx += 0;
			m_blitter_desty += m_blitter_sizey + 1;
			m_blitter_sizex ^= 0x00;
			m_blitter_sizey ^= 0xff;
		}
		else if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x0c)
		{
			m_blitter_direction_x = 1;
			m_blitter_direction_y = 1;
			m_blitter_destx += m_blitter_sizex + 1;
			m_blitter_desty += m_blitter_sizey + 1;
			m_blitter_sizex ^= 0xff;
			m_blitter_sizey ^= 0xff;
		}
		else if (m_param_old[(m_param_cnt - 1) & 0x0f] == 0x0e)
		{
			m_blitter_direction_x = 0;
			m_blitter_direction_y = 0;
			m_blitter_destx += 0;
			m_blitter_desty += 0;
			m_blitter_sizex ^= 0x00;
			m_blitter_sizey ^= 0x00;
		}

		gfxdraw();
	}

//  m_blitter_direction_x = 0;                // for debug
//  m_blitter_direction_y = 0;                // for debug
	m_dispflag = 1;                 // for debug

	m_param_cnt++;
}

WRITE8_MEMBER(nbmj8891_state::scrolly_w)
{
	m_scrolly = data;
}

WRITE8_MEMBER(nbmj8891_state::vramsel_w)
{
	/* protection - not sure about this */
	m_nb1413m3->m_sndromrgntag = (data & 0x20) ? "protection" : "voice";

	m_vram = data;
}

WRITE8_MEMBER(nbmj8891_state::romsel_w)
{
	int gfxlen = memregion("gfx1")->bytes();
	m_gfxrom = (data & 0x0f);

	if ((0x20000 * m_gfxrom) > (gfxlen - 1))
	{
#ifdef MAME_DEBUG
		popmessage("GFXROM BANK OVER!!");
#endif
		m_gfxrom &= (gfxlen / 0x20000 - 1);
	}
}

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


******************************************************************************/
void nbmj8891_state::vramflip(int vram)
{
	int x, y;
	uint8_t color1, color2;
	uint8_t *vidram;

	int width = m_screen->width();
	int height = m_screen->height();

	if (m_flipscreen == m_flipscreen_old) return;

	vidram = vram ? m_videoram1.get() : m_videoram0.get();

	for (y = 0; y < (height / 2); y++)
	{
		for (x = 0; x < width; x++)
		{
			color1 = vidram[(y * width) + x];
			color2 = vidram[((y ^ 0xff) * width) + (x ^ 0x1ff)];
			vidram[(y * width) + x] = color2;
			vidram[((y ^ 0xff) * width) + (x ^ 0x1ff)] = color1;
		}
	}

	m_flipscreen_old = m_flipscreen;
	m_screen_refresh = 1;
}


void nbmj8891_state::update_pixel0(int x, int y)
{
	uint8_t color = m_videoram0[(y * m_screen->width()) + x];
	m_tmpbitmap0.pix16(y, x) = color;
}

void nbmj8891_state::update_pixel1(int x, int y)
{
	uint8_t color = m_videoram1[(y * m_screen->width()) + x];
	m_tmpbitmap1.pix16(y, x) = (color == 0x7f) ? 0xff : color;
}

void nbmj8891_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
	case TIMER_BLITTER:
		m_nb1413m3->busyflag_w(1);
		break;
	default:
		throw emu_fatalerror("Unknown id in nbmj8891_state::device_timer");
	}
}

void nbmj8891_state::gfxdraw()
{
	uint8_t *GFX = memregion("gfx1")->base();
	int width = m_screen->width();

	int x, y;
	int dx1, dx2, dy1, dy2;
	int startx, starty;
	int sizex, sizey;
	int skipx, skipy;
	int ctrx, ctry;
	uint8_t color, color1, color2;
	int gfxaddr, gfxlen;

	m_nb1413m3->m_busyctr = 0;

	startx = m_blitter_destx + m_blitter_sizex;
	starty = m_blitter_desty + m_blitter_sizey;

	if (m_blitter_direction_x)
	{
		sizex = m_blitter_sizex ^ 0xff;
		skipx = 1;
	}
	else
	{
		sizex = m_blitter_sizex;
		skipx = -1;
	}

	if (m_blitter_direction_y)
	{
		sizey = m_blitter_sizey ^ 0xff;
		skipy = 1;
	}
	else
	{
		sizey = m_blitter_sizey;
		skipy = -1;
	}

	gfxlen = memregion("gfx1")->bytes();
	gfxaddr = (m_gfxrom << 17) + (m_blitter_src_addr << 1);

	for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
	{
		for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
		{
			if ((gfxaddr > (gfxlen - 1)))
			{
#ifdef MAME_DEBUG
				popmessage("GFXROM ADDRESS OVER!!");
#endif
				gfxaddr &= (gfxlen - 1);
			}

			color = GFX[gfxaddr++];

			// for hanamomo font type
			if (m_nb1413m3->m_nb1413m3_type == NB1413M3_HANAMOMO)
			{
				if ((ioport("FONTTYPE")->read()) == 0x00)
				{
					if ((gfxaddr >= 0x20000) && (gfxaddr < 0x28000))
					{
						color |= ((color & 0x0f) << 4);
					}
				}
			}

			dx1 = (2 * x + 0) & 0x1ff;
			dx2 = (2 * x + 1) & 0x1ff;

			if (m_gfxdraw_mode)
			{
				// 2 layer type
				dy1 = y & 0xff;
				dy2 = (y + m_scrolly) & 0xff;
			}
			else
			{
				// 1 layer type
				dy1 = (y + m_scrolly) & 0xff;
				dy2 = 0;
			}

			if (!m_flipscreen)
			{
				dx1 ^= 0x1ff;
				dx2 ^= 0x1ff;
				dy1 ^= 0xff;
				dy2 ^= 0xff;
			}

			if (m_blitter_direction_x)
			{
				// flip
				color1 = (color & 0x0f) >> 0;
				color2 = (color & 0xf0) >> 4;
			}
			else
			{
				// normal
				color1 = (color & 0xf0) >> 4;
				color2 = (color & 0x0f) >> 0;
			}

			color1 = m_clut[((m_clutsel & 0x7f) << 4) + color1];
			color2 = m_clut[((m_clutsel & 0x7f) << 4) + color2];

			if ((!m_gfxdraw_mode) || (m_vram & 0x01))
			{
				// layer 1
				if (color1 != 0xff)
				{
					m_videoram0[(dy1 * width) + dx1] = color1;
					update_pixel0(dx1, dy1);
				}
				if (color2 != 0xff)
				{
					m_videoram0[(dy1 * width) + dx2] = color2;
					update_pixel0(dx2, dy1);
				}
			}
			if (m_gfxdraw_mode && (m_vram & 0x02))
			{
				// layer 2
				if (m_vram & 0x08)
				{
					// transparent enable
					if (color1 != 0xff)
					{
						m_videoram1[(dy2 * width) + dx1] = color1;
						update_pixel1(dx1, dy2);
					}
					if (color2 != 0xff)
					{
						m_videoram1[(dy2 * width) + dx2] = color2;
						update_pixel1(dx2, dy2);
					}
				}
				else
				{
					// transparent disable
					m_videoram1[(dy2 * width) + dx1] = color1;
					update_pixel1(dx1, dy2);
					m_videoram1[(dy2 * width) + dx2] = color2;
					update_pixel1(dx2, dy2);
				}
			}

			m_nb1413m3->m_busyctr++;
		}
	}

	m_nb1413m3->busyflag_w(0);
	m_blitter_timer->adjust(attotime::from_hz(400000) * m_nb1413m3->m_busyctr);
}

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


******************************************************************************/
VIDEO_START_MEMBER( nbmj8891_state, _1layer )
{
	int width = m_screen->width();
	int height = m_screen->height();

	m_blitter_timer = timer_alloc(TIMER_BLITTER);
	m_screen->register_screen_bitmap(m_tmpbitmap0);
	m_videoram0 = std::make_unique<uint8_t[]>(width * height);
	m_palette_ptr = std::make_unique<uint8_t[]>(0x200);
	m_clut = std::make_unique<uint8_t[]>(0x800);
	memset(m_videoram0.get(), 0xff, (width * height * sizeof(char)));
	m_gfxdraw_mode = 0;
	m_screen_refresh = 1;

	if (m_nb1413m3->m_nb1413m3_type == NB1413M3_TAIWANMB)
	{
		if (m_clut_ptr)
		{
			for (int i = 0; i < 0x0800; i++)
			{
				m_clut[i] = m_clut_ptr[i];
			}
		}
		save_item(NAME(m_param_cnt));
		save_item(NAME(m_param_old));
	}

	common_save_state();
}

void nbmj8891_state::video_start()
{
	int width = m_screen->width();
	int height = m_screen->height();

	m_blitter_timer = timer_alloc(TIMER_BLITTER);
	m_screen->register_screen_bitmap(m_tmpbitmap0);
	m_screen->register_screen_bitmap(m_tmpbitmap1);
	m_videoram0 = std::make_unique<uint8_t[]>(width * height);
	m_videoram1 = std::make_unique<uint8_t[]>(width * height);
	m_palette_ptr = std::make_unique<uint8_t[]>(0x200);
	m_clut = std::make_unique<uint8_t[]>(0x800);
	memset(m_videoram0.get(), 0xff, (width * height * sizeof(uint8_t)));
	memset(m_videoram1.get(), 0xff, (width * height * sizeof(uint8_t)));
	m_gfxdraw_mode = 1;
	m_screen_refresh = 1;

	common_save_state();
	save_pointer(NAME(m_videoram1), width * height);
}

void nbmj8891_state::common_save_state()
{
	save_item(NAME(m_scrolly));
	save_item(NAME(m_blitter_destx));
	save_item(NAME(m_blitter_desty));
	save_item(NAME(m_blitter_sizex));
	save_item(NAME(m_blitter_sizey));
	save_item(NAME(m_blitter_src_addr));
	save_item(NAME(m_blitter_direction_x));
	save_item(NAME(m_blitter_direction_y));
	save_item(NAME(m_vram));
	save_item(NAME(m_gfxrom));
	save_item(NAME(m_dispflag));
	save_item(NAME(m_flipscreen));
	save_item(NAME(m_clutsel));
	save_item(NAME(m_gfxdraw_mode));
	save_pointer(NAME(m_videoram0), m_screen->width() * m_screen->height());
	save_pointer(NAME(m_palette_ptr), 0x200);
	save_pointer(NAME(m_clut), 0x800);
	save_item(NAME(m_flipscreen_old));

	machine().save().register_postload(save_prepost_delegate(FUNC(nbmj8891_state::postload), this));
}

void nbmj8891_state::postload()
{
	m_screen_refresh = 1;
}

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


******************************************************************************/
uint32_t nbmj8891_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int x, y;

	if (m_screen_refresh)
	{
		int width = screen.width();
		int height = screen.height();

		m_screen_refresh = 0;
		for (y = 0; y < height; y++)
			for (x = 0; x < width; x++)
				update_pixel0(x, y);

		if (m_gfxdraw_mode)
			for (y = 0; y < height; y++)
				for (x = 0; x < width; x++)
					update_pixel1(x, y);
	}

	if (m_dispflag)
	{
		int scrolly;
		if (!m_flipscreen) scrolly =   m_scrolly;
		else                      scrolly = (-m_scrolly) & 0xff;

		if (m_gfxdraw_mode)
		{
			copyscrollbitmap      (bitmap, m_tmpbitmap0, 0, nullptr, 0, nullptr, cliprect);
			copyscrollbitmap_trans(bitmap, m_tmpbitmap1, 0, nullptr, 1, &scrolly, cliprect, 0xff);
		}
		else
			copyscrollbitmap(bitmap, m_tmpbitmap0, 0, nullptr, 1, &scrolly, cliprect);
	}
	else
		bitmap.fill(0xff);

	return 0;
}