summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/lc7580.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/lc7580.cpp')
-rw-r--r--src/devices/video/lc7580.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/devices/video/lc7580.cpp b/src/devices/video/lc7580.cpp
new file mode 100644
index 00000000000..19868db4409
--- /dev/null
+++ b/src/devices/video/lc7580.cpp
@@ -0,0 +1,159 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+Sanyo LC7580 LCD Driver
+
+53 outputs (static), or 104 outputs (1/2 duty)
+
+TODO:
+- any difference between LC7580 and LC7582?
+- OSC pin (input is R/C)
+- AD/DSP function
+
+*/
+
+#include "emu.h"
+#include "lc7580.h"
+
+#include <tuple>
+
+
+DEFINE_DEVICE_TYPE(LC7580, lc7580_device, "lc7580", "Sanyo LC7580 LCD Driver")
+DEFINE_DEVICE_TYPE(LC7582, lc7582_device, "lc7582", "Sanyo LC7582 LCD Driver")
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+lc7580_device::lc7580_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ device_nvram_interface(mconfig, *this),
+ m_write_segs(*this)
+{
+ // disable nvram by default
+ nvram_enable_backup(false);
+}
+
+lc7580_device::lc7580_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ lc7580_device(mconfig, LC7580, tag, owner, clock)
+{ }
+
+lc7582_device::lc7582_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ lc7580_device(mconfig, LC7582, tag, owner, clock)
+{ }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void lc7580_device::device_start()
+{
+ // zerofill
+ m_data = 0;
+ m_ce = 0;
+ m_clk = 0;
+ m_blank = false;
+ m_shift = 0;
+ std::fill_n(m_latch, std::size(m_latch), 0);
+
+ // register for savestates
+ save_item(NAME(m_data));
+ save_item(NAME(m_ce));
+ save_item(NAME(m_clk));
+ save_item(NAME(m_blank));
+ save_item(NAME(m_shift));
+ save_item(NAME(m_latch));
+}
+
+
+//-------------------------------------------------
+// nvram (when VDD is battery-backed)
+//-------------------------------------------------
+
+bool lc7580_device::nvram_write(util::write_stream &file)
+{
+ std::error_condition err;
+ size_t actual;
+
+ std::tie(err, actual) = write(file, &m_shift, sizeof(m_shift));
+ if (err)
+ return false;
+ std::tie(err, actual) = write(file, &m_latch, sizeof(m_latch));
+ if (err)
+ return false;
+
+ return true;
+}
+
+bool lc7580_device::nvram_read(util::read_stream &file)
+{
+ std::error_condition err;
+ size_t actual;
+
+ std::tie(err, actual) = read(file, &m_shift, sizeof(m_shift));
+ if (err || (sizeof(m_shift) != actual))
+ return false;
+ std::tie(err, actual) = read(file, &m_latch, sizeof(m_latch));
+ if (err || (sizeof(m_latch) != actual))
+ return false;
+
+ return true;
+}
+
+
+//-------------------------------------------------
+// handlers
+//-------------------------------------------------
+
+void lc7580_device::refresh_output()
+{
+ if (BIT(m_latch[0], 53))
+ {
+ // 1/2 duty
+ u64 segs[2] = { 0, 0 };
+
+ // COM1 on even bits, COM2 on uneven bits
+ for (int i = 0; i < 104; i++)
+ segs[i & 1] |= BIT(m_latch[i / 52], i % 52) << (i >> 1);
+
+ for (int i = 0; i < 2; i++)
+ m_write_segs(i, m_blank ? 0 : segs[i]);
+ }
+ else
+ {
+ // 1/1 duty
+ m_write_segs(0, m_blank ? 0 : m_latch[0] & ((1ULL << 53) - 1));
+ m_write_segs(1, 0);
+ }
+}
+
+void lc7580_device::clk_w(int state)
+{
+ state = (state) ? 1 : 0;
+
+ // clock shift register
+ if (state && !m_clk)
+ m_shift = m_shift >> 1 | u64(m_data) << 55;
+
+ m_clk = state;
+}
+
+void lc7580_device::ce_w(int state)
+{
+ state = (state) ? 1 : 0;
+
+ // latch at falling edge
+ if (!state && m_ce)
+ {
+ // d0-d52: segment data
+ // d53(0): DP (drive mode select, aka duty)
+ // d54(0): DQ (AD/DSP function)
+ // d55: latch select
+ m_latch[BIT(m_shift, 55)] = m_shift;
+ refresh_output();
+ }
+
+ m_ce = state;
+}