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

                                   






                                   

                         


                            













                                            
                           















                                                          
                                                                                        
                       
                                                                  




















                                                             
                                                         








                                                                           
                                                               



















                                           
                                                     
 
                       

 
                                                                          
 
                     




                            
                                       
                                 
                                                                                         


                       

                                                                                  
                                    

                                           


                                

                                            

         
                                                                                        

 
                                                         



                                                                                 



                               


                     
                           



                            
                                               

            
                                              
 


                                                                          
 
                                             













                                                                       
                                                                                             
                         
                                                                                  







                                                  
                                 

 
                                                      


                                                                       
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                    



                                           

                                                                                                              

                                    
                                                         



                 
                                                    

              
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                    



                                           
                                                                                                 

                                    

                                           

                                    
                                                         



                 
                                                     

              
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                    



                                           
                                                                                                 

                                    

                                           

                                    
                                                         



                 
                                                     

              
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                    



                                           
                                                                                                 

                                    

                                           

                                    
                                                         



                 
                                                     

              
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                    



                                           
                                                                                                 

                                    

                                           

                                    
                                                         



                 
                                                         


                                                                          
                    
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    
                 
                                                                                                 
 
                                                
 
                                                         



                 
                                                           


                                                                             
                        
                     
                     
 

                                                 



                            
                                               

            
                                              


                                               
                                                    



                                       
                                                                

                                              
                                                                

                                              
                                                                

                                              

                                                                                                              

                                    
                                                         



                 
                                                 
 
                                    

                                  
                                                      

                                
                                                    

                                 
                                                     

                                 
                                                     

                                 
                                                     

                                       
                                                           

                                     
                                                         


                              
                                                         


         
                                                    
 

                                                                                               

 
                                                        






                                           
                                         
                       
                                          

                               
                                                       
         

                                                  




                    
                                  
 



                          
 




                              
 

                          
            


                           
            
                           
 


                      
         
                                           






                                        
                 

                                    
                 
                             
                 

                                    




                                         
                                                                                 




                                   
                               











                                                                                               
         
                                              





















                                                                                              
                               












                                                                               
                                              
























                                                                                              
                               















                                                                               
                                              




























































































































































































                                                                                              
                                
































































                                                                                                             
                                                                                                            




























                                                                                            
                                                                                                 

                              
                                                                                                

                              
                                                                                                  




















                                                                               
                           
 
                              















                                              
                                                     

















                                                               
                           



                                           
                               













                                                   
                                                                                               



                                                   
                                                                                                











                                                                                   

                                            
































                                                                    
                                                                  
























































                                                                                                     



                                      
                     




































































































                                                                                                            
                                           






                                                                                               
                                              
 

                                         

                                                                                                                      


            
                                       
                                                                                





                                                                                         

                                                    












































                                                                                                     



                                                    
                                                    






















































                                                                                                                   
                                                    








                                                  
                                                    






                                   
                             
 












                                       

 
                                                                                                             
 




                                                    
                    
                               
 
                                           

                              
                                   

                         
                                                      




                                                
                                                                
                                 



                                                                                                                      
                                 
                                                                
                                 



                                                                                                                      
                                 
                                                                
                                 



                                                                                                                     





                                                                                                                                                                                                      
                                                                                                  









                                                





                                                                                                                          


                                                                                                                                                     
                                                                                               





                                 
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*
 *
 *  Fujitsu Micro 7 Video functions
 *
 */

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

#include "cpu/m6809/m6809.h"
#include "screen.h"


/*
 * Main CPU: Sub-CPU interface (port 0xfd05)
 *
 * Read:
 *   bit 7: Sub-CPU busy (or halted)
 *   bit 0: EXTDET (?)
 * Write:
 *   bit 7: Sub-CPU halt
 *   bit 6: Sub-CPU cancel IRQ
 */

READ8_MEMBER(fm7_state::fm7_subintf_r)
{
	uint8_t ret = 0x00;

	if(m_video.sub_busy != 0 || m_video.sub_halt != 0)
		ret |= 0x80;

	ret |= 0x7e;
	//ret |= 0x01; // EXTDET (not implemented yet)

	return ret;
}

WRITE8_MEMBER(fm7_state::fm7_subintf_w)
{
	m_video.sub_halt = data & 0x80;
	if(data & 0x80)
		m_video.sub_busy = data & 0x80;

	m_sub->set_input_line(INPUT_LINE_HALT,(data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
	if(data & 0x40)
		m_sub->set_input_line(M6809_IRQ_LINE,ASSERT_LINE);
	//popmessage("Sub CPU Interface write: %02x\n",data);
}

READ8_MEMBER(fm7_state::fm7_sub_busyflag_r)
{
	if(m_video.sub_halt == 0)
		m_video.sub_busy = 0x00;
	return 0x00;
}

WRITE8_MEMBER(fm7_state::fm7_sub_busyflag_w)
{
	m_video.sub_busy = 0x80;
}

/*
 * Sub-CPU port 0xd402
 *   Read-only: Acknowledge Cancel IRQ
 */
READ8_MEMBER(fm7_state::fm7_cancel_ack)
{
	m_sub->set_input_line(M6809_IRQ_LINE,CLEAR_LINE);
	return 0x00;
}

/*
 * Reading from 0xd404 (sub-CPU) causes an "Attention" FIRQ on the main CPU
 */
READ8_MEMBER(fm7_state::fm7_attn_irq_r)
{
	m_video.attn_irq = 1;
	m_maincpu->set_input_line(M6809_FIRQ_LINE,ASSERT_LINE);
	return 0xff;
}

/*
 *  Sub CPU: I/O port 0xd409
 *
 *  On read, enables VRAM access
 *  On write, disables VRAM access
 */
READ8_MEMBER(fm7_state::fm7_vram_access_r)
{
	m_video.vram_access = 1;
	return 0xff;
}

WRITE8_MEMBER(fm7_state::fm7_vram_access_w)
{
	m_video.vram_access = 0;
}

TIMER_CALLBACK_MEMBER(fm7_state::fm77av_alu_task_end)
{
	m_alu.busy = 0;
}

void fm7_state::fm7_alu_mask_write(uint32_t offset, int bank, uint8_t dat)
{
	uint8_t temp;
	int page = 0;

	if(offset >= 0xc000)
		page = 1;

	if((m_alu.command & 0x40) == 0)
	{  // "always" write mode
		m_video_ram[(offset & 0x3fff) + (bank * 0x4000) + (page * 0xc000)] = dat;
		return;
	}

	temp = m_video_ram[(offset & 0x3fff) + (bank * 0x4000) + (page * 0xc000)];
	if(m_alu.command & 0x20)
	{  // "not equal" write mode
		temp &= m_alu.compare_data;
		dat &= ~m_alu.compare_data;
	}
	else
	{  // "equal" write mode
		temp &= ~m_alu.compare_data;
		dat &= m_alu.compare_data;
	}

	m_video_ram[(offset & 0x3fff) + (bank * 0x4000) + (page * 0xc000)] = temp | dat;
}

void fm7_state::fm7_alu_function_compare(uint32_t offset)
{
	// COMPARE - compares which colors match those in the compare registers
	// can be used on its own, or when bit 6 of the command register is high.

	uint8_t red,green,blue;
	uint8_t dat = 0;
	uint8_t colour;
	uint8_t banks;
	int x,y;
	int match;
	int page = 0;
	uint8_t bit = 0x80;

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	blue = m_video_ram[(offset & 0x3fff) + (page * 0xc000)];
	red = m_video_ram[(offset & 0x3fff) + 0x4000 + (page * 0xc000)];
	green = m_video_ram[(offset & 0x3fff) + 0x8000 + (page * 0xc000)];

	banks = (~m_alu.bank_disable) & 0x07;

	for(x=0;x<8;x++) // loop through each pixel
	{
		colour = 0;
		if(blue & bit)
			colour |= 1;
		if(red & bit)
			colour |= 2;
		if(green & bit)
			colour |= 4;

		match = 0;
		for(y=0;y<8;y++)  // loop through each compare register
		{
			if(!(m_alu.compare[y] & 0x80)) // don't compare if register is masked
			{
				if((m_alu.compare[y] & banks) == (colour & banks))
					match = 1;
			}
		}
		if(match != 0)
			dat |= bit;

		bit >>= 1;
	}
	m_alu.compare_data = dat;
}

void fm7_state::fm7_alu_function_pset(uint32_t offset)
{
	// PSET - simply sets the pixels to the selected logical colour
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			if(m_alu.lcolour & (1 << x))
				dat = 0xff;
			else
				dat = 0;

			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]) & m_alu.mask;
			dat &= ~m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_or(uint32_t offset)
{
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			if(m_alu.lcolour & (1 << x))
				dat = 0xff;
			else
				dat = 0;

			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]);
			dat |= mask;

			mask &= m_alu.mask;
			dat &= ~m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_and(uint32_t offset)
{
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			if(m_alu.lcolour & (1 << x))
				dat = 0xff;
			else
				dat = 0;

			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]);
			dat &= mask;

			mask &= m_alu.mask;
			dat &= ~m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_xor(uint32_t offset)
{
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			if(m_alu.lcolour & (1 << x))
				dat = 0xff;
			else
				dat = 0;

			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]);
			dat ^= mask;

			mask &= m_alu.mask;
			dat &= ~m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_not(uint32_t offset)
{
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			if(m_alu.lcolour & (1 << x))
				dat = 0xff;
			else
				dat = 0;

			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]);
			dat = ~mask;

			mask &= m_alu.mask;
			dat &= ~m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_invalid(uint32_t offset)
{
	// Invalid function, still does something though (used by Laydock)
	int x;
	uint8_t dat;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]);

			dat = mask & m_alu.mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function_tilepaint(uint32_t offset)
{
	// TILEPAINT - writes to VRAM based on the tilepaint colour registers
	int x;
	uint8_t dat = 0;
	int page = 0;
	uint8_t mask;

	if(m_alu.command & 0x40)
		fm7_alu_function_compare(offset);

	if(offset >= 0xc000)
	{
		page = 1;
		offset += m_video.vram_offset2;
	}
	else
		offset += m_video.vram_offset;

	for(x=0;x<3;x++) // cycle through banks
	{
		if(!(m_alu.bank_disable & (1 << x)))
		{
			switch(x)
			{
				case 0:
					dat = m_alu.tilepaint_b;
					break;
				case 1:
					dat = m_alu.tilepaint_r;
					break;
				case 2:
					dat = m_alu.tilepaint_g;
					break;
			}
			dat &= ~m_alu.mask;
			mask = (m_video_ram[(offset & 0x3fff) + (x * 0x4000) + (page * 0xc000)]) & m_alu.mask;
			dat |= mask;

			fm7_alu_mask_write(offset,x,dat);
		}
	}
}

void fm7_state::fm7_alu_function(uint32_t offset)
{
	switch(m_alu.command & 0x07)
	{
		case 0x00: // PSET
			fm7_alu_function_pset(offset);
			break;
		case 0x02: // OR
			fm7_alu_function_or(offset);
			break;
		case 0x03: // AND
			fm7_alu_function_and(offset);
			break;
		case 0x04: // XOR
			fm7_alu_function_xor(offset);
			break;
		case 0x05: // NOT
			fm7_alu_function_not(offset);
			break;
		case 0x06: // TILEPAINT
			fm7_alu_function_tilepaint(offset);
			break;
		case 0x07: // COMPARE
			fm7_alu_function_compare(offset);
			break;
		case 0x01:
		default:
			fm7_alu_function_invalid(offset);
	}
}

uint32_t fm7_state::fm7_line_set_pixel(int x, int y)
{
	uint32_t addr;
	static const uint8_t pixel_mask[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };


	if(m_video.modestatus & 0x40) // 320 pixels wide
	{
		addr = (x >> 3) + (y * 40);
	}
	else  // 640 pixels wide
	{
		addr = (x >> 3) + (y * 80);
	}
	addr += (m_alu.addr_offset << 1);
	addr &= 0x3fff;
	if(m_video.active_video_page != 0)
		addr += 0xc000;

	if(m_alu.command & 0x80)  // ALU must be active
	{
		m_alu.mask = pixel_mask[x & 0x07];
		fm7_alu_function(addr);
	}

	return addr;
}

void fm7_state::fm77av_line_draw()
{
	int x1 = m_alu.x0;
	int x2 = m_alu.x1;
	int y1 = m_alu.y0;
	int y2 = m_alu.y1;

	int dx = abs(x2 - x1);
	int dy = abs(y2 - y1);
	int stepx, stepy;
	int err,err2;
	int byte_count = 0;

	if(x1 < x2)
		stepx = 1;
	else
		stepx = -1;
	if(y1 < y2)
		stepy = 1;
	else
		stepy = -1;

	err = dx - dy;

	for(;;)
	{
		fm7_line_set_pixel(x1, y1);
		byte_count++;

		if(x1 == x2 && y1 == y2)
			break;

		err2 = 2*err;
		if(err2 > -dy)
		{
			err -= dy;
			x1 += stepx;
		}
		if(err2 < dx)
		{
			err += dx;
			y1 += stepy;
		}
	}

	// set timer to disable busy flag
	// 1/16 us for each byte changed
	timer_set(attotime::from_usec(byte_count/16), TIMER_FM77AV_ALU_TASK_END);
}

READ8_MEMBER(fm7_state::fm7_vram_r)
{
	int offs;
	uint16_t page = 0x0000;

	if(m_video.active_video_page != 0)
		page = 0xc000;

	if(offset < 0x4000 && (m_video.multi_page & 0x01))
		return 0xff;
	if((offset < 0x8000 && offset >=0x4000) && (m_video.multi_page & 0x02))
		return 0xff;
	if((offset < 0xc000 && offset >=0x8000) && (m_video.multi_page & 0x04))
		return 0xff;

	if(m_alu.command & 0x80) // ALU active, writes to VRAM even when reading it (go figure)
	{
		fm7_alu_function(offset+page);
	}

	if(m_video.modestatus & 0x40)
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset2) & 0x1fff);
		else
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset) & 0x1fff);
	}
	else
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset2) & 0x3fff);
		else
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset) & 0x3fff);
	}
	return m_video_ram[offs + page];
}

WRITE8_MEMBER(fm7_state::fm7_vram_w)
{
	int offs;
	uint16_t page = 0x0000;

	if(m_video.active_video_page != 0)
		page = 0xc000;

	if(offset < 0x4000 && (m_video.multi_page & 0x01))
		return;
	if((offset < 0x8000 && offset >=0x4000) && (m_video.multi_page & 0x02))
		return;
	if((offset < 0xc000 && offset >=0x8000) && (m_video.multi_page & 0x04))
		return;

	if(m_alu.command & 0x80) // ALU active
	{
		fm7_alu_function(offset+page);
		return;
	}

	if(m_video.modestatus & 0x40)
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset2) & 0x1fff);
		else
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset) & 0x1fff);
	}
	else
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset2) & 0x3fff);
		else
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset) & 0x3fff);
	}
//  if(m_video.vram_access != 0)
		m_video_ram[offs+page] = data;
}

// not pretty, but it should work.
WRITE8_MEMBER(fm7_state::fm7_vram_banked_w)
{
	int offs;
	uint16_t page = 0x0000;

	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return;

	if(m_video.active_video_page != 0)
		page = 0xc000;

	if(offset < 0x4000 && (m_video.multi_page & 0x01))
		return;
	if((offset < 0x8000 && offset >=0x4000) && (m_video.multi_page & 0x02))
		return;
	if((offset < 0xc000 && offset >=0x8000) && (m_video.multi_page & 0x04))
		return;

	if(m_alu.command & 0x80) // ALU active
	{
		fm7_alu_function(offset+page);
		return;
	}

	if(m_video.modestatus & 0x40)
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset2) & 0x1fff);
		else
			offs = (offset & 0xe000) | ((offset + m_video.vram_offset) & 0x1fff);
	}
	else
	{
		if(m_video.active_video_page != 0)
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset2) & 0x3fff);
		else
			offs = (offset & 0xc000) | ((offset + m_video.vram_offset) & 0x3fff);
	}
	m_video_ram[offs+page] = data;
}

READ8_MEMBER(fm7_state::fm7_vram0_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset);
}

READ8_MEMBER(fm7_state::fm7_vram1_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x1000);
}

READ8_MEMBER(fm7_state::fm7_vram2_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x2000);
}

READ8_MEMBER(fm7_state::fm7_vram3_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x3000);
}

READ8_MEMBER(fm7_state::fm7_vram4_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x4000);
}

READ8_MEMBER(fm7_state::fm7_vram5_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x5000);
}

READ8_MEMBER(fm7_state::fm7_vram6_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x6000);
}

READ8_MEMBER(fm7_state::fm7_vram7_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x7000);
}

READ8_MEMBER(fm7_state::fm7_vram8_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x8000);
}

READ8_MEMBER(fm7_state::fm7_vram9_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0x9000);
}

READ8_MEMBER(fm7_state::fm7_vramA_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0xa000);
}

READ8_MEMBER(fm7_state::fm7_vramB_r)
{
	if(!m_video.sub_halt)  // no access if sub CPU is not halted.
		return 0xff;
	return fm7_vram_r(space,offset+0xb000);
}

WRITE8_MEMBER(fm7_state::fm7_vram0_w)
{
	fm7_vram_banked_w(space,offset,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram1_w)
{
	fm7_vram_banked_w(space,offset+0x1000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram2_w)
{
	fm7_vram_banked_w(space,offset+0x2000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram3_w)
{
	fm7_vram_banked_w(space,offset+0x3000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram4_w)
{
	fm7_vram_banked_w(space,offset+0x4000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram5_w)
{
	fm7_vram_banked_w(space,offset+0x5000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram6_w)
{
	fm7_vram_banked_w(space,offset+0x6000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram7_w)
{
	fm7_vram_banked_w(space,offset+0x7000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram8_w)
{
	fm7_vram_banked_w(space,offset+0x8000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vram9_w)
{
	fm7_vram_banked_w(space,offset+0x9000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vramA_w)
{
	fm7_vram_banked_w(space,offset+0xa000,data);
}

WRITE8_MEMBER(fm7_state::fm7_vramB_w)
{
	fm7_vram_banked_w(space,offset+0xb000,data);
}

/*
 *  Sub CPU: I/O port 0xd408
 *
 *  On read, enables the CRT display
 *  On write, disables the CRT display
 */
READ8_MEMBER(fm7_state::fm7_crt_r)
{
	m_video.crt_enable = 1;
	return 0xff;
}

WRITE8_MEMBER(fm7_state::fm7_crt_w)
{
	m_video.crt_enable = 0;
}

/*
 *  Sub CPU: I/O ports 0xd40e - 0xd40f
 *
 *  0xd40e: bits 0-6 - offset in bytes (high byte) (bit 6 is used for 400 line video only)
 *  0xd40f: bits 0-7 - offset in bytes (low byte)
 */
WRITE8_MEMBER(fm7_state::fm7_vram_offset_w)
{
	uint16_t new_offset = 0;

	switch(offset)
	{
		case 0:
			if(m_video.active_video_page != 0)
				new_offset = ((data & 0x3f) << 8) | (m_video.vram_offset2 & 0x00ff);
			else
				new_offset = ((data & 0x3f) << 8) | (m_video.vram_offset & 0x00ff);
			break;
		case 1:  // low 5 bits are used on FM-77AV and later only
			if(m_type == SYS_FM7)
				new_offset = (m_video.vram_offset & 0xff00) | (data & 0xe0);
			else
			{
				if(m_video.active_video_page != 0)
				{
					if(m_video.fine_offset != 0)
						new_offset = (m_video.vram_offset2 & 0xff00) | (data & 0xff);
					else
						new_offset = (m_video.vram_offset2 & 0xff00) | (data & 0xe0);
				}
				else
				{
					if(m_video.fine_offset != 0)
						new_offset = (m_video.vram_offset & 0xff00) | (data & 0xff);
					else
						new_offset = (m_video.vram_offset & 0xff00) | (data & 0xe0);
				}
			}
			break;
	}
	if(m_video.active_video_page != 0)
		m_video.vram_offset2 = new_offset;
	else
		m_video.vram_offset = new_offset;
}

/*
 *  Main CPU: port 0xfd37
 *  Multipage
 *  Port is write-only
 *
 *  bits 6-4: VRAM planes to display (G,R,B) (1=disable)
 *  bits 2-0: VRAM CPU access (G,R,B) (1=disable)
 */
WRITE8_MEMBER(fm7_state::fm7_multipage_w)
{
	m_video.multi_page = data & 0x77;
}

/*
 *  Main CPU: I/O ports 0xfd38-0xfd3f
 *  Colour palette.
 *  Each port represents one of eight colours.  Palette is 3-bit.
 *  bit 2 = Green
 *  bit 1 = Red
 *  bit 0 = Blue
 */
READ8_MEMBER(fm7_state::fm7_palette_r)
{
	return m_video.fm7_pal[offset];
}

WRITE8_MEMBER(fm7_state::fm7_palette_w)
{
	m_palette->set_pen_color(offset, rgb_t(pal1bit(data >> 1), pal1bit(data >> 2), pal1bit(data >> 0)));
	m_video.fm7_pal[offset] = data & 0x07;
}

/*
 *  Main CPU: 0xfd30 - 0xfd34
 *  Analog colour palette (FM-77AV and later only)
 *  All ports are write-only.
 *
 *  fd30: colour select(?) high 4 bits (LC11-LC8)
 *  fd31: colour select(?) low 8 bits (LC7-LC0)
 *  fd32: blue level (4 bits)
 *  fd33: red level (4 bits)
 *  fd34: green level (4 bits)
 */
WRITE8_MEMBER(fm7_state::fm77av_analog_palette_w)
{
	int val;

	switch(offset)
	{
		case 0:
			val = ((data & 0x0f) << 8) | (m_video.fm77av_pal_selected & 0x00ff);
			m_video.fm77av_pal_selected = val;
			break;
		case 1:
			val = data | (m_video.fm77av_pal_selected & 0x0f00);
			m_video.fm77av_pal_selected = val;
			break;
		case 2:
			m_av_palette->set_pen_blue_level(m_video.fm77av_pal_selected, data << 4);
			break;
		case 3:
			m_av_palette->set_pen_red_level(m_video.fm77av_pal_selected, data << 4);
			break;
		case 4:
			m_av_palette->set_pen_green_level(m_video.fm77av_pal_selected, data << 4);
			break;
	}
}


/*
 *   Sub CPU: 0xd430 - BUSY/NMI/Bank register (FM77AV series only)
 *
 *   On read:  bit 7 - 0 if in VBlank
 *             bit 4 - ALU busy(0)/ready(1)
 *             bit 2 - VSync status (1 if active?)
 *             bit 0 - RESET
 *
 *   On write: bits 1-0 - CGROM select (maps to 0xd800)
 *             bit 2 - fine offset enable (enables OA4-OA0 bits in VRAM offset)
 *             bit 5 - active VRAM page
 *             bit 6 - display VRAM page
 *             bit 7 - NMI mask register (1=mask)
 */
READ8_MEMBER(fm7_state::fm77av_video_flags_r)
{
	uint8_t ret = 0xff;

	if(m_screen->vblank())
		ret &= ~0x80;

	if(m_alu.busy != 0)
		ret &= ~0x10;

	if(m_video.vsync_flag == 0)
		ret &= ~0x04;

	if(!m_video.sub_reset)
		ret &= ~0x01;

	return ret;
}

WRITE8_MEMBER(fm7_state::fm77av_video_flags_w)
{
	uint8_t* RAM = memregion("subsyscg")->base();

	m_video.cgrom = data & 0x03;
	membank("bank20")->set_base(RAM+(m_video.cgrom*0x800));
	m_video.fine_offset = data & 0x04;
	m_video.active_video_page = data & 0x20;
	m_video.display_video_page = data & 0x40;
	m_video.nmi_mask = data & 0x80;
}

/*
 *  Main CPU: port 0xfd12
 *  Sub mode status register  (FM-77AV or later)
 *  bit 6 (R/W) - Video mode width(?) 0=640 (default) 1=320.
 *  bit 1 (R/O) - DISPTMG status (0=blank)
 *  bit 0 (R/O) - VSync status (1=sync?)
 */
READ8_MEMBER(fm7_state::fm77av_sub_modestatus_r)
{
	uint8_t ret = 0x00;

	ret |= 0xbc;
	ret |= (m_video.modestatus & 0x40);

	if(!m_screen->vblank())
		ret |= 0x02;

	if(m_video.vsync_flag != 0)
		ret |= 0x01;

	return ret;
}

WRITE8_MEMBER(fm7_state::fm77av_sub_modestatus_w)
{
	m_video.modestatus = data & 0x40;
	if(data & 0x40)
	{
		rectangle rect(0, 320-1, 0, 200-1);
		m_screen->configure(512, 262, rect, m_screen->frame_period().as_attoseconds());
	}
	else
	{
		rectangle rect(0, 640-1, 0, 200-1);
		m_screen->configure(1024, 262, rect, m_screen->frame_period().as_attoseconds());
	}
}

/*
 *  Main CPU: port 0xfd13
 *  Sub Bank select register
 *
 *  bits 1 and 0 select which subsys ROM to be banked into sub CPU space
 *  on the FM-77AV40 and later, bit 2 can also selected to bank in sub monitor RAM.
 */
WRITE8_MEMBER(fm7_state::fm77av_sub_bank_w)
{
//  uint8_t* RAM = memregion("sub")->base();
	uint8_t* ROM;

	if((data & 0x03) == (m_sb_prev & 0x03))
		return;

	m_video.subrom = data & 0x03;
	switch (data & 0x03)
	{
		case 0x00:  // Type C, 640x200 (as used on the FM-7)
			ROM = memregion("subsys_c")->base();
		//  membank(20)->set_base(ROM);
			membank("bank21")->set_base(ROM+0x800);
			logerror("VID: Sub ROM Type C selected\n");
			break;
		case 0x01:  // Type A, 640x200
			ROM = memregion("subsys_a")->base();
		//  membank(20)->set_base(RAM+0xd800);
			membank("bank21")->set_base(ROM);
			logerror("VID: Sub ROM Type A selected\n");
			break;
		case 0x02:  // Type B, 320x200
			ROM = memregion("subsys_b")->base();
		//  membank(20)->set_base(RAM+0xd800);
			membank("bank21")->set_base(ROM);
			logerror("VID: Sub ROM Type B selected\n");
			break;
		case 0x03:  // CG Font?
			ROM = memregion("subsyscg")->base();
		//  membank(20)->set_base(RAM+0xd800);
			membank("bank21")->set_base(ROM);
			logerror("VID: Sub ROM CG selected\n");
			break;
	}
	// reset sub CPU, set busy flag, set reset flag
	m_sub->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
	m_video.sub_busy = 0x80;
	m_video.sub_halt = 0;
	m_video.sub_reset = 1;
	m_sb_prev = data;
}

/*
 *  Sub CPU: ports 0xd410-0xd42b (FM-77AV and later only)
 *  Video operations
 *
 *  0xd410 (R/W): Command register
 *                bit 7: 0=DIS 1=Start
 *                bits 6-5: MBIT1, MBIT2
 *                bits 2-0: Draw mode
 *                  0 0 0 - PSET
 *                  0 1 0 - OR
 *                  0 1 1 - AND
 *                  1 0 0 - XOR
 *                  1 0 1 - NOT
 *                  1 1 0 - TILEPAINT
 *                  1 1 1 - COMPARE
 *  0xd411 (R/W): Logical colour (bits 2-0, G-R-B)
 *  0xd412 (R/W): Mask register
 *  0xd413 (R)  : Compare data (?)
 *  0xd413-1a(W): Compare registers (bits 2-0, G-R-B, 1=mask (bit 7))
 *  0xd41b (R/W): Bank disable register (bits 2-0, G-R-B, 1=disable, bit 3 must always be 1)
 *  0xd41c-1e(W): Tilepaint registers (B-R-G)
 *  0xd420-21(W): Line Address offset register (High-Low, A13-A1)
 *  0xd422-23(W): Line style pattern register (High-Low, P15-P0)
 *  0xd424-25(W): Line X0 (High-Low, X9-X0)
 *  0xd426-27(W): Line Y0 (High-Low, Y8-Y0)
 *  0xd428-29(W): Line X1 (High-Low, X9-X0)
 *  0xd42a-2b(W): Line Y1 (High-Low, Y8-Y0)
 */
READ8_MEMBER(fm7_state::fm77av_alu_r)
{
	switch(offset)
	{
		case 0x00:
			logerror("ALU: read from command register (%02x)\n",m_alu.command);
			return m_alu.command;
		case 0x01:
			logerror("ALU: read from logical colour\n");
			return m_alu.lcolour;
		case 0x02:
			logerror("ALU: read from mask register\n");
			return m_alu.mask;
		case 0x03:
			logerror("ALU: read from compare data register (%02x)\n",m_alu.compare_data);
			return m_alu.compare_data;
		case 0x0b:
			logerror("ALU: read from bank disable register\n");
			return 0xf7 | m_alu.bank_disable;
		default:
			logerror("ALU: read from invalid register 0x%02x\n",offset);
			return 0xff;
	}
}

WRITE8_MEMBER(fm7_state::fm77av_alu_w)
{
	uint16_t dat;

	switch(offset)
	{
		case 0x00:
			m_alu.command = data;
			logerror("ALU: write to command register - %02x\n",data);
			break;
		case 0x01:
			m_alu.lcolour = data & 0x07;
			logerror("ALU: write to logical colour - %02x\n",data);
			break;
		case 0x02:
			m_alu.mask = data;
			logerror("ALU: write to mask register - %02x\n",data);
			break;
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case 0x09:
		case 0x0a:
			m_alu.compare[offset-3] = data;
			logerror("ALU: write to compare register %i - %02x\n",offset-3,data);
			break;
		case 0x0b:
			m_alu.bank_disable = data & 0x03;
//          logerror("ALU: write to bank disable register - %02x\n",data);
			break;
		case 0x0c:
			m_alu.tilepaint_b = data;
//          logerror("ALU: write to tilepaint (blue) register - %02x\n",data);
			break;
		case 0x0d:
			m_alu.tilepaint_r = data;
//          logerror("ALU: write to tilepaint (red) register - %02x\n",data);
			break;
		case 0x0e:
			m_alu.tilepaint_g = data;
//          logerror("ALU: write to tilepaint (green) register - %02x\n",data);
			break;
		case 0x10:
			dat = ((data & 0x1f) << 8) | (m_alu.addr_offset & 0x00ff);
			m_alu.addr_offset = dat;
//          logerror("ALU: write to address offset (high) register - %02x (%04x)\n",data,m_alu.addr_offset);
			break;
		case 0x11:
			dat = (m_alu.addr_offset & 0xff00) | data;
			m_alu.addr_offset = dat;
//          logerror("ALU: write to address offset (low) register - %02x (%04x)\n",data,m_alu.addr_offset);
			break;
		case 0x12:
			dat = (data << 8) | (m_alu.line_style & 0x00ff);
			m_alu.line_style = dat;
//          logerror("ALU: write to line style (high) register - %02x (%04x)\n",data,m_alu.line_style);
			break;
		case 0x13:
			dat = (m_alu.line_style & 0xff00) | data;
			m_alu.line_style = dat;
//          logerror("ALU: write to line style (low) register - %02x (%04x)\n",data,m_alu.line_style);
			break;
		case 0x14:
			dat = ((data & 0x03) << 8) | (m_alu.x0 & 0x00ff);
			m_alu.x0 = dat;
//          logerror("ALU: write to X0 (high) register - %02x (%04x)\n",data,m_alu.x0);
			break;
		case 0x15:
			dat = (m_alu.x0 & 0xff00) | data;
			m_alu.x0 = dat;
//          logerror("ALU: write to X0 (low) register - %02x (%04x)\n",data,m_alu.x0);
			break;
		case 0x16:
			dat = ((data & 0x01) << 8) | (m_alu.y0 & 0x00ff);
			m_alu.y0 = dat;
//          logerror("ALU: write to Y0 (high) register - %02x (%04x)\n",data,m_alu.y0);
			break;
		case 0x17:
			dat = (m_alu.y0 & 0xff00) | data;
			m_alu.y0 = dat;
//          logerror("ALU: write to Y0 (low) register - %02x (%04x)\n",data,m_alu.y0);
			break;
		case 0x18:
			dat = ((data & 0x03) << 8) | (m_alu.x1 & 0x00ff);
			m_alu.x1 = dat;
//          logerror("ALU: write to X1 (high) register - %02x (%04x)\n",data,m_alu.x1);
			break;
		case 0x19:
			dat = (m_alu.x1 & 0xff00) | data;
			m_alu.x1 = dat;
//          logerror("ALU: write to X1 (low) register - %02x (%04x)\n",data,m_alu.x1);
			break;
		case 0x1a:
			dat = ((data & 0x01) << 8) | (m_alu.y1 & 0x00ff);
			m_alu.y1 = dat;
//          logerror("ALU: write to Y1 (high) register - %02x (%04x)\n",data,m_alu.y1);
			break;
		case 0x1b:
			dat = (m_alu.y1 & 0xff00) | data;
			m_alu.y1 = dat;
			// draw line
			fm77av_line_draw();
//          logerror("ALU: write to Y1 (low) register - %02x (%04x)\n",data,m_alu.y1);
			break;
		default:
			logerror("ALU: write 0x%02x to invalid register 0x%02x\n",data,offset);
	}
}

TIMER_CALLBACK_MEMBER(fm7_state::fm77av_vsync)
{
	if(param == 0)  // start of vsync
	{
		m_video.vsync_flag = 1;
		m_fm77av_vsync_timer->adjust(attotime::from_usec(510),1);  // VSync length for 200 line modes = 0.51ms
	}
	else
	{
		m_video.vsync_flag = 0;
		m_fm77av_vsync_timer->adjust(m_screen->time_until_vblank_end());
	}
}

// called when banked into main CPU space by the MMR, available only if sub CPU is halted
READ8_MEMBER(fm7_state::fm7_sub_ram_ports_banked_r)
{
	uint8_t* RAM = memregion("maincpu")->base();
	uint8_t* ROM;

	if(!m_video.sub_halt)
		return 0xff;

	if(offset < 0x380)  // work RAM
		return RAM[0x1d000+offset];
	if(offset >= 0x380 && offset < 0x400) // shared RAM
		return m_shared_ram[offset-0x380];
	if(offset >= 0x500 && offset < 0x800) // work RAM
		return RAM[0x1d000+offset];
	if(offset > 0x800) // CGROM
	{
		ROM = memregion("subsyscg")->base();
		return ROM[(m_video.cgrom*0x800)+(offset-0x800)];
	}

	if(offset >= 0x410 && offset <= 0x42b)
		return fm77av_alu_r(space,offset-0x410);

	switch(offset)
	{
		case 0x400:
		case 0x401:
			return fm7_sub_keyboard_r(space,offset-0x400);
		case 0x402:
			return fm7_cancel_ack(space,0);
		case 0x403:
			return fm7_sub_beeper_r(space,0);
		case 0x404:
			return fm7_attn_irq_r(space,0);
		case 0x408:
			return fm7_crt_r(space,0);
		case 0x409:
			return fm7_vram_access_r(space,0);
		case 0x40a:
			return fm7_sub_busyflag_r(space,0);
		case 0x430:
			return fm77av_video_flags_r(space,0);
		case 0x431:
		case 0x432:
			return fm77av_key_encoder_r(space,offset-0x431);
		default:
			logerror("Unmapped read from sub CPU port 0xd%03x via MMR banking\n",offset);
			return 0xff;
	}
}

WRITE8_MEMBER(fm7_state::fm7_sub_ram_ports_banked_w)
{
	uint8_t* RAM = memregion("maincpu")->base();

	if(!m_video.sub_halt)
		return;

	if(offset < 0x380)  // work RAM
	{
		RAM[0x1d000+offset] = data;
		return;
	}
	if(offset >= 0x380 && offset < 0x400) // shared RAM
	{
		m_shared_ram[offset-0x380] = data;
		return;
	}
	if(offset >= 0x500 && offset < 0x800) // work RAM
	{
		RAM[0x1d000+offset] = data;
		return;
	}

	if(offset >= 0x410 && offset <= 0x42b)
	{
		fm77av_alu_w(space,offset-0x410,data);
		return;
	}

	switch(offset)
	{
		case 0x408:
			fm7_crt_w(space,0,data);
			break;
		case 0x409:
			fm7_vram_access_w(space,0,data);
			break;
		case 0x40a:
			fm7_sub_busyflag_w(space,0,data);
			break;
		case 0x40e:
		case 0x40f:
			fm7_vram_offset_w(space,offset-0x40e,data);
			break;
		case 0x430:
			fm77av_video_flags_w(space,0,data);
			break;
		case 0x431:
		case 0x432:
			fm77av_key_encoder_w(space,offset-0x431,data);
			break;
		default:
			logerror("Unmapped write of 0x%02x to sub CPU port 0xd%03x via MMR banking\n",data,offset);
	}
}

READ8_MEMBER(fm7_state::fm7_console_ram_banked_r)
{
	uint8_t* RAM = memregion("maincpu")->base();

	if(!m_video.sub_halt)
		return 0xff;

	return RAM[0x1c000+offset];
}

WRITE8_MEMBER(fm7_state::fm7_console_ram_banked_w)
{
	uint8_t* RAM = memregion("maincpu")->base();

	if(!m_video.sub_halt)
		return;

	RAM[0x1c000+offset] = data;
}

void fm7_state::video_start()
{
	m_video.vram_access = 0;
	m_video.crt_enable = 0;
	m_video.vram_offset = 0x0000;
	m_video.vram_offset2 = 0x0000;
	m_video.sub_reset = 0;
	m_video.multi_page = 0;
	m_video.subrom = 0;
	m_video.cgrom = 0;
	m_video.fine_offset = 0;
	m_video.nmi_mask = 0;
	m_video.active_video_page = 0;
	m_video.display_video_page = 0;
	m_video.vsync_flag = 0;
}

uint32_t fm7_state::screen_update_fm7(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	uint8_t code_r = 0,code_g = 0,code_b = 0;
	uint8_t code_r2 = 0,code_g2 = 0,code_b2 = 0;
	uint8_t code_r3 = 0,code_g3 = 0,code_b3 = 0;
	uint8_t code_r4 = 0,code_g4 = 0,code_b4 = 0;
	uint16_t col;
	int y, x, b;
	uint16_t page = 0x0000;

	if(m_video.display_video_page != 0)
		page = 0xc000;

	if(m_video.crt_enable == 0)
		return 0;

	if(m_video.modestatus & 0x40)  // 320x200 mode
	{
		for (y = 0; y < 200; y++)
		{
			for (x = 0; x < 40; x++)
			{
				if(!(m_video.multi_page & 0x40))
				{
					code_r = m_video_ram[0x8000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_r2 = m_video_ram[0xa000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_r3 = m_video_ram[0x14000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
					code_r4 = m_video_ram[0x16000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
				}
				if(!(m_video.multi_page & 0x20))
				{
					code_g = m_video_ram[0x4000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_g2 = m_video_ram[0x6000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_g3 = m_video_ram[0x10000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
					code_g4 = m_video_ram[0x12000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
				}
				if(!(m_video.multi_page & 0x10))
				{
					code_b = m_video_ram[0x0000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_b2 = m_video_ram[0x2000 + ((y*40 + x + m_video.vram_offset) & 0x1fff)];
					code_b3 = m_video_ram[0xc000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
					code_b4 = m_video_ram[0xe000 + ((y*40 + x + m_video.vram_offset2) & 0x1fff)];
				}
				for (b = 0; b < 8; b++)
				{
					col = (((code_b >> b) & 0x01) ? 8 : 0) | (((code_b2 >> b) & 0x01) ? 4 : 0) | (((code_b3 >> b) & 0x01) ? 2 : 0) | (((code_b4 >> b) & 0x01) ? 1 : 0);
					col |= (((code_g >> b) & 0x01) ? 128 : 0) | (((code_g2 >> b) & 0x01) ? 64 : 0) | (((code_g3 >> b) & 0x01) ? 32 : 0) | (((code_g4 >> b) & 0x01) ? 16 : 0);
					col |= (((code_r >> b) & 0x01) ? 2048 : 0) | (((code_r2 >> b) & 0x01) ? 1024 : 0) | (((code_r3 >> b) & 0x01) ? 512 : 0) | (((code_r4 >> b) & 0x01) ? 256 : 0);
					bitmap.pix32(y, x*8+(7-b)) = m_av_palette->pen_color(col);
				}
			}
		}
	}
	else
	{
		for (y = 0; y < 200; y++)
		{
			for (x = 0; x < 80; x++)
			{
				if(!(m_video.multi_page & 0x40))
					code_r = m_video_ram[page + 0x8000 + ((y*80 + x + m_video.vram_offset) & 0x3fff)];
				if(!(m_video.multi_page & 0x20))
					code_g = m_video_ram[page + 0x4000 + ((y*80 + x + m_video.vram_offset) & 0x3fff)];
				if(!(m_video.multi_page & 0x10))
					code_b = m_video_ram[page + 0x0000 + ((y*80 + x + m_video.vram_offset) & 0x3fff)];
				for (b = 0; b < 8; b++)
				{
					col = (((code_r >> b) & 0x01) ? 4 : 0) + (((code_g >> b) & 0x01) ? 2 : 0) + (((code_b >> b) & 0x01) ? 1 : 0);
					bitmap.pix32(y, x*8+(7-b)) = m_palette->pen_color(col);
				}
			}
		}
	}
	return 0;
}