1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// license:BSD-3-Clause
// copyright-holders:hap
/*
Hitachi HD61603 LCD Driver
64 segment outputs, no duty cycle
TODO:
- OSC pin (input is resistor)
- SB pin, halts internal clock
- SYNC pin for chip cascading
- READY pin
*/
#include "emu.h"
#include "video/hd61603.h"
DEFINE_DEVICE_TYPE(HD61603, hd61603_device, "hd61603", "Hitachi HD61603 LCD Driver")
//-------------------------------------------------
// constructor
//-------------------------------------------------
hd61603_device::hd61603_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, HD61603, tag, owner, clock),
m_write_segs(*this)
{ }
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void hd61603_device::device_start()
{
// resolve callbacks
m_write_segs.resolve_safe();
// zerofill
m_blank = 0;
m_count = 0;
m_data = 0;
m_ram = 0;
// register for savestates
save_item(NAME(m_blank));
save_item(NAME(m_count));
save_item(NAME(m_data));
save_item(NAME(m_ram));
}
void hd61603_device::device_reset()
{
m_count = 0;
}
//-------------------------------------------------
// handlers
//-------------------------------------------------
void hd61603_device::data_w(u8 data)
{
// 1-byte nop command
if (m_count == 0 && (data & 0xc) == 0xc)
return;
// each command is 4 writes
m_data = (m_data << 4) | (data & 0xf);
m_count = (m_count + 1) & 3;
if (m_count == 0)
{
switch (m_data >> 14 & 3)
{
// write byte
case 0:
{
u8 shift = (m_data >> 8 & 7) * 8;
u8 digit = bitswap<8>(m_data & 0xff, 0,1,2,3,4,5,6,7);
m_ram = (m_ram & ~(u64(0xff) << shift)) | u64(digit) << shift;
break;
}
// write bit
case 1:
{
u64 mask = u64(1) << (m_data & 0x3f);
m_ram = (m_ram & ~mask) | ((m_data & 0x2000) ? mask : 0);
break;
}
// set mode
case 2:
m_blank = BIT(m_data, 2);
break;
default:
break;
}
m_write_segs(0, m_blank ? 0 : m_ram);
}
}
|