summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/video/hd44102.cpp
blob: 71e8a0fba132510740e3c88eee5064c1151bdf51 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                               



                                                                             



                                                                       
 


                     





                                                                            






                                        

 



                                                               

 
                         
                                                                                        






                                                                            
                      























                                                                            
                                                                                                               
                                                        
                                                       



                          




                                                   




                                                   





























                                                        
                         











































                                                                                               
                                             




                                               
                                            




                                                
                                                 




                                             
                                               





                                            



















                                                                                                    










                                                   
                                


































                                                   
                                                                                                              






                                            
                                                       
 

                                          
 
                                                      


                                                                                                   
                                                             





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

    HD44102 Dot Matrix Liquid Crystal Graphic Display Column Driver emulation

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

#include "emu.h"
#include "hd44102.h"

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



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

#define CONTROL_DISPLAY_OFF         0x38
#define CONTROL_DISPLAY_ON          0x39
#define CONTROL_COUNT_DOWN_MODE     0x3a
#define CONTROL_COUNT_UP_MODE       0x3b
#define CONTROL_Y_ADDRESS_MASK      0x3f
#define CONTROL_X_ADDRESS_MASK      0xc0
#define CONTROL_DISPLAY_START_PAGE  0x3e


#define STATUS_BUSY                 0x80    /* not supported */
#define STATUS_COUNT_UP             0x40
#define STATUS_DISPLAY_OFF          0x20
#define STATUS_RESET                0x10    /* not supported */


// device type definition
DEFINE_DEVICE_TYPE(HD44102, hd44102_device, "hd44102", "Hitachi HD44102 LCD Controller")


//**************************************************************************
//  INLINE HELPERS
//**************************************************************************

//-------------------------------------------------
//  count_up_or_down -
//-------------------------------------------------

inline void hd44102_device::count_up_or_down()
{
	if (m_status & STATUS_COUNT_UP)
	{
		if (++m_y > 49) m_y = 0;
	}
	else
	{
		if (--m_y < 0) m_y = 49;
	}
}



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

//-------------------------------------------------
//  hd44102_device - constructor
//-------------------------------------------------

hd44102_device::hd44102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, HD44102, tag, owner, clock),
		device_video_interface(mconfig, *this),
		m_cs2(0),
		m_page(0),
		m_x(0),
		m_y(0)
{
}


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

void hd44102_device::device_start()
{
	// register for state saving
	save_item(NAME(m_ram[0]));
	save_item(NAME(m_ram[1]));
	save_item(NAME(m_ram[2]));
	save_item(NAME(m_ram[3]));
	save_item(NAME(m_status));
	save_item(NAME(m_output));
	save_item(NAME(m_cs2));
	save_item(NAME(m_page));
	save_item(NAME(m_x));
	save_item(NAME(m_y));
}


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

void hd44102_device::device_reset()
{
	m_status = STATUS_DISPLAY_OFF | STATUS_COUNT_UP;
}


//-------------------------------------------------
//  read - register read
//-------------------------------------------------

READ8_MEMBER( hd44102_device::read )
{
	uint8_t data = 0;

	if (m_cs2)
	{
		data = (offset & 0x01) ? data_r(space, offset) : status_r(space, offset);
	}

	return data;
}


//-------------------------------------------------
//  write - register write
//-------------------------------------------------

WRITE8_MEMBER( hd44102_device::write )
{
	if (m_cs2)
	{
		(offset & 0x01) ? data_w(space, offset, data) : control_w(space, offset, data);
	}
}


//-------------------------------------------------
//  status_r - status read
//-------------------------------------------------

READ8_MEMBER( hd44102_device::status_r )
{
	return m_status;
}


//-------------------------------------------------
//  control_w - control write
//-------------------------------------------------

WRITE8_MEMBER( hd44102_device::control_w )
{
	if (m_status & STATUS_BUSY) return;

	switch (data)
	{
	case CONTROL_DISPLAY_OFF:
		LOG("HD44102 Display Off\n");

		m_status |= STATUS_DISPLAY_OFF;
		break;

	case CONTROL_DISPLAY_ON:
		LOG("HD44102 Display On\n");

		m_status &= ~STATUS_DISPLAY_OFF;
		break;

	case CONTROL_COUNT_DOWN_MODE:
		LOG("HD44102 Count Down Mode\n");

		m_status &= ~STATUS_COUNT_UP;
		break;

	case CONTROL_COUNT_UP_MODE:
		LOG("HD44102 Count Up Mode\n");

		m_status |= STATUS_COUNT_UP;
		break;

	default:
		{
			const int x = (data & CONTROL_X_ADDRESS_MASK) >> 6;
			const int y = data & CONTROL_Y_ADDRESS_MASK;

			if ((data & CONTROL_Y_ADDRESS_MASK) == CONTROL_DISPLAY_START_PAGE)
			{
				LOG("HD44102 Display Start Page %u\n", x);

				m_page = x;
			}
			else if (y > 49)
			{
				logerror("HD44102 Invalid Address X %u Y %u (%02x)!\n", data, x, y);
			}
			else
			{
				LOG("HD44102 Address X %u Y %u (%02x)\n", data, x, y);

				m_x = x;
				m_y = y;
			}
		}
	}
}


//-------------------------------------------------
//  data_r - data read
//-------------------------------------------------

READ8_MEMBER( hd44102_device::data_r )
{
	uint8_t data = m_output;

	m_output = m_ram[m_x][m_y];

	count_up_or_down();

	return data;
}


//-------------------------------------------------
//  data_w - data write
//-------------------------------------------------

WRITE8_MEMBER( hd44102_device::data_w )
{
	m_ram[m_x][m_y] = data;

	count_up_or_down();
}


//-------------------------------------------------
//  cs2_w - chip select 2 write
//-------------------------------------------------

WRITE_LINE_MEMBER( hd44102_device::cs2_w )
{
	m_cs2 = state;
}


//-------------------------------------------------
//  update_screen - update screen
//-------------------------------------------------

uint32_t hd44102_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	for (int y = 0; y < 50; y++)
	{
		int z = m_page << 3;

		for (int x = 0; x < 32; x++)
		{
			uint8_t data = m_ram[z / 8][y];

			int sy = m_sy + z;
			int sx = m_sx + y;

			if (cliprect.contains(sx, sy))
			{
				int color = (m_status & STATUS_DISPLAY_OFF) ? 0 : BIT(data, z % 8);

				bitmap.pix16(sy, sx) = color;
			}

			z++;
			z %= 32;
		}
	}
	return 0;
}