1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont
3 /*********************************************************************
4 
5     ezcgi.c
6 
7     "E-Z Color Graphics Interface" by Steve Ciarcia
8     from BYTE Magazine, August, 1982
9     https://archive.org/details/byte-magazine-1982-08-rescan
10 
11 *********************************************************************/
12 
13 #include "emu.h"
14 #include "ezcgi.h"
15 
16 
17 /***************************************************************************
18     PARAMETERS
19 ***************************************************************************/
20 
21 #define TMS_TAG "ezcgi_tms"
22 #define SCREEN_TAG "screen"
23 
24 //**************************************************************************
25 //  GLOBAL VARIABLES
26 //**************************************************************************
27 
28 DEFINE_DEVICE_TYPE(A2BUS_EZCGI,      a2bus_ezcgi_device,      "a2ezcgi",  "E-Z Color Graphics Interface")
29 DEFINE_DEVICE_TYPE(A2BUS_EZCGI_9938, a2bus_ezcgi_9938_device, "a2ezcgi3", "E-Z Color Graphics Interface (TMS9938)")
30 DEFINE_DEVICE_TYPE(A2BUS_EZCGI_9958, a2bus_ezcgi_9958_device, "a2ezcgi5", "E-Z Color Graphics Interface (TMS9958)")
31 
32 #define MSX2_XBORDER_PIXELS     16
33 #define MSX2_YBORDER_PIXELS     28
34 #define MSX2_TOTAL_XRES_PIXELS      256 * 2 + (MSX2_XBORDER_PIXELS * 2)
35 #define MSX2_TOTAL_YRES_PIXELS      212 * 2 + (MSX2_YBORDER_PIXELS * 2)
36 #define MSX2_VISIBLE_XBORDER_PIXELS 8 * 2
37 #define MSX2_VISIBLE_YBORDER_PIXELS 14 * 2
38 
39 //-------------------------------------------------
40 //  device_add_mconfig - add device configuration
41 //-------------------------------------------------
42 
device_add_mconfig(machine_config & config)43 void a2bus_ezcgi_device::device_add_mconfig(machine_config &config)
44 {
45 	TMS9918A(config, m_tms, XTAL(10'738'635)).set_screen(SCREEN_TAG);
46 	m_tms->set_vram_size(0x4000); // 16k of VRAM
47 	m_tms->int_callback().set(FUNC(a2bus_ezcgi_device::tms_irq_w));
48 	SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER);
49 }
50 
device_add_mconfig(machine_config & config)51 void a2bus_ezcgi_9938_device::device_add_mconfig(machine_config &config)
52 {
53 	V9938(config, m_tms, XTAL(21'477'272));    // typical 9938 clock, not verified
54 	m_tms->set_vram_size(0x30000);    // 192K of VRAM
55 	m_tms->set_screen(SCREEN_TAG);
56 	m_tms->int_cb().set(FUNC(a2bus_ezcgi_9938_device::tms_irq_w));
57 
58 	screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER));
59 	screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
60 	screen.set_refresh_hz(60);
61 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
62 	screen.set_size(MSX2_TOTAL_XRES_PIXELS, 262*2);
63 	screen.set_visarea(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1);
64 }
65 
device_add_mconfig(machine_config & config)66 void a2bus_ezcgi_9958_device::device_add_mconfig(machine_config &config)
67 {
68 	V9958(config, m_tms, XTAL(21'477'272));    // typical 9938/9958 clock, not verified
69 	m_tms->set_vram_size(0x30000);    // 192K of VRAM
70 	m_tms->set_screen(SCREEN_TAG);
71 	m_tms->int_cb().set(FUNC(a2bus_ezcgi_9958_device::tms_irq_w));
72 
73 	screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER));
74 	screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
75 	screen.set_refresh_hz(60);
76 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
77 	screen.set_size(MSX2_TOTAL_XRES_PIXELS, 262*2);
78 	screen.set_visarea(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1);
79 }
80 
81 //**************************************************************************
82 //  LIVE DEVICE
83 //**************************************************************************
84 
a2bus_ezcgi_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)85 a2bus_ezcgi_device::a2bus_ezcgi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
86 	a2bus_ezcgi_device(mconfig, A2BUS_EZCGI, tag, owner, clock)
87 {
88 }
89 
a2bus_ezcgi_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)90 a2bus_ezcgi_device::a2bus_ezcgi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
91 	device_t(mconfig, type, tag, owner, clock),
92 	device_a2bus_card_interface(mconfig, *this),
93 	m_tms(*this, TMS_TAG)
94 {
95 }
96 
a2bus_ezcgi_9938_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)97 a2bus_ezcgi_9938_device::a2bus_ezcgi_9938_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
98 	a2bus_ezcgi_9938_device(mconfig, A2BUS_EZCGI_9938, tag, owner, clock)
99 {
100 }
101 
a2bus_ezcgi_9938_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)102 a2bus_ezcgi_9938_device::a2bus_ezcgi_9938_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
103 	device_t(mconfig, type, tag, owner, clock),
104 	device_a2bus_card_interface(mconfig, *this),
105 	m_tms(*this, TMS_TAG)
106 {
107 }
108 
a2bus_ezcgi_9958_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)109 a2bus_ezcgi_9958_device::a2bus_ezcgi_9958_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
110 	a2bus_ezcgi_9958_device(mconfig, A2BUS_EZCGI_9958, tag, owner, clock)
111 {
112 }
113 
a2bus_ezcgi_9958_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)114 a2bus_ezcgi_9958_device::a2bus_ezcgi_9958_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
115 	device_t(mconfig, type, tag, owner, clock),
116 	device_a2bus_card_interface(mconfig, *this),
117 	m_tms(*this, TMS_TAG)
118 {
119 }
120 
121 //-------------------------------------------------
122 //  device_start - device-specific startup
123 //-------------------------------------------------
124 
device_start()125 void a2bus_ezcgi_device::device_start()
126 {
127 }
128 
device_reset()129 void a2bus_ezcgi_device::device_reset()
130 {
131 }
132 
device_start()133 void a2bus_ezcgi_9938_device::device_start()
134 {
135 }
136 
device_reset()137 void a2bus_ezcgi_9938_device::device_reset()
138 {
139 }
140 
device_start()141 void a2bus_ezcgi_9958_device::device_start()
142 {
143 }
144 
device_reset()145 void a2bus_ezcgi_9958_device::device_reset()
146 {
147 }
148 
149 /*
150     C0nx map:
151     0 - TMS read
152     1 - TMS write
153 */
154 
read_c0nx(uint8_t offset)155 uint8_t a2bus_ezcgi_device::read_c0nx(uint8_t offset)
156 {
157 	switch (offset)
158 	{
159 		case 0:
160 			return m_tms->vram_read();
161 
162 		case 1:
163 			return m_tms->register_read();
164 	}
165 
166 	return 0xff;
167 }
168 
write_c0nx(uint8_t offset,uint8_t data)169 void a2bus_ezcgi_device::write_c0nx(uint8_t offset, uint8_t data)
170 {
171 	switch (offset)
172 	{
173 		case 0:
174 			m_tms->vram_write(data);
175 			break;
176 
177 		case 1:
178 			m_tms->register_write(data);
179 			break;
180 	}
181 }
182 
read_c0nx(uint8_t offset)183 uint8_t a2bus_ezcgi_9938_device::read_c0nx(uint8_t offset)
184 {
185 	switch (offset)
186 	{
187 		case 0:
188 			return m_tms->vram_r();
189 
190 		case 1:
191 			return m_tms->status_r();
192 	}
193 
194 	return 0xff;
195 }
196 
write_c0nx(uint8_t offset,uint8_t data)197 void a2bus_ezcgi_9938_device::write_c0nx(uint8_t offset, uint8_t data)
198 {
199 	switch (offset)
200 	{
201 		case 0:
202 			m_tms->vram_w(data);
203 			break;
204 
205 		case 1:
206 			m_tms->command_w(data);
207 			break;
208 
209 		case 2:
210 			m_tms->palette_w(data);
211 			break;
212 
213 		case 3:
214 			m_tms->register_w(data);
215 			break;
216 	}
217 }
218 
read_c0nx(uint8_t offset)219 uint8_t a2bus_ezcgi_9958_device::read_c0nx(uint8_t offset)
220 {
221 	switch (offset)
222 	{
223 		case 0:
224 			return m_tms->vram_r();
225 
226 		case 1:
227 			return m_tms->status_r();
228 	}
229 
230 	return 0xff;
231 }
232 
write_c0nx(uint8_t offset,uint8_t data)233 void a2bus_ezcgi_9958_device::write_c0nx(uint8_t offset, uint8_t data)
234 {
235 	switch (offset)
236 	{
237 		case 0:
238 			m_tms->vram_w(data);
239 			break;
240 
241 		case 1:
242 			m_tms->command_w(data);
243 			break;
244 
245 		case 2:
246 			m_tms->palette_w(data);
247 			break;
248 
249 		case 3:
250 			m_tms->register_w(data);
251 			break;
252 	}
253 }
254 
WRITE_LINE_MEMBER(a2bus_ezcgi_device::tms_irq_w)255 WRITE_LINE_MEMBER( a2bus_ezcgi_device::tms_irq_w )
256 {
257 	if (state)
258 	{
259 		raise_slot_irq();
260 	}
261 	else
262 	{
263 		lower_slot_irq();
264 	}
265 }
266 
WRITE_LINE_MEMBER(a2bus_ezcgi_9938_device::tms_irq_w)267 WRITE_LINE_MEMBER( a2bus_ezcgi_9938_device::tms_irq_w )
268 {
269 	if (state)
270 	{
271 		raise_slot_irq();
272 	}
273 	else
274 	{
275 		lower_slot_irq();
276 	}
277 }
278 
WRITE_LINE_MEMBER(a2bus_ezcgi_9958_device::tms_irq_w)279 WRITE_LINE_MEMBER( a2bus_ezcgi_9958_device::tms_irq_w )
280 {
281 	if (state)
282 	{
283 		raise_slot_irq();
284 	}
285 	else
286 	{
287 		lower_slot_irq();
288 	}
289 }
290