1 // license:BSD-3-Clause
2 // copyright-holders:Dirk Best
3 /***************************************************************************
4 
5     Thomson EF9369
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 #include "ef9369.h"
11 
12 #include <algorithm>
13 
14 /*static*/ constexpr int ef9369_device::NUMCOLORS;
15 
16 //**************************************************************************
17 //  DEVICE DEFINITIONS
18 //**************************************************************************
19 
20 DEFINE_DEVICE_TYPE(EF9369, ef9369_device, "ef9369", "Thomson EF9369 Single Chip Color Palette")
21 
22 
23 //**************************************************************************
24 //  LIVE DEVICE
25 //**************************************************************************
26 
27 //-------------------------------------------------
28 //  ef9369_device - constructor
29 //-------------------------------------------------
30 
ef9369_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)31 ef9369_device::ef9369_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
32 	: device_t(mconfig, EF9369, tag, owner, clock)
33 	, m_color_update_cb(*this)
34 	, m_address(0)
35 {
36 	std::fill(m_ca, m_ca + NUMCOLORS, 0);
37 	std::fill(m_cb, m_cb + NUMCOLORS, 0);
38 	std::fill(m_cc, m_cc + NUMCOLORS, 0);
39 	std::fill(m_m, m_m + NUMCOLORS, 0);
40 }
41 
42 //-------------------------------------------------
43 //  device_start - device-specific startup
44 //-------------------------------------------------
45 
device_start()46 void ef9369_device::device_start()
47 {
48 	// bind delegate
49 	m_color_update_cb.resolve();
50 
51 	// register for save states
52 	save_pointer(NAME(m_ca), NUMCOLORS);
53 	save_pointer(NAME(m_cb), NUMCOLORS);
54 	save_pointer(NAME(m_cc), NUMCOLORS);
55 	save_pointer(NAME(m_m), NUMCOLORS);
56 	save_item(NAME(m_address));
57 }
58 
59 //-------------------------------------------------
60 //  device_reset - device-specific reset
61 //-------------------------------------------------
62 
device_reset()63 void ef9369_device::device_reset()
64 {
65 	m_address = 0;
66 }
67 
68 
69 //**************************************************************************
70 //  IMPLEMENTATION
71 //**************************************************************************
72 
data_r()73 uint8_t ef9369_device::data_r()
74 {
75 	if (m_address & 1)
76 		return m_m[m_address >> 1] << 4 | m_cc[m_address >> 1];
77 	else
78 		return m_cb[m_address >> 1] << 4 | m_ca[m_address >> 1];
79 }
80 
data_w(uint8_t data)81 void ef9369_device::data_w(uint8_t data)
82 {
83 	const int entry = m_address >> 1;
84 
85 	if (m_address & 1)
86 	{
87 		m_m[entry] = (data >> 4) & 0x1;
88 		m_cc[entry] = (data >> 0) & 0xf;
89 	}
90 	else
91 	{
92 		m_cb[entry] = (data >> 4) & 0xf;
93 		m_ca[entry] = (data >> 0) & 0xf;
94 	}
95 
96 	// update color
97 	if (!m_color_update_cb.isnull())
98 		m_color_update_cb(entry, m_m[entry], m_ca[entry], m_cb[entry], m_cc[entry]);
99 
100 	// auto-increment
101 	m_address++;
102 	m_address &= 0x1f;
103 }
104 
address_w(uint8_t data)105 void ef9369_device::address_w(uint8_t data)
106 {
107 	m_address = data & 0x1f;    // 5-bit
108 }
109