1 // license:GPL-2.0+
2 // copyright-holders:Dirk Best, Carl
3 /***************************************************************************
4 
5     Siemens PC-D
6 
7     For PC-X HDD should have 306,4,9 chs at 1024Bps or 18 at 512Bps
8 
9 ***************************************************************************/
10 
11 #include "emu.h"
12 #include "machine/pcd_kbd.h"
13 #include "video/pcd.h"
14 
15 #include "bus/rs232/rs232.h"
16 #include "bus/scsi/omti5100.h"
17 #include "cpu/i86/i186.h"
18 #include "imagedev/floppy.h"
19 #include "machine/mc146818.h"
20 #include "machine/nvram.h"
21 #include "machine/pic8259.h"
22 #include "machine/scn_pci.h"
23 #include "machine/ram.h"
24 #include "machine/timer.h"
25 #include "machine/wd_fdc.h"
26 #include "sound/spkrdev.h"
27 
28 #include "speaker.h"
29 
30 #include "formats/pc_dsk.h"
31 
32 
33 //**************************************************************************
34 //  TYPE DEFINITIONS
35 //**************************************************************************
36 
37 class pcd_state : public driver_device
38 {
39 public:
pcd_state(const machine_config & mconfig,device_type type,const char * tag)40 	pcd_state(const machine_config &mconfig, device_type type, const char *tag)
41 		: driver_device(mconfig, type, tag)
42 		, m_maincpu(*this, "maincpu")
43 		, m_pic1(*this, "pic1")
44 		, m_pic2(*this, "pic2")
45 		, m_speaker(*this, "speaker")
46 		, m_fdc(*this, "fdc")
47 		, m_rtc(*this, "rtc")
48 		, m_usart(*this, "usart%u", 1U)
49 		, m_scsi(*this, "scsi")
50 		, m_scsi_data_out(*this, "scsi_data_out")
51 		, m_scsi_data_in(*this, "scsi_data_in")
52 		, m_ram(*this, "ram")
53 	{ }
54 
55 	void pcx(machine_config &config);
56 	void pcd(machine_config &config);
57 
58 private:
59 	uint8_t irq_callback(offs_t offset);
60 	TIMER_DEVICE_CALLBACK_MEMBER( timer0_tick );
61 	DECLARE_WRITE_LINE_MEMBER( i186_timer1_w );
62 
63 	uint8_t nmi_io_r(address_space &space, offs_t offset);
64 	void nmi_io_w(address_space &space, offs_t offset, uint8_t data);
65 	uint8_t stat_r();
66 	void stat_w(uint8_t data);
67 	uint8_t led_r();
68 	void led_w(uint8_t data);
69 	uint16_t dskctl_r();
70 	void dskctl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
71 
72 	uint8_t scsi_r(offs_t offset);
73 	void scsi_w(offs_t offset, uint8_t data);
74 	uint16_t mmu_r(offs_t offset);
75 	void mmu_w(offs_t offset, uint16_t data);
76 	uint16_t mem_r(address_space &space, offs_t offset);
77 	void mem_w(address_space &space, offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
78 
79 	DECLARE_FLOPPY_FORMATS( floppy_formats );
80 	DECLARE_WRITE_LINE_MEMBER(write_scsi_bsy);
81 	DECLARE_WRITE_LINE_MEMBER(write_scsi_cd);
82 	DECLARE_WRITE_LINE_MEMBER(write_scsi_io);
83 	DECLARE_WRITE_LINE_MEMBER(write_scsi_msg);
84 	DECLARE_WRITE_LINE_MEMBER(write_scsi_req);
85 
86 	void pcd_io(address_map &map);
87 	void pcd_map(address_map &map);
88 	void pcx_io(address_map &map);
89 
90 	// driver_device overrides
91 	virtual void machine_start() override;
92 	virtual void machine_reset() override;
93 
94 	required_device<i80186_cpu_device> m_maincpu;
95 	required_device<pic8259_device> m_pic1;
96 	required_device<pic8259_device> m_pic2;
97 	required_device<speaker_sound_device> m_speaker;
98 	required_device<wd2793_device> m_fdc;
99 	required_device<mc146818_device> m_rtc;
100 	required_device_array<scn2661b_device, 3> m_usart;
101 	required_device<scsi_port_device> m_scsi;
102 	required_device<output_latch_device> m_scsi_data_out;
103 	required_device<input_buffer_device> m_scsi_data_in;
104 	required_device<ram_device> m_ram;
105 	uint8_t m_stat, m_led;
106 	int m_msg, m_bsy, m_io, m_cd, m_req, m_rst;
107 	uint16_t m_dskctl;
108 	struct {
109 		uint16_t ctl;
110 		uint16_t regs[1024];
111 		int type;
112 		bool sc;
113 	} m_mmu;
114 
115 	void check_scsi_irq();
116 };
117 
118 
119 //**************************************************************************
120 //  MACHINE EMULATION
121 //**************************************************************************
122 
machine_start()123 void pcd_state::machine_start()
124 {
125 	save_item(NAME(m_mmu.ctl));
126 	save_item(NAME(m_mmu.regs));
127 }
128 
machine_reset()129 void pcd_state::machine_reset()
130 {
131 	m_stat = 0;
132 	m_led = 0;
133 	m_dskctl = 0;
134 	m_rst = 0;
135 	m_mmu.ctl = 0;
136 	m_mmu.sc = false;
137 	if(ioport("mmu"))
138 		m_mmu.type = ioport("mmu")->read();
139 	else
140 		m_mmu.type = 0;
141 }
142 
irq_callback(offs_t offset)143 uint8_t pcd_state::irq_callback(offs_t offset)
144 {
145 	return (offset ? m_pic2 : m_pic1)->acknowledge();
146 }
147 
TIMER_DEVICE_CALLBACK_MEMBER(pcd_state::timer0_tick)148 TIMER_DEVICE_CALLBACK_MEMBER( pcd_state::timer0_tick )
149 {
150 	m_maincpu->tmrin0_w(0);
151 	m_maincpu->tmrin0_w(1);
152 }
153 
WRITE_LINE_MEMBER(pcd_state::i186_timer1_w)154 WRITE_LINE_MEMBER( pcd_state::i186_timer1_w )
155 {
156 	if(m_dskctl & 0x20)
157 		m_speaker->level_w(state);
158 }
159 
nmi_io_r(address_space & space,offs_t offset)160 uint8_t pcd_state::nmi_io_r(address_space &space, offs_t offset)
161 {
162 	if(machine().side_effects_disabled())
163 		return 0;
164 	logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset);
165 	m_stat |= 0xfd;
166 	m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
167 	return 0;
168 }
169 
nmi_io_w(address_space & space,offs_t offset,uint8_t data)170 void pcd_state::nmi_io_w(address_space &space, offs_t offset, uint8_t data)
171 {
172 	if(machine().side_effects_disabled())
173 		return;
174 	logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset);
175 	m_stat |= 0xfd;
176 	m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
177 }
178 
stat_r()179 uint8_t pcd_state::stat_r()
180 {
181 	return m_stat;
182 }
183 
stat_w(uint8_t data)184 void pcd_state::stat_w(uint8_t data)
185 {
186 	m_stat &= ~data;
187 }
188 
dskctl_r()189 uint16_t pcd_state::dskctl_r()
190 {
191 	return m_dskctl;
192 }
193 
dskctl_w(offs_t offset,uint16_t data,uint16_t mem_mask)194 void pcd_state::dskctl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
195 {
196 	floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
197 	floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
198 
199 	COMBINE_DATA(&m_dskctl);
200 
201 	if((m_dskctl & 1) && floppy0)
202 		m_fdc->set_floppy(floppy0);
203 	if((m_dskctl & 2) && floppy1)
204 		m_fdc->set_floppy(floppy1);
205 
206 	if(floppy0)
207 	{
208 		floppy0->mon_w(!(m_dskctl & 4));
209 		floppy0->ss_w((m_dskctl & 8) != 0);
210 	}
211 	if(floppy1)
212 	{
213 		floppy1->mon_w(!(m_dskctl & 4));
214 		floppy1->ss_w((m_dskctl & 8) != 0);
215 	}
216 	m_fdc->dden_w((m_dskctl & 0x10) ? 1 : 0);
217 }
218 
led_r()219 uint8_t pcd_state::led_r()
220 {
221 	// DIPs?
222 	// 0x01 no mmu
223 	// 0x10 enter monitor after post
224 	// 0x20 enter monitor before post
225 	return 0x01;
226 }
227 
led_w(uint8_t data)228 void pcd_state::led_w(uint8_t data)
229 {
230 	for(int i = 0; i < 6; i++)
231 		logerror("%c", (data & (1 << i)) ? '-' : '*');
232 	logerror("\n");
233 	m_led = data;
234 }
235 
mmu_r(offs_t offset)236 uint16_t pcd_state::mmu_r(offs_t offset)
237 {
238 	uint16_t data = m_mmu.regs[((m_mmu.ctl & 0x1f) << 5) | ((offset >> 2) & 0x1f)];
239 	//logerror("%s: mmu read %04x %04x\n", machine().describe_context(), (offset << 1) + 0x8000, data);
240 	if(!offset)
241 		return m_mmu.ctl;
242 	else if((offset >= 0x200) && (offset < 0x400) && !(offset & 3))
243 		return (data << 4) | (data >> 12) | (m_mmu.sc && (offset == 0x200) ? 0xc0 : 0);
244 	else if(offset == 0x400)
245 	{
246 		m_mmu.sc = false;
247 		m_pic1->ir0_w(CLEAR_LINE);
248 	}
249 	return 0;
250 }
251 
mmu_w(offs_t offset,uint16_t data)252 void pcd_state::mmu_w(offs_t offset, uint16_t data)
253 {
254 	//logerror("%s: mmu write %04x %04x\n", machine().describe_context(), (offset << 1) + 0x8000, data);
255 	if(!offset)
256 		m_mmu.ctl = data;
257 	else if((offset >= 0x200) && (offset < 0x400) && !(offset & 3))
258 		m_mmu.regs[((m_mmu.ctl & 0x1f) << 5) | ((offset >> 2) & 0x1f)] = (data >> 4) | (data << 12);
259 	else if(offset == 0x400)
260 	{
261 		m_mmu.sc = true;
262 		m_pic1->ir0_w(ASSERT_LINE);
263 	}
264 }
265 
scsi_r(offs_t offset)266 uint8_t pcd_state::scsi_r(offs_t offset)
267 {
268 	uint8_t ret = 0;
269 
270 	switch(offset)
271 	{
272 		case 0:
273 		case 2:
274 			ret = m_scsi_data_in->read();
275 			m_scsi->write_ack(1);
276 			if(!offset)
277 				m_maincpu->drq0_w(0);
278 			break;
279 
280 		case 1:
281 			ret = (m_cd << 7) | (m_req << 5) | (m_bsy << 4);
282 			break;
283 	}
284 
285 	return ret;
286 }
287 
scsi_w(offs_t offset,uint8_t data)288 void pcd_state::scsi_w(offs_t offset, uint8_t data)
289 {
290 	switch(offset)
291 	{
292 		case 0:
293 			m_scsi_data_out->write(data);
294 			m_scsi->write_ack(1);
295 			m_maincpu->drq0_w(0);
296 			break;
297 		case 1:
298 			if(data & 4)
299 			{
300 				m_rst = 1;
301 				m_scsi->write_rst(1);
302 				break;
303 			}
304 			if(m_rst)
305 			{
306 				m_rst = 0;
307 				m_scsi->write_rst(0);
308 				break;
309 			}
310 
311 			if(!m_bsy)
312 			{
313 				m_scsi_data_out->write(0);
314 				m_scsi->write_sel(1);
315 			}
316 			break;
317 	}
318 }
319 
check_scsi_irq()320 void pcd_state::check_scsi_irq()
321 {
322 	m_pic1->ir5_w(m_io && m_cd && m_req);
323 }
324 
WRITE_LINE_MEMBER(pcd_state::write_scsi_bsy)325 WRITE_LINE_MEMBER(pcd_state::write_scsi_bsy)
326 {
327 	m_bsy = state ? 1 : 0;
328 	m_scsi->write_sel(0);
329 }
WRITE_LINE_MEMBER(pcd_state::write_scsi_cd)330 WRITE_LINE_MEMBER(pcd_state::write_scsi_cd)
331 {
332 	m_cd = state ? 1 : 0;
333 	check_scsi_irq();
334 }
WRITE_LINE_MEMBER(pcd_state::write_scsi_io)335 WRITE_LINE_MEMBER(pcd_state::write_scsi_io)
336 {
337 	m_io = state ? 1 : 0;
338 	if(state)
339 		m_scsi_data_out->write(0);
340 	check_scsi_irq();
341 }
WRITE_LINE_MEMBER(pcd_state::write_scsi_msg)342 WRITE_LINE_MEMBER(pcd_state::write_scsi_msg)
343 {
344 	m_msg = state ? 1 : 0;
345 }
346 
WRITE_LINE_MEMBER(pcd_state::write_scsi_req)347 WRITE_LINE_MEMBER(pcd_state::write_scsi_req)
348 {
349 	m_req = state ? 1 : 0;
350 	if(state)
351 	{
352 		if(!m_cd)
353 		{
354 			m_maincpu->drq0_w(1);
355 		}
356 		else if(m_msg)
357 		{
358 			m_scsi_data_in->read();
359 			m_scsi->write_ack(1);
360 		}
361 	}
362 	else
363 	{
364 		m_scsi->write_ack(0);
365 	}
366 	check_scsi_irq();
367 }
368 
mem_w(address_space & space,offs_t offset,uint16_t data,uint16_t mem_mask)369 void pcd_state::mem_w(address_space &space, offs_t offset, uint16_t data, uint16_t mem_mask)
370 {
371 	uint16_t *ram = (uint16_t *)m_ram->pointer();
372 	if((m_mmu.ctl & 0x20) && m_mmu.type)
373 	{
374 		uint16_t reg;
375 		if(m_mmu.type == 2)
376 			reg = m_mmu.regs[((offset >> 10) & 0xff) | ((m_mmu.ctl & 0x18) << 5)];
377 		else
378 			reg = m_mmu.regs[((offset >> 10) & 0x7f) | ((m_mmu.ctl & 0x1c) << 5)];
379 		if(!(reg & 1) && !machine().side_effects_disabled())
380 		{
381 			offset <<= 1;
382 			logerror("%s: Null mmu entry %06x\n", machine().describe_context(), offset);
383 			nmi_io_w(space, offset, data);
384 			return;
385 		}
386 		offset = ((reg << 3) & 0x7fc00) | (offset & 0x3ff);
387 	}
388 	COMBINE_DATA(&ram[offset]);
389 }
390 
mem_r(address_space & space,offs_t offset)391 uint16_t pcd_state::mem_r(address_space &space, offs_t offset)
392 {
393 	uint16_t *ram = (uint16_t *)m_ram->pointer();
394 	if((m_mmu.ctl & 0x20) && m_mmu.type)
395 	{
396 		uint16_t reg;
397 		if(m_mmu.type == 2)
398 			reg = m_mmu.regs[((offset >> 10) & 0xff) | ((m_mmu.ctl & 0x18) << 5)];
399 		else
400 			reg = m_mmu.regs[((offset >> 10) & 0x7f) | ((m_mmu.ctl & 0x1c) << 5)];
401 		if(!(reg & 2) && !machine().side_effects_disabled())
402 		{
403 			offset <<= 1;
404 			logerror("%s: Null mmu entry %06x\n", machine().describe_context(), offset);
405 			return nmi_io_r(space, offset);
406 		}
407 		offset = ((reg << 3) & 0x7fc00) | (offset & 0x3ff);
408 	}
409 	return ram[offset];
410 }
411 
412 //**************************************************************************
413 //  ADDRESS MAPS
414 //**************************************************************************
415 
pcd_map(address_map & map)416 void pcd_state::pcd_map(address_map &map)
417 {
418 	map(0x00000, 0xfffff).rw(FUNC(pcd_state::nmi_io_r), FUNC(pcd_state::nmi_io_w));
419 	map(0x00000, 0x7ffff).rw(FUNC(pcd_state::mem_r), FUNC(pcd_state::mem_w));
420 	map(0xfc000, 0xfffff).rom().region("bios", 0);
421 }
422 
pcd_io(address_map & map)423 void pcd_state::pcd_io(address_map &map)
424 {
425 	map.unmap_value_high();
426 	map(0x0000, 0xefff).rw(FUNC(pcd_state::nmi_io_r), FUNC(pcd_state::nmi_io_w));
427 	map(0xf000, 0xf7ff).ram().share("nvram");
428 	map(0xf800, 0xf801).rw(m_pic1, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
429 	map(0xf820, 0xf821).rw(m_pic2, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
430 	map(0xf840, 0xf840).rw(FUNC(pcd_state::stat_r), FUNC(pcd_state::stat_w));
431 	map(0xf841, 0xf841).rw(FUNC(pcd_state::led_r), FUNC(pcd_state::led_w));
432 	map(0xf880, 0xf8bf).rw(m_rtc, FUNC(mc146818_device::read_direct), FUNC(mc146818_device::write_direct));
433 	map(0xf900, 0xf903).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write));
434 	map(0xf904, 0xf905).rw(FUNC(pcd_state::dskctl_r), FUNC(pcd_state::dskctl_w));
435 	map(0xf940, 0xf943).rw(FUNC(pcd_state::scsi_r), FUNC(pcd_state::scsi_w));
436 	map(0xf980, 0xf9bf).m("video", FUNC(pcdx_video_device::map));
437 	map(0xf9c0, 0xf9c3).rw(m_usart[0], FUNC(scn2661b_device::read), FUNC(scn2661b_device::write));  // UARTs
438 	map(0xf9d0, 0xf9d3).rw(m_usart[1], FUNC(scn2661b_device::read), FUNC(scn2661b_device::write));
439 	map(0xf9e0, 0xf9e3).rw(m_usart[2], FUNC(scn2661b_device::read), FUNC(scn2661b_device::write));
440 //  map(0xfa00, 0xfa7f) // pcs4-n (peripheral chip select)
441 	map(0xfb00, 0xfb00).rw(FUNC(pcd_state::nmi_io_r), FUNC(pcd_state::nmi_io_w));
442 	map(0xfb02, 0xffff).rw(FUNC(pcd_state::nmi_io_r), FUNC(pcd_state::nmi_io_w));
443 }
444 
pcx_io(address_map & map)445 void pcd_state::pcx_io(address_map &map)
446 {
447 	map.unmap_value_high();
448 	pcd_io(map);
449 	map(0x8000, 0x8fff).rw(FUNC(pcd_state::mmu_r), FUNC(pcd_state::mmu_w));
450 	map(0xfb01, 0xfb01).rw(FUNC(pcd_state::nmi_io_r), FUNC(pcd_state::nmi_io_w));
451 }
452 
453 //**************************************************************************
454 //  MACHINE DRIVERS
455 //**************************************************************************
456 
pcd_floppies(device_slot_interface & device)457 static void pcd_floppies(device_slot_interface &device)
458 {
459 	device.option_add("55f", TEAC_FD_55F); // 80 tracks
460 	device.option_add("55g", TEAC_FD_55G); // 77 tracks
461 }
462 
FLOPPY_FORMATS_MEMBER(pcd_state::floppy_formats)463 FLOPPY_FORMATS_MEMBER( pcd_state::floppy_formats )
464 	FLOPPY_PC_FORMAT
465 FLOPPY_FORMATS_END
466 
467 static INPUT_PORTS_START(pcx)
468 	PORT_START("mmu")
469 	PORT_CONFNAME(0x03, 0x00, "MMU Type")
470 	PORT_CONFSETTING(0x00, "None")
471 	PORT_CONFSETTING(0x01, "SINIX 1.0")
472 	PORT_CONFSETTING(0x02, "SINIX 1.2")
473 INPUT_PORTS_END
474 
475 void pcd_state::pcd(machine_config &config)
476 {
477 	I80186(config, m_maincpu, 16_MHz_XTAL);
478 	m_maincpu->set_addrmap(AS_PROGRAM, &pcd_state::pcd_map);
479 	m_maincpu->set_addrmap(AS_IO, &pcd_state::pcd_io);
480 	m_maincpu->tmrout1_handler().set(FUNC(pcd_state::i186_timer1_w));
481 	m_maincpu->read_slave_ack_callback().set(FUNC(pcd_state::irq_callback));
482 
483 	TIMER(config, "timer0_tick").configure_periodic(FUNC(pcd_state::timer0_tick), attotime::from_hz(16_MHz_XTAL / 24)); // adjusted to pass post
484 
485 	PIC8259(config, m_pic1, 0);
486 	m_pic1->out_int_callback().set(m_maincpu, FUNC(i80186_cpu_device::int0_w));
487 
488 	PIC8259(config, m_pic2, 0);
489 	m_pic2->out_int_callback().set(m_maincpu, FUNC(i80186_cpu_device::int1_w));
490 
491 	PCD_VIDEO(config, "video", 0);
492 
493 	RAM(config, RAM_TAG).set_default_size("1M");
494 
495 	// nvram
496 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
497 
498 	// floppy disk controller
499 	WD2793(config, m_fdc, 16_MHz_XTAL / 8);
500 	m_fdc->intrq_wr_callback().set(m_pic1, FUNC(pic8259_device::ir6_w));
501 	m_fdc->drq_wr_callback().set(m_maincpu, FUNC(i80186_cpu_device::drq1_w));
502 	m_fdc->enmf_rd_callback().set_constant(0);
503 
504 	// floppy drives
505 	FLOPPY_CONNECTOR(config, "fdc:0", pcd_floppies, "55f", pcd_state::floppy_formats);
506 	FLOPPY_CONNECTOR(config, "fdc:1", pcd_floppies, "55f", pcd_state::floppy_formats);
507 
508 	// usart
509 	SCN2661B(config, m_usart[0], 4.9152_MHz_XTAL);
510 	m_usart[0]->rxrdy_handler().set(m_pic1, FUNC(pic8259_device::ir3_w));
511 	m_usart[0]->txrdy_handler().set(m_pic1, FUNC(pic8259_device::ir3_w));
512 	m_usart[0]->txd_handler().set("rs232_1", FUNC(rs232_port_device::write_txd));
513 
514 	SCN2661B(config, m_usart[1], 4.9152_MHz_XTAL);
515 	m_usart[1]->rxrdy_handler().set(m_pic1, FUNC(pic8259_device::ir2_w));
516 	//m_usart[1]->.txrdy_handler().set(m_pic1, FUNC(pic8259_device::ir2_w)); // this gets stuck high causing the keyboard to not work
517 	m_usart[1]->txd_handler().set("keyboard", FUNC(pcd_keyboard_device::t0_w));
518 
519 	SCN2661B(config, m_usart[2], 4.9152_MHz_XTAL);
520 	m_usart[2]->rxrdy_handler().set(m_pic1, FUNC(pic8259_device::ir4_w));
521 	m_usart[2]->txrdy_handler().set(m_pic1, FUNC(pic8259_device::ir4_w));
522 	m_usart[2]->txd_handler().set("rs232_2", FUNC(rs232_port_device::write_txd));
523 
524 	rs232_port_device &rs232_1(RS232_PORT(config, "rs232_1", default_rs232_devices, nullptr));
525 	rs232_1.rxd_handler().set(m_usart[0], FUNC(scn2661b_device::rxd_w));
526 	rs232_port_device &rs232_2(RS232_PORT(config, "rs232_2", default_rs232_devices, nullptr));
527 	rs232_2.rxd_handler().set(m_usart[2], FUNC(scn2661b_device::rxd_w));
528 
529 	// sound hardware
530 	SPEAKER(config, "mono").front_center();
531 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
532 
533 	// rtc
534 	MC146818(config, m_rtc, 32.768_kHz_XTAL);
535 	m_rtc->irq().set(m_pic1, FUNC(pic8259_device::ir7_w));
536 	m_rtc->set_binary(true);
537 	m_rtc->set_binary_year(true);
538 	m_rtc->set_epoch(1900);
539 	m_rtc->set_24hrs(true);
540 
541 	pcd_keyboard_device &keyboard(PCD_KEYBOARD(config, "keyboard", 0));
542 	keyboard.out_tx_handler().set(m_usart[1], FUNC(scn2661b_device::rxd_w));
543 
544 	SCSI_PORT(config, m_scsi, 0);
545 	m_scsi->set_data_input_buffer("scsi_data_in");
546 	m_scsi->msg_handler().set(FUNC(pcd_state::write_scsi_msg));
547 	m_scsi->bsy_handler().set(FUNC(pcd_state::write_scsi_bsy));
548 	m_scsi->io_handler().set(FUNC(pcd_state::write_scsi_io));
549 	m_scsi->cd_handler().set(FUNC(pcd_state::write_scsi_cd));
550 	m_scsi->req_handler().set(FUNC(pcd_state::write_scsi_req));
551 
552 	output_latch_device &scsi_out(OUTPUT_LATCH(config, "scsi_data_out", 0));
553 	m_scsi->set_output_latch(scsi_out);
554 
555 	INPUT_BUFFER(config, "scsi_data_in", 0);
556 	m_scsi->set_slot_device(1, "harddisk", OMTI5100, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_0));
557 
558 	SOFTWARE_LIST(config, "flop_list").set_original("pcd_flop");
559 }
560 
pcx(machine_config & config)561 void pcd_state::pcx(machine_config &config)
562 {
563 	pcd(config);
564 	m_maincpu->set_addrmap(AS_IO, &pcd_state::pcx_io);
565 
566 	pcx_video_device &video(PCX_VIDEO(config.replace(), "video", 0));
567 	video.txd_handler().set("keyboard", FUNC(pcd_keyboard_device::t0_w));
568 
569 	subdevice<pcd_keyboard_device>("keyboard")->out_tx_handler().set("video", FUNC(pcx_video_device::rx_w));
570 
571 	m_usart[1]->txd_handler().set_nop();
572 
573 	config.device_remove("flop_list");
574 	SOFTWARE_LIST(config, "flop_ls").set_original("pcx_flop");
575 }
576 
577 //**************************************************************************
578 //  ROM DEFINITIONS
579 //**************************************************************************
580 
581 ROM_START( pcd )
582 	ROM_REGION16_LE(0x4000, "bios", 0)
583 	ROM_SYSTEM_BIOS(0, "v2", "V2 GS")  // from mainboard SYBAC S26361-D359 V2 GS
584 	ROMX_LOAD("s26361-d359.d42", 0x0001, 0x2000, CRC(e20244dd) SHA1(0ebc5ddb93baacd9106f1917380de58aac64fe73), ROM_SKIP(1) | ROM_BIOS(0))
585 	ROMX_LOAD("s26361-d359.d43", 0x0000, 0x2000, CRC(e03db2ec) SHA1(fcae8b0c9e7543706817b0a53872826633361fda), ROM_SKIP(1) | ROM_BIOS(0))
586 	ROM_SYSTEM_BIOS(1, "v3", "V3 GS4") // from mainboard SYBAC S26361-D359 V3 GS4
587 	ROMX_LOAD("361d0359.d42", 0x0001, 0x2000, CRC(5b4461e4) SHA1(db6756aeabb2e6d3921dc7571a5bed3497b964bf), ROM_SKIP(1) | ROM_BIOS(1))
588 	ROMX_LOAD("361d0359.d43", 0x0000, 0x2000, CRC(71c3189d) SHA1(e8dd6c632bfc833074d3a833ea7f59bb5460f313), ROM_SKIP(1) | ROM_BIOS(1))
589 ROM_END
590 
591 ROM_START( pcx )
592 	ROM_REGION16_LE(0x4000, "bios", 0)
593 	ROM_SYSTEM_BIOS(0, "v2", "V2 GS")  // from mainboard SYBAC S26361-D359 V2 GS
594 	ROMX_LOAD("s26361-d359.d42", 0x0001, 0x2000, CRC(e20244dd) SHA1(0ebc5ddb93baacd9106f1917380de58aac64fe73), ROM_SKIP(1) | ROM_BIOS(0))
595 	ROMX_LOAD("s26361-d359.d43", 0x0000, 0x2000, CRC(e03db2ec) SHA1(fcae8b0c9e7543706817b0a53872826633361fda), ROM_SKIP(1) | ROM_BIOS(0))
596 	ROM_SYSTEM_BIOS(1, "v3", "V3 GS4") // from mainboard SYBAC S26361-D359 V3 GS4
597 	ROMX_LOAD("361d0359.d42", 0x0001, 0x2000, CRC(5b4461e4) SHA1(db6756aeabb2e6d3921dc7571a5bed3497b964bf), ROM_SKIP(1) | ROM_BIOS(1))
598 	ROMX_LOAD("361d0359.d43", 0x0000, 0x2000, CRC(71c3189d) SHA1(e8dd6c632bfc833074d3a833ea7f59bb5460f313), ROM_SKIP(1) | ROM_BIOS(1))
599 ROM_END
600 
601 //**************************************************************************
602 //  GAME DRIVERS
603 //**************************************************************************
604 
605 COMP( 1984, pcd, 0,   0, pcd, 0,   pcd_state, empty_init, "Siemens", "PC-D", MACHINE_NOT_WORKING )
606 COMP( 1984, pcx, pcd, 0, pcx, pcx, pcd_state, empty_init, "Siemens", "PC-X", MACHINE_NOT_WORKING )
607