1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 /*
4
5 Hughes HLCD 0438 LCD Driver
6 32 segment outputs, may also be used as a column driver
7
8 LCD pin can be driven manually, or oscillating.
9
10 */
11
12 #include "emu.h"
13 #include "video/hlcd0438.h"
14
15
16 DEFINE_DEVICE_TYPE(HLCD0438, hlcd0438_device, "hlcd0438", "Hughes HLCD 0438 LCD Driver")
17
18 //-------------------------------------------------
19 // constructor
20 //-------------------------------------------------
21
hlcd0438_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)22 hlcd0438_device::hlcd0438_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
23 device_t(mconfig, HLCD0438, tag, owner, clock),
24 m_write_segs(*this), m_write_data(*this)
25 { }
26
27
28 //-------------------------------------------------
29 // device_start - device-specific startup
30 //-------------------------------------------------
31
device_start()32 void hlcd0438_device::device_start()
33 {
34 // resolve callbacks
35 m_write_segs.resolve_safe();
36 m_write_data.resolve_safe();
37
38 // timer (when LCD pin is oscillator)
39 m_lcd_timer = timer_alloc();
40 attotime period = (clock() != 0) ? attotime::from_hz(2 * clock()) : attotime::never;
41 m_lcd_timer->adjust(period, 0, period);
42
43 // register for savestates
44 save_item(NAME(m_data_in));
45 save_item(NAME(m_data_out));
46 save_item(NAME(m_clk));
47 save_item(NAME(m_load));
48 save_item(NAME(m_lcd));
49 save_item(NAME(m_shift));
50 save_item(NAME(m_latch));
51 }
52
53
54 //-------------------------------------------------
55 // handlers
56 //-------------------------------------------------
57
clock_w(int state)58 void hlcd0438_device::clock_w(int state)
59 {
60 state = state ? 1 : 0;
61
62 // shift on falling edge
63 if (m_clk && !state)
64 {
65 // DATA OUT pin follows carry out
66 m_data_out = BIT(m_shift, 31);
67
68 m_shift = m_shift << 1 | m_data_in;
69
70 m_write_data(m_data_out);
71 load_w(m_load);
72 }
73
74 m_clk = state;
75 }
76
load_w(int state)77 void hlcd0438_device::load_w(int state)
78 {
79 m_load = state ? 1 : 0;
80
81 // load to output latches while LOAD pin is high
82 if (m_load)
83 m_latch = m_shift;
84 }
85
lcd_w(int state)86 void hlcd0438_device::lcd_w(int state)
87 {
88 state = state ? 1 : 0;
89
90 // LCD pin drives backplate
91 if (state != m_lcd)
92 m_write_segs(m_lcd, m_latch);
93
94 m_lcd = state;
95 }
96