mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
199 lines
4.3 KiB
C++
199 lines
4.3 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:hap
|
|
/*
|
|
|
|
Hughes HLCD 0515 family LCD Driver
|
|
|
|
0515: 25 columns(also size of buffer/ram)
|
|
0569: 24 columns, no DATA OUT pin, display blank has no effect
|
|
0530: specifications unknown, pinout seems similar to 0569
|
|
|
|
TODO:
|
|
- read mode is untested
|
|
- MAME bitmap update callback when needed
|
|
|
|
*/
|
|
|
|
#include "emu.h"
|
|
#include "video/hlcd0515.h"
|
|
|
|
|
|
DEFINE_DEVICE_TYPE(HLCD0515, hlcd0515_device, "hlcd0515", "Hughes HLCD 0515 LCD Driver")
|
|
DEFINE_DEVICE_TYPE(HLCD0569, hlcd0569_device, "hlcd0569", "Hughes HLCD 0569 LCD Driver")
|
|
DEFINE_DEVICE_TYPE(HLCD0530, hlcd0530_device, "hlcd0530", "Hughes HLCD 0530 LCD Driver")
|
|
|
|
//-------------------------------------------------
|
|
// constructor
|
|
//-------------------------------------------------
|
|
|
|
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 colmax) :
|
|
device_t(mconfig, type, tag, owner, clock),
|
|
m_colmax(colmax),
|
|
m_write_cols(*this), m_write_data(*this)
|
|
{ }
|
|
|
|
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
|
hlcd0515_device(mconfig, HLCD0515, tag, owner, clock, 25)
|
|
{ }
|
|
|
|
hlcd0569_device::hlcd0569_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
|
hlcd0515_device(mconfig, HLCD0569, tag, owner, clock, 24)
|
|
{ }
|
|
|
|
hlcd0530_device::hlcd0530_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
|
hlcd0515_device(mconfig, HLCD0530, tag, owner, clock, 24)
|
|
{ }
|
|
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_start - device-specific startup
|
|
//-------------------------------------------------
|
|
|
|
void hlcd0515_device::device_start()
|
|
{
|
|
// resolve callbacks
|
|
m_write_cols.resolve_safe();
|
|
m_write_data.resolve_safe();
|
|
|
|
// timer
|
|
m_lcd_timer = timer_alloc();
|
|
m_lcd_timer->adjust(attotime::from_hz(clock() / 2), 0, attotime::from_hz(clock() / 2));
|
|
|
|
// zerofill
|
|
m_cs = 0;
|
|
m_clk = 0;
|
|
m_data = 0;
|
|
m_count = 0;
|
|
m_control = 0;
|
|
m_blank = false;
|
|
m_rowmax = 0;
|
|
m_rowout = 0;
|
|
m_rowsel = 0;
|
|
m_buffer = 0;
|
|
memset(m_ram, 0, sizeof(m_ram));
|
|
|
|
// register for savestates
|
|
save_item(NAME(m_cs));
|
|
save_item(NAME(m_clk));
|
|
save_item(NAME(m_data));
|
|
save_item(NAME(m_count));
|
|
save_item(NAME(m_control));
|
|
save_item(NAME(m_blank));
|
|
save_item(NAME(m_rowmax));
|
|
save_item(NAME(m_rowout));
|
|
save_item(NAME(m_rowsel));
|
|
save_item(NAME(m_buffer));
|
|
save_item(NAME(m_ram));
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_timer - handler timer events
|
|
//-------------------------------------------------
|
|
|
|
void hlcd0515_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
|
{
|
|
if (m_rowout > m_rowmax)
|
|
m_rowout = 0;
|
|
|
|
// write to COL/ROW pins
|
|
m_write_cols(m_rowout, m_blank ? 0 : m_ram[m_rowout], ~0);
|
|
m_rowout++;
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------
|
|
// handlers
|
|
//-------------------------------------------------
|
|
|
|
void hlcd0515_device::set_control()
|
|
{
|
|
// clock 0,1,2: row select
|
|
m_rowsel = m_control >> 2 & 7;
|
|
|
|
// clock 3(,4): initialize
|
|
if (m_control & 2)
|
|
{
|
|
m_rowmax = m_rowsel;
|
|
m_blank = bool(~m_control & 1);
|
|
}
|
|
|
|
// clock 4: read/write mode
|
|
m_buffer = (m_control & 1) ? m_ram[m_rowsel] : 0;
|
|
}
|
|
|
|
void hlcd0569_device::set_control()
|
|
{
|
|
hlcd0515_device::set_control();
|
|
m_blank = false; // 0569 doesn't support display blanking
|
|
}
|
|
|
|
|
|
void hlcd0515_device::clock_data(int col)
|
|
{
|
|
if (m_control & 1)
|
|
{
|
|
if (col < m_colmax)
|
|
m_buffer <<= 1;
|
|
|
|
m_write_data(m_buffer >> m_colmax & 1);
|
|
}
|
|
else
|
|
{
|
|
if (col < m_colmax)
|
|
m_buffer >>= 1;
|
|
|
|
// always write last column
|
|
u32 mask = 1 << (m_colmax - 1);
|
|
m_buffer = (m_buffer & ~mask) | (m_data ? mask : 0);
|
|
}
|
|
}
|
|
|
|
|
|
WRITE_LINE_MEMBER(hlcd0515_device::clock_w)
|
|
{
|
|
state = (state) ? 1 : 0;
|
|
|
|
// clock/shift data on falling edge
|
|
if (!m_cs && !state && m_clk)
|
|
{
|
|
if (m_count < 5)
|
|
{
|
|
// 5-bit mode/control
|
|
m_control = m_control << 1 | m_data;
|
|
if (m_count == 4)
|
|
set_control();
|
|
}
|
|
|
|
else
|
|
clock_data(m_count - 5);
|
|
|
|
if (m_count < (m_colmax + 5))
|
|
m_count++;
|
|
}
|
|
|
|
m_clk = state;
|
|
}
|
|
|
|
|
|
WRITE_LINE_MEMBER(hlcd0515_device::cs_w)
|
|
{
|
|
state = (state) ? 1 : 0;
|
|
|
|
// finish serial sequence on rising edge
|
|
if (state && !m_cs)
|
|
{
|
|
// transfer to ram
|
|
if (~m_control & 1)
|
|
m_ram[m_rowsel] = m_buffer;
|
|
|
|
m_count = 0;
|
|
m_control = 0;
|
|
}
|
|
|
|
m_cs = state;
|
|
}
|