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

                                                             

                                                                            
                                              


                                                                            
                
                              
 
 






                                       
                                  
 
                                                            
                                                                                                                                            
                                                                                           
 
                                       



                                             


 





                                       
                                                  
 
                                                   




                                                                              
                                                                                         
                                                               
                                                                                               
 
                                                          
                                                          
 
                                      
 
                                                                          
                                               
                 
                                                                                                                      
                 





                                                    

                                                                                                              


         
                                                 
 



                                                                               

                                                              
 
                                                                          
                                               
                 
                                                                                                                      




                                              
                                           
 






                                       
                                                  





                                                
                                                              




                            

                                                      


            

                                                      





                                                                                                        
                                                                                                                  







                                        
                                               





                                       
                                                                                


                          
                                          
         















                                                                  


                          

                                                 

                          
                                                                

                                  
                                                                        
                                  
                                                                        


         
                                                 



                                                
 

                            
                                                      
            
                                                      






                                        
                                               





                                       
                                                                                                  







                                           
                                    


                                       
                                          
 
                    
 
                                                        
         
                                                         
 
                                                                                                  
         

 
                                                                 
 
                                      
                      
 
                       
 

                                               
 
                                        
         


                                   







                                                                                       




                           

                                                      
                                                                 

 
                                                                                                                       
 
                                                                    
 

                 
// license:BSD-3-Clause
// copyright-holders:Dan Boris, Olivier Galibert, Aaron Giles
/***************************************************************************

    Star Fire/Fire One system - video hardware

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

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



/*************************************
 *
 *  Initialize the video system
 *
 *************************************/

void starfire_state::video_start()
{
	m_screen->register_screen_bitmap(m_starfire_screen);
	m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(starfire_state::starfire_scanline_callback),this));
	m_scanline_timer->adjust(m_screen->time_until_pos(STARFIRE_VBEND), STARFIRE_VBEND);

	/* register for state saving */
	save_item(NAME(m_starfire_vidctrl));
	save_item(NAME(m_starfire_vidctrl1));
	save_item(NAME(m_starfire_color));
	save_item(NAME(m_starfire_colors));
}


/*************************************
 *
 *  Color RAM read/writes
 *
 *************************************/

WRITE8_MEMBER(starfire_state::starfire_colorram_w)
{
	/* handle writes to the pseudo-color RAM */
	if ((offset & 0xe0) == 0)
	{
		int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4);

		/* set RAM regardless */
		int cl = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
		int cr = (data >> 5) | ((offset & 0x100) >> 5);
		cr |= (m_starfire_vidctrl1 & 0x80) ? (m_starfire_color & 0x10) : (data & 0x10);

		m_starfire_colorram[offset & ~0x100] = cl;
		m_starfire_colorram[offset |  0x100] = cr;

		m_starfire_color = cl;

		/* don't modify the palette unless the TRANS bit is set */
		if (m_starfire_vidctrl1 & 0x40)
		{
			m_starfire_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
		}
	}

	/* handle writes to the rest of color RAM */
	else
	{
		/* set RAM based on CDRM */
		m_starfire_colorram[offset] = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
		m_starfire_color = (m_starfire_vidctrl1 & 0x80) ? m_starfire_color : (data & 0x1f);
	}
}

READ8_MEMBER(starfire_state::starfire_colorram_r)
{
	/* handle writes to the pseudo-color RAM, which also happen on reads */
	if ((offset & 0xe0) == 0)
	{
		int palette_index = (offset & 0x1f) | ((offset & 0x200) >> 4);
		int cl = m_starfire_colorram[offset & ~0x100];
		int cr = m_starfire_colorram[offset |  0x100];

		/* don't modify the palette unless the TRANS bit is set */
		if (m_starfire_vidctrl1 & 0x40)
		{
			m_starfire_colors[palette_index] = ((cl & 0x3) << 7) | ((cr & 0xf) << 3) | ((cl & 0x1c) >> 2);
		}

		return cl | ((cr & 0x7) << 5);
	}

	return m_starfire_colorram[offset];
}

/*************************************
 *
 *  Video RAM read/writes
 *
 *************************************/

WRITE8_MEMBER(starfire_state::starfire_videoram_w)
{
	int sh, lr, dm, ds, mask, d0, dalu;
	int offset1 = offset & 0x1fff;
	int offset2 = (offset + 0x100) & 0x1fff;

	/* PROT */
	if (!(offset & 0xe0) && !(m_starfire_vidctrl1 & 0x20))
		return;

	/* selector 6A */
	if (offset & 0x2000)
	{
		sh = (m_starfire_vidctrl >> 1) & 0x07;
		lr = m_starfire_vidctrl & 0x01;
	}
	else
	{
		sh = (m_starfire_vidctrl >> 5) & 0x07;
		lr = (m_starfire_vidctrl >> 4) & 0x01;
	}

	/* mirror bits 5B/5C/5D/5E */
	dm = data;
	if (lr)
		dm = ((dm & 0x01) << 7) | ((dm & 0x02) << 5) | ((dm & 0x04) << 3) | ((dm & 0x08) << 1) |
				((dm & 0x10) >> 1) | ((dm & 0x20) >> 3) | ((dm & 0x40) >> 5) | ((dm & 0x80) >> 7);

	/* shifters 6D/6E */
	ds = (dm << 8) >> sh;
	mask = 0xff00 >> sh;

	/* ROLL */
	if ((offset & 0x1f00) == 0x1f00)
	{
		if (m_starfire_vidctrl1 & 0x10)
			mask &= 0x00ff;
		else
			mask &= 0xff00;
	}

	/* ALU 8B/8D */
	d0 = (m_starfire_videoram[offset1] << 8) | m_starfire_videoram[offset2];
	dalu = d0 & ~mask;
	d0 &= mask;
	ds &= mask;
	switch (~m_starfire_vidctrl1 & 15)
	{
		case 0:     dalu |= ds ^ mask;              break;
		case 1:     dalu |= (ds | d0) ^ mask;       break;
		case 2:     dalu |= (ds ^ mask) & d0;       break;
		case 3:     dalu |= 0;                      break;
		case 4:     dalu |= (ds & d0) ^ mask;       break;
		case 5:     dalu |= d0 ^ mask;              break;
		case 6:     dalu |= ds ^ d0;                break;
		case 7:     dalu |= ds & (d0 ^ mask);       break;
		case 8:     dalu |= (ds ^ mask) | d0;       break;
		case 9:     dalu |= (ds ^ d0) ^ mask;       break;
		case 10:    dalu |= d0;                     break;
		case 11:    dalu |= ds & d0;                break;
		case 12:    dalu |= mask;                   break;
		case 13:    dalu |= ds | (d0 ^ mask);       break;
		case 14:    dalu |= ds | d0;                break;
		case 15:    dalu |= ds;                     break;
	}

	/* final output */
	m_starfire_videoram[offset1] = dalu >> 8;
	m_starfire_videoram[offset2] = dalu;

	/* color output */
	if (!(offset & 0x2000) && !(m_starfire_vidctrl1 & 0x80))
	{
		if (mask & 0xff00)
			m_starfire_colorram[offset1] = m_starfire_color;
		if (mask & 0x00ff)
			m_starfire_colorram[offset2] = m_starfire_color;
	}
}

READ8_MEMBER(starfire_state::starfire_videoram_r)
{
	int sh, mask, d0;
	int offset1 = offset & 0x1fff;
	int offset2 = (offset + 0x100) & 0x1fff;

	/* selector 6A */
	if (offset & 0x2000)
		sh = (m_starfire_vidctrl >> 1) & 0x07;
	else
		sh = (m_starfire_vidctrl >> 5) & 0x07;

	/* shifters 6D/6E */
	mask = 0xff00 >> sh;

	/* ROLL */
	if ((offset & 0x1f00) == 0x1f00)
	{
		if (m_starfire_vidctrl1 & 0x10)
			mask &= 0x00ff;
		else
			mask &= 0xff00;
	}

	/* munge the results */
	d0 = (m_starfire_videoram[offset1] & (mask >> 8)) | (m_starfire_videoram[offset2] & mask);
	d0 = (d0 << sh) | (d0 >> (8 - sh));
	return d0 & 0xff;
}



/*************************************
 *
 *  Standard screen refresh callback
 *
 *************************************/

void starfire_state::get_pens(pen_t *pens)
{
	offs_t offs;

	for (offs = 0; offs < STARFIRE_NUM_PENS; offs++)
	{
		uint16_t color = m_starfire_colors[offs];

		pens[offs] = rgb_t(pal3bit(color >> 6), pal3bit(color >> 3), pal3bit(color >> 0));
	}
}

TIMER_CALLBACK_MEMBER(starfire_state::starfire_scanline_callback)
{
	pen_t pens[STARFIRE_NUM_PENS];
	int y = param;

	get_pens(pens);

	uint8_t *pix = &m_starfire_videoram[y];
	uint8_t *col = &m_starfire_colorram[y];

	for (int x = 0; x < 256; x += 8)
	{
		int data = pix[0];
		int color = col[0];

		m_starfire_screen.pix32(y, x + 0) = pens[color | ((data >> 2) & 0x20)];
		m_starfire_screen.pix32(y, x + 1) = pens[color | ((data >> 1) & 0x20)];
		m_starfire_screen.pix32(y, x + 2) = pens[color | ((data >> 0) & 0x20)];
		m_starfire_screen.pix32(y, x + 3) = pens[color | ((data << 1) & 0x20)];
		m_starfire_screen.pix32(y, x + 4) = pens[color | ((data << 2) & 0x20)];
		m_starfire_screen.pix32(y, x + 5) = pens[color | ((data << 3) & 0x20)];
		m_starfire_screen.pix32(y, x + 6) = pens[color | ((data << 4) & 0x20)];
		m_starfire_screen.pix32(y, x + 7) = pens[color | ((data << 5) & 0x20)];

		pix += 256;
		col += 256;
	}

	y++;
	if (y >= STARFIRE_VBSTART) y = STARFIRE_VBEND;
	m_scanline_timer->adjust(m_screen->time_until_pos(y), y);
}

uint32_t starfire_state::screen_update_starfire(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	copybitmap(bitmap, m_starfire_screen, 0, 0, 0, 0, cliprect);

	return 0;
}