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