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

                               



                                                                       

                                                                       
                

                             
                   
 


                     




                                                                            
            


                                   


                







                                  

 




                                                                            
                                                                                         

 

                                                     
                                                                                                                   



                                                     

                                                                                                                  



                                                      








                                                                              




                                                      





                                                                              




                                                      




                                                                                       






                                                      






                                                   


                                                                                                                               



                                                                                                                     


                                                                                                                           

                                      
                                                                                                                                                               






                                                   
                                                                     
 




                                                   
          

                                                   
                                                                                        




















                                   
 

          

                                          
 


                                                                    
                                                        
 
                  
                                             
 

                                                           
                                                         
 


                                                                                       
                                                                 
 

                                                          
                                                                                        
 
                                                                              
 





                                           



                                                                  
                                                   
                                                 

                                                   

                                                                     
                                                  
 


                                                                                              
 
                                                               
 



                                                     

                                                                                            
 

 
                                                                            
               


                                                                            


                                                   
                                                                                                                             
                                                            
                                                
                                                                                                                                 
                                 



                                    






















































                                                   
                                                                                              
 
                                    

                                                  



                                                   


                                                   
                                                                  
 
                                                                  






                                                   
                                                                                             
 
                                                  
 
                                                                                                          






                                                   
                                                 
 
                                                     
                         


                          
                                                  


            
                                                









                                                   
                                                  
 
                                                     






                                                        
                                                                  




                                                          
                                                                    



                                                             
                                                                                      






                                                             
                                                                  




                                                               
                                                                    



                                                             
                                                                                      







                                                   
                                             


          
                               
 







                             
 
          
 
                         











                                                               
               

                                                   
                                                
 
          
 
                               
 







                          
 
          
 
                                                                      
 



                                                          
 
 


                                                   
 


                                                
 
                               
 







                          
 
          
 
                                                                      
 

                                           
 
 


                                                   
 


                                                
 
                               
 







                           
 
          
 
                                                                      
 

                                                          
 
 


                                                   
 


                                                
 
                               
 







                          
 
          
 
                                                                      
 

                                           
 
 


                                                   
 


                                                
 
                               
 







                              
 
          
 
                                                                      
 


                                                         
 
 


                                                   
 


                                                
 
                               
 







                              
 
          
 
                                                                      
 


                                                
 
 




















                                                   
                                                                      
 

                        


                                                         



                                                   
               

                                                   
                                                
 














                               
                                                                      
 

                        








                                                   
 


                                                
 
                               
 







                                
 
          
 
                                                                      
 


                                                          
 
 


                                                   
 


                                                
 
                               
 







                                
 
          
 
                                                                      
 


                                                
 
 


                                                   
 


                                                
 
                               
 







                         
 
          
 
                                                                      
 

                                                         
 
 


                                                   
 


                                                
 
                               
 







                         
 
          
 
                                                                      
 
                                                
 

                
 
 


                                                   
 


                                             
 
                               
 










                                                                 
                                                          



                                                  




                                                   
            

                                                   
                                             
 
          
 











                                                                 
 
                                                          





                                                  
 
 


                                                   
 





                                                         
                                              




                                                     
                                             

         
 
 


                                                   
 





                                                         
                                              




                                                
                                             



         





                                                      
                               

























                                                    
                                   









                                                   
                        


 








                                                                            
                                               
 

                                     














                                                   
                                               
 

                                     














                                                   
                                               
 

                                     











                                                   
                                               
 

                                     











                                                   
                                              
 

                                     








                                                   
                                              
 

                                    








                                                   
                                               


                        
                                       










                                                   
                                                 
 

                                                            













                                                   
                                                 

                                                  
                                    











                                                   
                                             


          
                               
 








                          
 
          
 

                                                                                      









                                                   
                                                 


          
                               
 




                          
 
          
 
                                                           
                                       






                                                   
                                                 


          
                               
 











                               
 
          
 
                                                                                                                                                          
                                                






                                                   
                                                                 
 
                            















                                                   
                                                              
 

                                                                    















                                                   
                                  
 
                                                                                                                                                                   

















                                                   

                                                             








                                        



                                                             



















                                                          
                                                                                                                    
 

                     
                                                                 



                                                                
                                                      



                 
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Luxor ABC 1600 Mover emulation

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

#include "emu.h"
#include "includes/abc1600.h"
#include "abc1600.lh"
#include "render.h"

//#define VERBOSE 1
#include "logmacro.h"


//**************************************************************************
//  CONSTANTS / MACROS
//**************************************************************************

// video RAM
#define VIDEORAM_SIZE       0x40000
#define VIDEORAM16_MASK     0x3ffff
#define VIDEORAM8_MASK      0x7fffe


// flag register
#define L_P         BIT(m_flag, 0)
#define BLANK       BIT(m_flag, 1)
#define PIX_POL     BIT(m_flag, 2)
#define FRAME_POL   BIT(m_flag, 3)
#define HOLD_FY     BIT(m_flag, 4)
#define HOLD_FX     BIT(m_flag, 5)
#define COMP_MOVE   BIT(m_flag, 6)
#define REPLACE     BIT(m_flag, 7)



//**************************************************************************
//  DEVICE DEFINITIONS
//**************************************************************************

DEFINE_DEVICE_TYPE(ABC1600_MOVER, abc1600_mover_device, "abc1600mover", "ABC 1600 Mover")


void abc1600_mover_device::vram_map(address_map &map)
{
	map(0x00000, 0x7ffff).rw(FUNC(abc1600_mover_device::video_ram_r), FUNC(abc1600_mover_device::video_ram_w));
}

void abc1600_mover_device::crtc_map(address_map &map)
{
	map(0x00, 0x00).mirror(0xfe).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w));
	map(0x01, 0x01).mirror(0xfe).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
}

void abc1600_mover_device::iowr0_map(address_map &map)
{
	map(0x00, 0x00).mirror(0xff).r(FUNC(abc1600_mover_device::iord0_r));
	map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsx_hb_w));
	map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsx_lb_w));
	map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsy_hb_w));
	map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::ldsy_lb_w));
	map(0x04, 0x04).mirror(0xf8).w(FUNC(abc1600_mover_device::ldtx_hb_w));
	map(0x05, 0x05).mirror(0xf8).w(FUNC(abc1600_mover_device::ldtx_lb_w));
	map(0x06, 0x06).mirror(0xf8).w(FUNC(abc1600_mover_device::ldty_hb_w));
	map(0x07, 0x07).mirror(0xf8).w(FUNC(abc1600_mover_device::ldty_lb_w));
}

void abc1600_mover_device::iowr1_map(address_map &map)
{
	map(0x00, 0x00).mirror(0xff).nopr();
	map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfx_hb_w));
	map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfx_lb_w));
	map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfy_hb_w));
	map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::ldfy_lb_w));
	map(0x05, 0x05).mirror(0xf8).w(FUNC(abc1600_mover_device::wrml_w));
	map(0x07, 0x07).mirror(0xf8).w(FUNC(abc1600_mover_device::wrdl_w));
}

void abc1600_mover_device::iowr2_map(address_map &map)
{
	map(0x00, 0x00).mirror(0xff).nopr();
	map(0x00, 0x00).mirror(0xf8).w(FUNC(abc1600_mover_device::wrmask_strobe_hb_w));
	map(0x01, 0x01).mirror(0xf8).w(FUNC(abc1600_mover_device::wrmask_strobe_lb_w));
	map(0x02, 0x02).mirror(0xf8).w(FUNC(abc1600_mover_device::enable_clocks_w));
	map(0x03, 0x03).mirror(0xf8).w(FUNC(abc1600_mover_device::flag_strobe_w));
	map(0x04, 0x04).mirror(0xf8).w(FUNC(abc1600_mover_device::endisp_w));
}


void abc1600_mover_device::mover_map(address_map &map)
{
	map(0x00000, 0x3ffff).ram();
}


//-------------------------------------------------
//  ROM( abc1600_mover )
//-------------------------------------------------

ROM_START( abc1600_mover )
	ROM_REGION16_BE( 0x2000, "wrmsk", 0 )
	ROM_LOAD16_BYTE( "wrmskl 6490362-01.1g", 0x0001, 0x1000, CRC(bc737538) SHA1(80e2c3757eb7f713018808d6e41ebef612425028) )
	ROM_LOAD16_BYTE( "wrmskh 6490363-01.1j", 0x0000, 0x1000, CRC(6b7c9f0b) SHA1(7155a993adcf08a5a8a2f22becf9fd66fda698be) )

	ROM_REGION( 0x200, "shinf", 0 )
	ROM_LOAD( "shinf 6490361-01.1f", 0x000, 0x200, CRC(20260f8f) SHA1(29bf49c64e7cc7592e88cde2768ac57c7ce5e085) )

	ROM_REGION16_BE( 0x40, "drmsk", 0 )
	ROM_LOAD16_BYTE( "drmskl 6490359-01.1k", 0x01, 0x20, CRC(6e71087c) SHA1(0acf67700d6227f4b315cf8fb0fb31c0e7fb9496) )
	ROM_LOAD16_BYTE( "drmskh 6490358-01.1l", 0x00, 0x20, CRC(a4a9a9dc) SHA1(d8575c0335d6021cbb5f7bcd298b41c35294a80a) )

	ROM_REGION( 0x104, "plds", 0 )
	ROM_LOAD( "drmsk 6490360-01.1m", 0x000, 0x104, CRC(5f7143c1) SHA1(1129917845f8e505998b15288f02bf907487e4ac) ) // PAL16L8 mover word mixer @ 1m,1n,1t,2t
ROM_END


//-------------------------------------------------
//  rom_region - device-specific ROM region
//-------------------------------------------------

const tiny_rom_entry *abc1600_mover_device::device_rom_region() const
{
	return ROM_NAME( abc1600_mover );
}


//-------------------------------------------------
//  mc6845
//-------------------------------------------------

inline uint16_t abc1600_mover_device::get_crtca(uint16_t ma, uint8_t ra, uint8_t column)
{
	/*

	    bit         description

	    CRTCA0      0
	    CRTCA1      0
	    CRTCA2      CC1/MA1
	    CRTCA3      CC2/MA2
	    CRTCA4      CC3/MA3
	    CRTCA5      CC4/MA4
	    CRTCA6      RA0
	    CRTCA7      RA1
	    CRTCA8      RA2
	    CRTCA9      RA3
	    CRTCA10     CR0/MA8
	    CRTCA11     CR1/MA9
	    CRTCA12     CR2/MA10
	    CRTCA13     CR3/MA11
	    CRTCA14     CR4/MA12
	    CRTCA15     CR5/MA13

	*/

	uint8_t cc = (ma & 0xff) + column;
	uint8_t cr = ma >> 8;

	return (cr << 10) | ((ra & 0x0f) << 6) | ((cc << 1) & 0x3c);
}

MC6845_UPDATE_ROW(abc1600_mover_device::crtc_update_row)
{
	int x = 0;
	const pen_t *pen = m_palette->pens();

	for (int column = 0; column < x_count; column += 2)
	{
		uint16_t dma = get_crtca(ma, ra, column);

		// data is read out of video RAM in nibble mode by strobing CAS 4 times
		for (int cas = 0; cas < 4; cas++)
		{
			uint16_t data = read_videoram(dma + cas);

			for (int bit = 0; bit < 16; bit++)
			{
				int color = ((BIT(data, 15) ^ PIX_POL) && !BLANK) && de;

				bitmap.pix32(vbp + y, hbp + x++) = pen[color];

				data <<= 1;
			}
		}
	}
}

MC6845_ON_UPDATE_ADDR_CHANGED( abc1600_mover_device::crtc_update )
{
}

//-------------------------------------------------
//  device_add_mconfig - add device configuration
//-------------------------------------------------

void abc1600_mover_device::device_add_mconfig(machine_config &config)
{
	config.set_default_layout(layout_abc1600);

	screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER, rgb_t::green()));
	screen.set_screen_update(FUNC(abc1600_mover_device::screen_update));
	screen.set_raw(XTAL(64'000'000), 0x3e0, 0, 0x300, 0x433, 0, 0x400);

	PALETTE(config, m_palette, palette_device::MONOCHROME);

	SY6845E(config, m_crtc, XTAL(64'000'000)/32);
	m_crtc->set_screen(SCREEN_TAG);
	m_crtc->set_show_border_area(true);
	m_crtc->set_char_width(32);
	m_crtc->set_update_row_callback(FUNC(abc1600_mover_device::crtc_update_row));
	m_crtc->set_on_update_addr_change_callback(FUNC(abc1600_mover_device::crtc_update));
}


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  abc1600_mover_device - constructor
//-------------------------------------------------

abc1600_mover_device::abc1600_mover_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
	device_t(mconfig, ABC1600_MOVER, tag, owner, clock),
	device_memory_interface(mconfig, *this),
	m_space_config("vram", ENDIANNESS_BIG, 16, 18, -1, address_map_constructor(FUNC(abc1600_mover_device::mover_map), this)),
	m_crtc(*this, "sy6845e"),
	m_palette(*this, "palette"),
	m_wrmsk_rom(*this, "wrmsk"),
	m_shinf_rom(*this, "shinf"),
	m_drmsk_rom(*this, "drmsk")
{
}


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

void abc1600_mover_device::device_start()
{
	// state saving
	save_item(NAME(m_endisp));
	save_item(NAME(m_clocks_disabled));
	save_item(NAME(m_gmdi));
	save_item(NAME(m_wrm));
	save_item(NAME(m_ms));
	save_item(NAME(m_ds));
	save_item(NAME(m_flag));
	save_item(NAME(m_xsize));
	save_item(NAME(m_ysize));
	save_item(NAME(m_udx));
	save_item(NAME(m_udy));
	save_item(NAME(m_xfrom));
	save_item(NAME(m_xto));
	save_item(NAME(m_yto));
	save_item(NAME(m_ty));
	save_item(NAME(m_mfa));
	save_item(NAME(m_mta));
	save_item(NAME(m_sh));
	save_item(NAME(m_mdor));
	save_item(NAME(m_hold_1w_cyk));
	save_item(NAME(m_wrms0));
	save_item(NAME(m_wrms1));
	save_item(NAME(m_rmc));
	save_item(NAME(m_cmc));
}


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

void abc1600_mover_device::device_reset()
{
	// disable display
	m_clocks_disabled = 1;
	m_endisp = 0;
}


//-------------------------------------------------
//  memory_space_config - return a description of
//  any address spaces owned by this device
//-------------------------------------------------

device_memory_interface::space_config_vector abc1600_mover_device::memory_space_config() const
{
	return space_config_vector {
		std::make_pair(0, &m_space_config)
	};
}


//-------------------------------------------------
//  read_videoram -
//-------------------------------------------------

inline uint16_t abc1600_mover_device::read_videoram(offs_t offset)
{
	return space().read_word((offset & VIDEORAM16_MASK) << 1);
}


//-------------------------------------------------
//  write_videoram -
//-------------------------------------------------

inline void abc1600_mover_device::write_videoram(offs_t offset, uint16_t data, uint16_t mask)
{
	uint16_t old_data = read_videoram(offset);

	space().write_word((offset & VIDEORAM16_MASK) << 1, (data & mask) | (old_data & (mask ^ 0xffff)));
}


//-------------------------------------------------
//  video_ram_r -
//-------------------------------------------------

READ8_MEMBER( abc1600_mover_device::video_ram_r )
{
	offs_t addr = (offset & VIDEORAM8_MASK) >> 1;
	uint8_t data = 0;

	if (offset & 0x01)
	{
		data = read_videoram(addr) & 0xff;
	}
	else
	{
		data = read_videoram(addr) >> 8;
	}

	return data;
}


//-------------------------------------------------
//  video_ram_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::video_ram_w )
{
	offs_t addr = (offset & VIDEORAM8_MASK) >> 1;

	if (offset & 0x01)
	{
		if (REPLACE)
		{
			// WRPORT_LB
			m_wrm = (m_wrm & 0xff00) | data;
			LOG("WRM LB %02x -> %04x\n", data, m_wrm);
		}
		else
		{
			// DATAPORT_LB
			m_gmdi = (m_gmdi & 0xff00) | data;
			LOG("GMDI LB %02x -> %04x\n", data, m_gmdi);
		}

		write_videoram(addr, m_gmdi, m_wrm & 0x00ff);

		LOG("Video RAM write LB to %05x : %04x\n", addr, read_videoram(addr));
	}
	else
	{
		if (REPLACE)
		{
			// WRPORT_HB
			m_wrm = (data << 8) | (m_wrm & 0xff);
			LOG("WRM HB %02x -> %04x\n", data, m_wrm);
		}
		else
		{
			// DATAPORT_HB
			m_gmdi = (data << 8) | (m_gmdi & 0xff);
			LOG("GMDI HB %02x -> %04x\n", data, m_gmdi);
		}

		write_videoram(addr, m_gmdi, m_wrm & 0xff00);

		LOG("Video RAM write HB to %05x : %04x\n", addr, read_videoram(addr));
	}
}


//-------------------------------------------------
//  iord0_r -
//-------------------------------------------------

READ8_MEMBER( abc1600_mover_device::iord0_r )
{
	/*

	    bit     description

	    0       0
	    1       SCREENPOS
	    2
	    3
	    4
	    5
	    6       VSYNC
	    7       BUSY

	*/

	uint8_t data = 0;

	// monitor orientation (portrait/landscape)
	data |= machine().render().first_target()->view() << 1;

	// vertical sync
	data |= m_crtc->vsync_r() << 6;

	return data;
}


//-------------------------------------------------
//  ldsx_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldsx_hb_w )
{
	/*

	    bit     description

	    0       XSIZE8
	    1       XSIZE9
	    2       U/D* Y
	    3       U/D* X
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDSX HB: %02x\n", machine().describe_context(), data);

	m_xsize = ((data & 0x03) << 8) | (m_xsize & 0xff);
	m_udy = BIT(data, 2);
	m_udx = BIT(data, 3);
}


//-------------------------------------------------
//  ldsx_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldsx_lb_w )
{
	/*

	    bit     description

	    0       XSIZE0
	    1       XSIZE1
	    2       XSIZE2
	    3       XSIZE3
	    4       XSIZE4
	    5       XSIZE5
	    6       XSIZE6
	    7       XSIZE7

	*/

	LOG("%s LDSX LB: %02x\n", machine().describe_context(), data);

	m_xsize = (m_xsize & 0x300) | data;
}


//-------------------------------------------------
//  ldsy_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldsy_hb_w )
{
	/*

	    bit     description

	    0       YSIZE8
	    1       YSIZE9
	    2       YSIZE10
	    3       YSIZE11
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDSY HB: %02x\n", machine().describe_context(), data);

	m_ysize = ((data & 0x0f) << 8) | (m_ysize & 0xff);
}


//-------------------------------------------------
//  ldsy_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldsy_lb_w )
{
	/*

	    bit     description

	    0       YSIZE0
	    1       YSIZE1
	    2       YSIZE2
	    3       YSIZE3
	    4       YSIZE4
	    5       YSIZE5
	    6       YSIZE6
	    7       YSIZE7

	*/

	LOG("%s LDSY LB: %02x\n", machine().describe_context(), data);

	m_ysize = (m_ysize & 0xf00) | data;
}


//-------------------------------------------------
//  ldtx_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldtx_hb_w )
{
	/*

	    bit     description

	    0       XTO8, MTA4
	    1       XTO9, MTA5
	    2
	    3
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDTX HB: %02x\n", machine().describe_context(), data);

	m_xto = ((data & 0x03) << 8) | (m_xto & 0xff);
	m_mta = (m_mta & 0x3ffcf) | ((data & 0x03) << 4);
}


//-------------------------------------------------
//  ldtx_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldtx_lb_w )
{
	/*

	    bit     description

	    0       XTO0
	    1       XTO1
	    2       XTO2
	    3       XTO3
	    4       XTO4, MTA0
	    5       XTO5, MTA1
	    6       XTO6, MTA2
	    7       XTO7, MTA3

	*/

	LOG("%s LDTX LB: %02x\n", machine().describe_context(), data);

	m_xto = (m_xto & 0x300) | data;
	m_mta = (m_mta & 0x3fff0) | (data >> 4);
}


//-------------------------------------------------
//  ldty_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldty_hb_w )
{
	/*

	    bit     description

	    0       YTO8, MTA14
	    1       YTO9, MTA15
	    2       YTO10, MTA16
	    3       YTO11, MTA17
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDTY HB: %02x\n", machine().describe_context(), data);

	if (L_P) return;

	m_ty = ((data & 0x0f) << 8) | (m_yto & 0xff);
	m_yto = ((data & 0x0f) << 8) | (m_yto & 0xff);
	m_mta = ((data & 0x0f) << 14) | (m_mta & 0x3fff);
}


//-------------------------------------------------
//  ldty_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldty_lb_w )
{
	/*

	    bit     description

	    0       YTO0, MTA6
	    1       YTO1, MTA7
	    2       YTO2, MTA8
	    3       YTO3, MTA9
	    4       YTO4, MTA10
	    5       YTO5, MTA11
	    6       YTO6, MTA12
	    7       YTO7, MTA13

	*/

	LOG("%s LDTY LB: %02x\n", machine().describe_context(), data);

	if (L_P) return;

	m_ty = (m_ty & 0xf00) | data;
	m_yto = (m_yto & 0xf00) | data;
	m_mta = (m_mta & 0x3c03f) | (data << 6);
}


//-------------------------------------------------
//  ldfx_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldfx_hb_w )
{
	/*

	    bit     description

	    0       XFROM8, MFA4
	    1       XFROM9, MFA5
	    2
	    3
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDFX HB: %02x\n", machine().describe_context(), data);

	m_xfrom = ((data & 0x03) << 8) | (m_xfrom & 0xff);
	m_mfa = (m_mfa & 0x3ffcf) | ((data & 0x03) << 4);
}


//-------------------------------------------------
//  ldfx_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldfx_lb_w )
{
	/*

	    bit     description

	    0       XFROM0
	    1       XFROM1
	    2       XFROM2
	    3       XFROM3
	    4       XFROM4, MFA0
	    5       XFROM5, MFA1
	    6       XFROM6, MFA2
	    7       XFROM7, MFA3

	*/

	LOG("%s LDFX LB: %02x\n", machine().describe_context(), data);

	m_xfrom = (m_xfrom & 0x300) | data;
	m_mfa = (m_mfa & 0x3fff0) | (data >> 4);
}


//-------------------------------------------------
//  ldfy_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldfy_hb_w )
{
	/*

	    bit     description

	    0       MFA14
	    1       MFA15
	    2       MFA16
	    3       MFA17
	    4
	    5
	    6
	    7

	*/

	LOG("%s LDFY HB: %02x\n", machine().describe_context(), data);

	m_mfa = ((data & 0x0f) << 14) | (m_mfa & 0x3fff);
}


//-------------------------------------------------
//  ldfy_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::ldfy_lb_w )
{
	/*

	    bit     description

	    0       MFA6
	    1       MFA7
	    2       MFA8
	    3       MFA9
	    4       MFA10
	    5       MFA11
	    6       MFA12
	    7       MFA13

	*/

	LOG("%s LDFY LB: %02x\n", machine().describe_context(), data);

	m_mfa = (m_mfa & 0x3c03f) | (data << 6);

	mover();
}


//-------------------------------------------------
//  wrml_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::wrml_w )
{
	/*

	    bit     description

	    0       MOVE CYK CLK
	    1       DISP CYC SEL / DISP CYK PRE FETCH (+1 PIXCLK)
	    2       DATA CLK
	    3       _DISP MEM WE
	    4       _CAS HB
	    5       DTACK CLK / BLANK TEST (+2 PIXCLK)
	    6       DISPREC CLK
	    7       _RAS HB

	*/

	LOG("MS %u : %02x\n", (offset >> 4) & 0x0f, data);

	if (m_clocks_disabled)
	{
		m_ms[(offset >> 4) & 0x0f] = data;
	}
}


//-------------------------------------------------
//  wrdl_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::wrdl_w )
{
	/*

	    bit     description

	    0       MOVE CYK CLK
	    1       DISP CYC SEL / DISP CYK PRE FETCH (+1 PIXCLK)
	    2       DATA CLK
	    3       _DISP MEM WE
	    4       _CAS HB
	    5       DTACK CLK / BLANK TEST (+2 PIXCLK)
	    6       DISPREC CLK
	    7       _RAS HB

	*/

	LOG("WS %u : %02x\n", (offset >> 4) & 0x0f, data);

	if (m_clocks_disabled)
	{
		m_ds[(offset >> 4) & 0x0f] = data;
	}
}


//-------------------------------------------------
//  wrmask_strobe_hb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::wrmask_strobe_hb_w )
{
	if (REPLACE)
	{
		// DATAPORT_HB
		m_gmdi = (data << 8) | (m_gmdi & 0xff);
		LOG("GMDI HB %04x\n", m_gmdi);
	}
	else
	{
		// WRPORT_HB
		m_wrm = (data << 8) | (m_wrm & 0xff);
		LOG("WRM HB %04x\n", m_gmdi);
	}
}


//-------------------------------------------------
//  wrmask_strobe_lb_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::wrmask_strobe_lb_w )
{
	if (REPLACE)
	{
		// DATAPORT_LB
		m_gmdi = (m_gmdi & 0xff00) | data;
		LOG("GMDI LB %04x\n", m_gmdi);
	}
	else
	{
		// WRPORT_LB
		m_wrm = (m_wrm & 0xff00) | data;
		LOG("WRM LB %04x\n", m_gmdi);
	}
}


//-------------------------------------------------
//  enable_clocks_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::enable_clocks_w )
{
	LOG("ENABLE CLOCKS\n");
	m_clocks_disabled = 0;
}


//-------------------------------------------------
//  flag_strobe_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::flag_strobe_w )
{
	/*

	    bit     description

	    0       L/_P FLAG
	    1       BLANK FLAG
	    2       PIX POL
	    3       FRAME POL
	    4       HOLD FY
	    5       HOLD FX
	    6       COMP MOVE FLAG
	    7       REPLACE/SET & RESET

	*/

	m_flag = data;
	LOG("FLAG %02x\n", m_flag);
}


//-------------------------------------------------
//  endisp_w -
//-------------------------------------------------

WRITE8_MEMBER( abc1600_mover_device::endisp_w )
{
	m_endisp = 1;
	LOG("ENDISP\n");
}



//**************************************************************************
//  MOVER
//**************************************************************************

//-------------------------------------------------
//  clock_mfa_x -
//-------------------------------------------------

inline void abc1600_mover_device::clock_mfa_x()
{
	uint16_t mfa_y = m_mfa >> 6;
	uint8_t mfa_x = m_mfa & 0x3f;

	if (!HOLD_FX)
	{
		mfa_x += m_udx ? 1 : -1;
		mfa_x &= 0x3f;
	}

	m_mfa = (mfa_y << 6) | mfa_x;
}


//-------------------------------------------------
//  clock_mfa_y -
//-------------------------------------------------

inline void abc1600_mover_device::clock_mfa_y()
{
	uint16_t mfa_y = m_mfa >> 6;
	uint8_t mfa_x = m_mfa & 0x3f;

	if (!HOLD_FY)
	{
		mfa_y += m_udy ? 1 : -1;
		mfa_y &= 0xfff;
	}

	m_mfa = (mfa_y << 6) | mfa_x;
}


//-------------------------------------------------
//  clock_mta_x -
//-------------------------------------------------

inline void abc1600_mover_device::clock_mta_x()
{
	uint16_t mta_y = m_mta >> 6;
	uint8_t mta_x = m_mta & 0x3f;

	mta_x += m_udx ? 1 : -1;
	mta_x &= 0x3f;

	m_mta = (mta_y << 6) | mta_x;
}


//-------------------------------------------------
//  clock_mta_y -
//-------------------------------------------------

inline void abc1600_mover_device::clock_mta_y()
{
	uint16_t mta_y = m_mta >> 6;
	uint8_t mta_x = m_mta & 0x3f;

	mta_y += m_udy ? 1 : -1;
	mta_y &= 0xfff;

	m_mta = (mta_y << 6) | mta_x;
}


//-------------------------------------------------
//  load_mfa_x -
//-------------------------------------------------

inline void abc1600_mover_device::load_mfa_x()
{
	uint16_t mfa_y = m_mfa >> 6;
	uint8_t mfa_x = m_xfrom >> 4;

	m_mfa = (mfa_y << 6) | mfa_x;
}


//-------------------------------------------------
//  load_mta_x -
//-------------------------------------------------

inline void abc1600_mover_device::load_mta_x()
{
	uint16_t mta_y = m_mta >> 6;
	uint8_t mta_x = m_xto >> 4;

	m_mta = (mta_y << 6) | mta_x;
}


//-------------------------------------------------
//  load_xy_reg -
//-------------------------------------------------

inline void abc1600_mover_device::load_xy_reg()
{
	if (L_P) return;

	uint16_t sum = m_xto + m_xsize;

	m_xto = sum & 0x3ff;
	m_yto = m_ty & 0xfff;
	m_mta = (m_ty << 6) | (sum >> 4);
}


//-------------------------------------------------
//  compare_mta_x -
//-------------------------------------------------

inline void abc1600_mover_device::compare_mta_x()
{
	uint8_t mta_x_end = ((m_xto + m_xsize) >> 4) & 0x3f;
	uint8_t mta_x = m_mta & 0x3f;

	if (mta_x == mta_x_end)
	{
		m_cmc = 0;
	}

	m_wrms1 = m_cmc & m_amm;
}


//-------------------------------------------------
//  compare_mta_y -
//-------------------------------------------------

inline void abc1600_mover_device::compare_mta_y()
{
	int mta_y_end = (m_yto + m_ysize) & 0xfff;
	uint16_t mta_y = m_mta >> 6;

	if (mta_y == mta_y_end)
	{
		m_rmc = 0;
	}
}


//-------------------------------------------------
//  get_shinf -
//-------------------------------------------------

inline void abc1600_mover_device::get_shinf()
{
	/*

	    bit     description

	    A0      XFROM0
	    A1      XFROM1
	    A2      XFROM2
	    A3      XFROM3
	    A4      XTO0
	    A5      XTO1
	    A6      XTO2
	    A7      XTO3
	    A8      U/D* X

	*/

	uint16_t shinf_addr = (m_udx << 8) | ((m_xto & 0x0f) << 4) | (m_xfrom & 0x0f);
	uint8_t shinf = m_shinf_rom[shinf_addr];

	m_sh = shinf & 0x0f;
	m_hold_1w_cyk = BIT(shinf, 5);
}


//-------------------------------------------------
//  get_drmsk -
//-------------------------------------------------

inline uint16_t abc1600_mover_device::get_drmsk()
{
	/*

	    bit     description

	    A0      SH0
	    A1      SH1
	    A2      SH2
	    A3      SH3
	    A4      U/D* X

	*/

	uint16_t drmsk_addr = (m_udx << 4) | (m_sh & 0x0f);
	return m_drmsk_rom[drmsk_addr];
}


//-------------------------------------------------
//  get_wrmsk - get mover write mask
//-------------------------------------------------

inline uint16_t abc1600_mover_device::get_wrmsk()
{
	/*

	    bit     description

	    A0      XTO0
	    A1      XTO1
	    A2      XTO2
	    A3      XTO3
	    A4      XSIZE0
	    A5      XSIZE1
	    A6      XSIZE2
	    A7      XSIZE3
	    A8      U/D* X
	    A9      ANDED MASKS
	    A10     WRMS0
	    A11     WRMS1

	*/

	uint16_t wrmsk_addr = (m_wrms1 << 11) | (m_wrms0 << 10) | ((!m_wrms1 && !m_wrms0) << 9) | (m_udx << 8) | ((m_xsize & 0x0f) << 4) | (m_xto & 0x0f);
	return m_wrmsk_rom[wrmsk_addr] ^ 0xffff;
}


//-------------------------------------------------
//  barrel_shift -
//-------------------------------------------------

inline uint16_t abc1600_mover_device::barrel_shift(uint16_t gmdr)
{
	uint16_t rot = gmdr;

	for (int sh = 0; sh < m_sh; sh++)
	{
		int msb = BIT(rot, 15);
		rot <<= 1;
		rot |= msb;
	}

	return rot;
}


//-------------------------------------------------
//  word_mixer -
//-------------------------------------------------

inline uint16_t abc1600_mover_device::word_mixer(uint16_t rot)
{
	uint16_t drmsk = get_drmsk();
	uint16_t gmdi = (rot & drmsk) | (m_mdor & (drmsk ^ 0xffff));

	if (COMP_MOVE)
	{
		gmdi ^= 0xffff;
	}

	m_mdor = rot;

	return gmdi;
}


//-------------------------------------------------
//  mover -
//-------------------------------------------------

void abc1600_mover_device::mover()
{
	LOG("XFROM %u XSIZE %u YSIZE %u XTO %u YTO %u MFA %05x MTA %05x U/D*X %u U/D*Y %u\n", m_xfrom, m_xsize, m_ysize, m_xto, m_yto, m_mfa, m_mta, m_udx, m_udy);

	m_amm = 1;

	m_rmc = 1;
	get_shinf();

	do
	{
		compare_mta_y();

		load_mfa_x();
		load_mta_x();
		m_cmc = 1;
		m_wrms0 = 0;

		if (m_hold_1w_cyk)
		{
			// read one word in advance
			uint16_t gmdr = read_videoram(m_mfa);
			uint16_t rot = barrel_shift(gmdr);
			word_mixer(rot);

			clock_mfa_x();
		}

		do
		{
			compare_mta_x();

			uint16_t gmdr = read_videoram(m_mfa);
			uint16_t rot = barrel_shift(gmdr);
			uint16_t gmdi = word_mixer(rot);
			uint16_t mask = get_wrmsk();

			write_videoram(m_mta, gmdi, mask);

			clock_mfa_x();
			clock_mta_x();

			m_wrms0 = 1;
		}
		while (m_cmc);

		clock_mfa_y();
		clock_mta_y();
	}
	while (m_rmc);

	load_xy_reg();

	m_amm = 0;
}

uint32_t abc1600_mover_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	if (m_endisp)
	{
		bitmap.fill(m_palette->pen(FRAME_POL), cliprect);
		m_crtc->screen_update(screen, bitmap, cliprect);
	}
	else
	{
		bitmap.fill(rgb_t::black(), cliprect);
	}

	return 0;
}