1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /*
4 
5     Luxor ABC 1600
6 
7     How to create HDD image:
8     ------------------------
9     ./chdman createhd -chs 615,4,17 -ss 512 -o necd5126a.chd
10     ./chdman createhd -chs 1024,8,17 -ss 512 -o micr1325a.chd
11 
12     How to format HDD:
13     ------------------
14     mf(2,0)
15     mf(2,0)
16     sas/format/format
17     sa(40,0)
18     y
19     5
20     micr1325a
21 
22     How to install OS:
23     ------------------
24     mf(2,0)
25     mf(2,0)
26     abcenix
27     loadsys1
28     <enter>
29     <enter>
30 
31 */
32 
33 /*
34 
35     TODO:
36 
37     - sas/format/format in abcenix tries to access the SASI card using a memory location mapped for task 0, when the process is run as task 1
38 
39         [:mac] ':3f' (0009E) ff800:4f TASK 0 SEGMENT 15 PAGE 15 MEM 7f800-7ffff 1ff800
40         [:mac] ':3f' (0009E) ff801:ff TASK 0 SEGMENT 15 PAGE 15 MEM 7f800-7ffff 1ff800
41         [:mac] ':3f' (0009E) ff000:4f TASK 0 SEGMENT 15 PAGE 14 MEM 7f000-7f7ff 1ff000
42         [:mac] ':3f' (0009E) ff001:fe TASK 0 SEGMENT 15 PAGE 14 MEM 7f000-7f7ff 1ff000
43         [:mac] ':3f' (0009E) fe800:4f TASK 0 SEGMENT 15 PAGE 13 MEM 7e800-7efff 1fe800
44         [:mac] ':3f' (0009E) fe801:fd TASK 0 SEGMENT 15 PAGE 13 MEM 7e800-7efff 1fe800
45         [:mac] ':3f' (0009E) fe000:4f TASK 0 SEGMENT 15 PAGE 12 MEM 7e000-7e7ff 1fe000
46         [:mac] ':3f' (0009E) fe001:fc TASK 0 SEGMENT 15 PAGE 12 MEM 7e000-7e7ff 1fe000
47 
48         [:mac] ':3f' (08A98) MAC 7e4a2:0004a2 (SEGA 02f SEGD 09 PGA 09c PGD 8000 NONX 1 WP 0 TASK 1 FC 1)
49         should be
50         [:mac] ':3f' (089A8) MAC 7e4a2:1fe4a2 (SEGA 00f SEGD 0f PGA 0fc PGD 43fc NONX 0 WP 1 TASK 0 FC 5)
51 
52     - short/long reset (RSTBUT)
53     - CIO
54         - optimize timers!
55         - port C, open drain output bit PC1 (RTC/NVRAM data)
56     - connect RS-232 printer port
57     - Z80 SCC/DART interrupt chain
58     - Z80 SCC DMA request
59 
60 */
61 
62 #include "emu.h"
63 #include "includes/abc1600.h"
64 #include "softlist.h"
65 
66 
67 //**************************************************************************
68 //  CONSTANTS / MACROS
69 //**************************************************************************
70 
71 #define LOG 0
72 
73 
74 #define A1          BIT(offset, 1)
75 #define A2          BIT(offset, 2)
76 #define A4          BIT(offset, 4)
77 #define X11         BIT(offset, 11)
78 #define A1_A2       ((A1 << 1) | A2)
79 #define A2_A1       ((offset >> 1) & 0x03)
80 
81 
82 // external I/O
83 enum
84 {
85 	INP = 0,
86 	STAT,
87 	OPS
88 };
89 
90 enum
91 {
92 	OUT = 0,
93 	C1 = 2,
94 	C2,
95 	C3,
96 	C4
97 };
98 
99 
100 
101 
102 //**************************************************************************
103 //  READ/WRITE HANDLERS
104 //**************************************************************************
105 
106 //-------------------------------------------------
107 //  bus_r -
108 //-------------------------------------------------
109 
bus_r(offs_t offset)110 uint8_t abc1600_state::bus_r(offs_t offset)
111 {
112 	uint8_t data = 0;
113 
114 	// card select pulse
115 	uint8_t cs = (m_cs7 << 7) | ((offset >> 5) & 0x3f);
116 
117 	m_bus0i->write_cs(cs);
118 	m_bus0x->write_cs(cs);
119 	m_bus1->write_cs(cs);
120 	m_bus2->write_cs(cs);
121 
122 	// card select b?
123 	m_csb = m_bus2->csb_r();
124 	m_csb |= m_bus1->csb_r() << 1;
125 	m_csb |= m_bus0x->xcsb2_r() << 2;
126 	m_csb |= m_bus0x->xcsb3_r() << 3;
127 	m_csb |= m_bus0x->xcsb4_r() << 4;
128 	m_csb |= m_bus0x->xcsb5_r() << 5;
129 	m_csb |= m_bus0x->csb_r() << 6;
130 	m_csb |= m_bus0i->csb_r() << 7;
131 
132 	m_bus0 = !((m_csb & 0xfc) == 0xfc);
133 
134 	if (X11)
135 	{
136 		if (A4)
137 		{
138 			// EXP
139 			data = m_bus0x->exp_r();
140 
141 			if (LOG) logerror("%s EXP %02x: %02x\n", machine().describe_context(), cs, data);
142 		}
143 		else
144 		{
145 			// RCSB
146 			if (m_bus0)
147 			{
148 				/*
149 
150 				    bit     description
151 
152 				    0       1
153 				    1       1
154 				    2       LXCSB2*
155 				    3       LXCSB3*
156 				    4       LXCSB4*
157 				    5       LXCSB5*
158 				    6       LCSB*-0
159 				    7       LCSB*-0I
160 
161 				*/
162 
163 				data = (m_csb & 0xfc) | 0x03;
164 			}
165 			else
166 			{
167 				/*
168 
169 				    bit     description
170 
171 				    0       LCSB*-2
172 				    1       LCSB*-1
173 				    2       1
174 				    3       1
175 				    4       1
176 				    5       1
177 				    6       1
178 				    7       1
179 
180 				*/
181 
182 				data = 0xfc | (m_csb & 0x03);
183 			}
184 
185 			if (LOG) logerror("%s RCSB %02x\n", machine().describe_context(), data);
186 		}
187 	}
188 	else
189 	{
190 		data = 0xff;
191 
192 		switch ((offset >> 1) & 0x07)
193 		{
194 		case INP:
195 			if (m_bus0)
196 			{
197 				data &= m_bus0i->read_inp();
198 				data &= m_bus0x->read_inp();
199 			}
200 			else
201 			{
202 				data &= m_bus1->read_inp();
203 				data &= m_bus2->read_inp();
204 			}
205 
206 			if (LOG) logerror("%s INP %02x: %02x\n", machine().describe_context(), cs, data);
207 			break;
208 
209 		case STAT:
210 			if (m_bus0)
211 			{
212 				data &= m_bus0i->read_stat();
213 				data &= m_bus0x->read_stat();
214 			}
215 			else
216 			{
217 				data &= m_bus1->read_stat();
218 				data &= m_bus2->read_stat();
219 			}
220 
221 			if (LOG) logerror("%s STAT %02x: %02x\n", machine().describe_context(), cs, data);
222 			break;
223 
224 		case OPS:
225 			if (m_bus0)
226 			{
227 				data &= m_bus0i->ops_r();
228 				data &= m_bus0x->ops_r();
229 			}
230 			else
231 			{
232 				data &= m_bus1->ops_r();
233 				data &= m_bus2->ops_r();
234 			}
235 
236 			if (LOG) logerror("%s OPS %02x: %02x\n", machine().describe_context(), cs, data);
237 			break;
238 
239 		default:
240 			if (LOG) logerror("%s Unmapped read from virtual I/O %06x\n", machine().describe_context(), offset);
241 		}
242 	}
243 
244 	return data;
245 }
246 
247 
248 //-------------------------------------------------
249 //  bus_w -
250 //-------------------------------------------------
251 
bus_w(offs_t offset,uint8_t data)252 void abc1600_state::bus_w(offs_t offset, uint8_t data)
253 {
254 	uint8_t cs = (m_cs7 << 7) | ((offset >> 5) & 0x3f);
255 
256 	m_bus0i->write_cs(cs);
257 	m_bus0x->write_cs(cs);
258 	m_bus1->write_cs(cs);
259 	m_bus2->write_cs(cs);
260 
261 	switch ((offset >> 1) & 0x07)
262 	{
263 	case OUT:
264 		if (LOG) logerror("%s OUT %02x: %02x\n", machine().describe_context(), cs, data);
265 
266 		if (m_bus0)
267 		{
268 			m_bus0i->write_out(data);
269 			m_bus0x->write_out(data);
270 		}
271 		else
272 		{
273 			m_bus1->write_out(data);
274 			m_bus2->write_out(data);
275 		}
276 		break;
277 
278 	case C1:
279 		if (LOG) logerror("%s C1 %02x: %02x\n", machine().describe_context(), cs, data);
280 
281 		if (m_bus0)
282 		{
283 			m_bus0i->write_c1(data);
284 			m_bus0x->write_c1(data);
285 		}
286 		else
287 		{
288 			m_bus1->write_c1(data);
289 			m_bus2->write_c1(data);
290 		}
291 		break;
292 
293 	case C2:
294 		if (LOG) logerror("%s C2 %02x: %02x\n", machine().describe_context(), cs, data);
295 
296 		if (m_bus0)
297 		{
298 			m_bus0i->write_c2(data);
299 			m_bus0x->write_c2(data);
300 		}
301 		else
302 		{
303 			m_bus1->write_c2(data);
304 			m_bus2->write_c2(data);
305 		}
306 		break;
307 
308 	case C3:
309 		if (LOG) logerror("%s C3 %02x: %02x\n", machine().describe_context(), cs, data);
310 
311 		if (m_bus0)
312 		{
313 			m_bus0i->write_c3(data);
314 			m_bus0x->write_c3(data);
315 		}
316 		else
317 		{
318 			m_bus1->write_c3(data);
319 			m_bus2->write_c3(data);
320 		}
321 		break;
322 
323 	case C4:
324 		if (LOG) logerror("%s C4 %02x: %02x\n", machine().describe_context(), cs, data);
325 
326 		if (m_bus0)
327 		{
328 			m_bus0i->write_c4(data);
329 			m_bus0x->write_c4(data);
330 		}
331 		else
332 		{
333 			m_bus1->write_c4(data);
334 			m_bus2->write_c4(data);
335 		}
336 		break;
337 
338 	default:
339 		if (LOG) logerror("%s Unmapped write %02x to virtual I/O %06x\n", machine().describe_context(), data, offset);
340 	}
341 }
342 
343 
344 //-------------------------------------------------
345 //  fw0_w -
346 //-------------------------------------------------
347 
fw0_w(uint8_t data)348 void abc1600_state::fw0_w(uint8_t data)
349 {
350 	/*
351 
352 	    bit     description
353 
354 	    0       SEL1
355 	    1       SEL2
356 	    2       SEL3
357 	    3       MOTOR
358 	    4       LC/PC
359 	    5       LC/PC
360 	    6
361 	    7
362 
363 	*/
364 
365 	if (LOG) logerror("%s FW0 %02x\n", machine().describe_context(), data);
366 
367 	// drive select
368 	floppy_image_device *floppy = nullptr;
369 
370 	if (BIT(data, 0)) floppy = m_floppy0->get_device();
371 	if (BIT(data, 1)) floppy = m_floppy1->get_device();
372 	if (BIT(data, 2)) floppy = m_floppy2->get_device();
373 
374 	m_fdc->set_floppy(floppy);
375 
376 	// floppy motor
377 	if (floppy) floppy->mon_w(!BIT(data, 3));
378 }
379 
380 
381 //-------------------------------------------------
382 //  fw1_w -
383 //-------------------------------------------------
384 
fw1_w(uint8_t data)385 void abc1600_state::fw1_w(uint8_t data)
386 {
387 	/*
388 
389 	    bit     description
390 
391 	    0       MR
392 	    1       DDEN
393 	    2       HLT
394 	    3       MINI
395 	    4       HLD
396 	    5       P0
397 	    6       P1
398 	    7       P2
399 
400 	*/
401 
402 	if (LOG) logerror("%s FW1 %02x\n", machine().describe_context(), data);
403 
404 	// FDC master reset
405 	if (!BIT(data, 0)) m_fdc->reset();
406 
407 	// density select
408 	m_fdc->dden_w(BIT(data, 1));
409 }
410 
411 
412 //-------------------------------------------------
413 //  spec_contr_reg_w -
414 //-------------------------------------------------
415 
spec_contr_reg_w(uint8_t data)416 void abc1600_state::spec_contr_reg_w(uint8_t data)
417 {
418 	int state = BIT(data, 3);
419 
420 	if (LOG) logerror("%s SPEC CONTR REG %u:%u\n", machine().describe_context(), data & 0x07, state);
421 
422 	switch (data & 0x07)
423 	{
424 	case 0: // CS7
425 		m_cs7 = state;
426 		break;
427 
428 	case 1:
429 		break;
430 
431 	case 2: // _BTCE
432 		m_btce = state;
433 		break;
434 
435 	case 3: // _ATCE
436 		m_atce = state;
437 		break;
438 
439 	case 4: // PARTST
440 		m_partst = state;
441 		break;
442 
443 	case 5: // _DMADIS
444 		m_dmadis = state;
445 		break;
446 
447 	case 6: // SYSSCC
448 		m_sysscc = state;
449 
450 		m_cio->pb5_w(!state);
451 
452 		update_drdy1(0);
453 		break;
454 
455 	case 7: // SYSFS
456 		m_sysfs = state;
457 
458 		m_cio->pb6_w(!state);
459 
460 		update_drdy0(0);
461 		break;
462 	}
463 }
464 
465 
466 
467 //**************************************************************************
468 //  ADDRESS MAPS
469 //**************************************************************************
470 
471 //-------------------------------------------------
472 //  ADDRESS_MAP( abc1600_mem )
473 //-------------------------------------------------
474 
abc1600_mem(address_map & map)475 void abc1600_state::abc1600_mem(address_map &map)
476 {
477 	map(0x00000, 0xfffff).m(ABC1600_MAC_TAG, FUNC(abc1600_mac_device::map));
478 }
479 
480 
481 //-------------------------------------------------
482 //  ADDRESS_MAP( mac_mem )
483 //-------------------------------------------------
484 
mac_mem(address_map & map)485 void abc1600_state::mac_mem(address_map &map)
486 {
487 	map(0x000000, 0x0fffff).ram();
488 	map(0x100000, 0x17ffff).m(ABC1600_MOVER_TAG, FUNC(abc1600_mover_device::vram_map));
489 	map(0x1fe000, 0x1fefff).rw(FUNC(abc1600_state::bus_r), FUNC(abc1600_state::bus_w));
490 	map(0x1ff000, 0x1ff000).mirror(0xf9).rw(m_fdc, FUNC(fd1797_device::status_r), FUNC(fd1797_device::cmd_w));
491 	map(0x1ff002, 0x1ff002).mirror(0xf9).rw(m_fdc, FUNC(fd1797_device::track_r), FUNC(fd1797_device::track_w));
492 	map(0x1ff004, 0x1ff004).mirror(0xf9).rw(m_fdc, FUNC(fd1797_device::sector_r), FUNC(fd1797_device::sector_w));
493 	map(0x1ff006, 0x1ff006).mirror(0xf9).rw(m_fdc, FUNC(fd1797_device::data_r), FUNC(fd1797_device::data_w));
494 	map(0x1ff100, 0x1ff101).mirror(0xfe).m(ABC1600_MOVER_TAG, FUNC(abc1600_mover_device::crtc_map));
495 	map(0x1ff200, 0x1ff207).mirror(0xf8).rw(FUNC(abc1600_state::dart_r), FUNC(abc1600_state::dart_w));
496 	map(0x1ff300, 0x1ff300).mirror(0xff).rw(m_dma0, FUNC(z80dma_device::read), FUNC(z80dma_device::write));
497 	map(0x1ff400, 0x1ff400).mirror(0xff).rw(m_dma1, FUNC(z80dma_device::read), FUNC(z80dma_device::write));
498 	map(0x1ff500, 0x1ff500).mirror(0xff).rw(m_dma2, FUNC(z80dma_device::read), FUNC(z80dma_device::write));
499 	map(0x1ff600, 0x1ff607).mirror(0xf8).rw(FUNC(abc1600_state::scc_r), FUNC(abc1600_state::scc_w));
500 	map(0x1ff700, 0x1ff707).mirror(0xf8).rw(FUNC(abc1600_state::cio_r), FUNC(abc1600_state::cio_w));
501 	map(0x1ff800, 0x1ff8ff).m(ABC1600_MOVER_TAG, FUNC(abc1600_mover_device::iowr0_map));
502 	map(0x1ff900, 0x1ff9ff).m(ABC1600_MOVER_TAG, FUNC(abc1600_mover_device::iowr1_map));
503 	map(0x1ffa00, 0x1ffaff).m(ABC1600_MOVER_TAG, FUNC(abc1600_mover_device::iowr2_map));
504 	map(0x1ffb00, 0x1ffb00).mirror(0x7e).w(FUNC(abc1600_state::fw0_w));
505 	map(0x1ffb01, 0x1ffb01).mirror(0x7e).w(FUNC(abc1600_state::fw1_w));
506 	map(0x1ffd00, 0x1ffd07).mirror(0xf8).w(ABC1600_MAC_TAG, FUNC(abc1600_mac_device::dmamap_w));
507 	map(0x1ffe00, 0x1ffe00).mirror(0xff).w(FUNC(abc1600_state::spec_contr_reg_w));
508 }
509 
510 
511 
512 //**************************************************************************
513 //  INPUT PORTS
514 //**************************************************************************
515 
516 //-------------------------------------------------
517 //  INPUT_PORTS( abc1600 )
518 //-------------------------------------------------
519 
INPUT_PORTS_START(abc1600)520 static INPUT_PORTS_START( abc1600 )
521 	// inputs defined in machine/abc99.cpp
522 INPUT_PORTS_END
523 
524 
525 
526 //**************************************************************************
527 //  DEVICE CONFIGURATION
528 //**************************************************************************
529 
530 //-------------------------------------------------
531 //  Z80DMA 0
532 //-------------------------------------------------
533 
534 void abc1600_state::update_pren0(int state)
535 {
536 	if (m_sysfs)
537 	{
538 		// floppy
539 		m_dma0->iei_w(0);
540 	}
541 	else
542 	{
543 		// BUS0I/BUS0X
544 		bool pren0 = m_bus0i->pren_r() && m_bus0x->pren_r();
545 
546 		m_dma0->iei_w(!pren0);
547 	}
548 }
549 
update_drdy0(int state)550 void abc1600_state::update_drdy0(int state)
551 {
552 	if (m_sysfs)
553 	{
554 		// floppy
555 		m_dma0->rdy_w(!m_fdc->drq_r());
556 	}
557 	else
558 	{
559 		// BUS0I/BUS0X
560 		int trrq0 = m_bus0i->trrq_r() && m_bus0x->trrq_r();
561 
562 		m_dma0->rdy_w(trrq0);
563 	}
564 }
565 
WRITE_LINE_MEMBER(abc1600_state::dbrq_w)566 WRITE_LINE_MEMBER( abc1600_state::dbrq_w )
567 {
568 	m_maincpu->set_input_line(INPUT_LINE_HALT, state && m_dmadis);
569 }
570 
571 //-------------------------------------------------
572 //  Z80DMA 1
573 //-------------------------------------------------
574 
update_pren1(int state)575 void abc1600_state::update_pren1(int state)
576 {
577 	if (m_sysscc)
578 	{
579 		// SCC
580 		m_dma1->iei_w(1);
581 	}
582 	else
583 	{
584 		// BUS1
585 		m_dma1->iei_w(!m_bus1->pren_r());
586 	}
587 }
588 
update_drdy1(int state)589 void abc1600_state::update_drdy1(int state)
590 {
591 	if (m_sysscc)
592 	{
593 		// SCC
594 		m_dma1->rdy_w(m_sccrq_a && m_sccrq_b);
595 	}
596 	else
597 	{
598 		// BUS1
599 		m_dma1->rdy_w(m_bus1->trrq_r());
600 	}
601 }
602 
603 //-------------------------------------------------
604 //  Z80DART
605 //-------------------------------------------------
606 
dart_r(offs_t offset)607 uint8_t abc1600_state::dart_r(offs_t offset)
608 {
609 	return m_dart->ba_cd_r(A2_A1 ^ 0x03);
610 }
611 
dart_w(offs_t offset,uint8_t data)612 void abc1600_state::dart_w(offs_t offset, uint8_t data)
613 {
614 	m_dart->ba_cd_w(A2_A1 ^ 0x03, data);
615 }
616 
617 //-------------------------------------------------
618 //  SCC8530
619 //-------------------------------------------------
620 
scc_r(offs_t offset)621 uint8_t abc1600_state::scc_r(offs_t offset)
622 {
623 	return m_scc->ab_dc_r(A2_A1);
624 }
625 
scc_w(offs_t offset,uint8_t data)626 void abc1600_state::scc_w(offs_t offset, uint8_t data)
627 {
628 	m_scc->ab_dc_w(A2_A1, data);
629 }
630 
631 
632 //-------------------------------------------------
633 //  Z8536
634 //-------------------------------------------------
635 
cio_r(offs_t offset)636 uint8_t abc1600_state::cio_r(offs_t offset)
637 {
638 	return m_cio->read(A2_A1);
639 }
640 
cio_w(offs_t offset,uint8_t data)641 void abc1600_state::cio_w(offs_t offset, uint8_t data)
642 {
643 	m_cio->write(A2_A1, data);
644 }
645 
cio_pa_r()646 uint8_t abc1600_state::cio_pa_r()
647 {
648 	/*
649 
650 	    bit     description
651 
652 	    PA0     BUS2
653 	    PA1     BUS1
654 	    PA2     BUS0X*2
655 	    PA3     BUS0X*3
656 	    PA4     BUS0X*4
657 	    PA5     BUS0X*5
658 	    PA6     BUS0X
659 	    PA7     BUS0I
660 
661 	*/
662 
663 	uint8_t data = 0;
664 
665 	data |= m_bus2->irq_r();
666 	data |= m_bus1->irq_r() << 1;
667 	data |= m_bus0x->xint2_r() << 2;
668 	data |= m_bus0x->xint3_r() << 3;
669 	data |= m_bus0x->xint4_r() << 4;
670 	data |= m_bus0x->xint5_r() << 5;
671 	data |= m_bus0x->irq_r() << 6;
672 	data |= m_bus0i->irq_r() << 7;
673 
674 	return data;
675 }
676 
cio_pb_r()677 uint8_t abc1600_state::cio_pb_r()
678 {
679 	/*
680 
681 	    bit     description
682 
683 	    PB0
684 	    PB1     POWERFAIL
685 	    PB2
686 	    PB3
687 	    PB4     MINT
688 	    PB5     _PREN-1
689 	    PB6     _PREN-0
690 	    PB7     FINT
691 
692 	*/
693 
694 	uint8_t data = 0;
695 
696 	data |= !m_sysscc << 5;
697 	data |= !m_sysfs << 6;
698 
699 	// floppy interrupt
700 	data |= m_fdc->intrq_r() << 7;
701 
702 	return data;
703 }
704 
cio_pb_w(uint8_t data)705 void abc1600_state::cio_pb_w(uint8_t data)
706 {
707 	/*
708 
709 	    bit     description
710 
711 	    PB0     PRBR
712 	    PB1
713 	    PB2
714 	    PB3
715 	    PB4
716 	    PB5
717 	    PB6
718 	    PB7
719 
720 	*/
721 
722 	// printer baudrate
723 	int prbr = BIT(data, 0);
724 
725 	m_dart->txca_w(prbr);
726 	m_dart->rxca_w(prbr);
727 }
728 
cio_pc_r()729 uint8_t abc1600_state::cio_pc_r()
730 {
731 	/*
732 
733 	    bit     description
734 
735 	    PC0     1
736 	    PC1     DATA IN
737 	    PC2     1
738 	    PC3     1
739 
740 	*/
741 
742 	uint8_t data = 0x0d;
743 
744 	// data in
745 	data |= (m_rtc->dio_r() || m_nvram->do_r()) << 1;
746 
747 	return data;
748 }
749 
cio_pc_w(uint8_t data)750 void abc1600_state::cio_pc_w(uint8_t data)
751 {
752 	/*
753 
754 	    bit     description
755 
756 	    PC0     CLOCK
757 	    PC1     DATA OUT
758 	    PC2     RTC CS
759 	    PC3     NVRAM CS
760 
761 	*/
762 
763 	int clock = BIT(data, 0);
764 	int data_out = BIT(data, 1);
765 	int rtc_cs = BIT(data, 2);
766 	int nvram_cs = BIT(data, 3);
767 
768 	if (LOG) logerror("CLK %u DATA %u RTC %u NVRAM %u\n", clock, data_out, rtc_cs, nvram_cs);
769 
770 	m_rtc->cs_w(rtc_cs);
771 	m_rtc->dio_w(data_out);
772 	m_rtc->clk_w(clock);
773 
774 	m_nvram->cs_w(nvram_cs);
775 	m_nvram->di_w(data_out);
776 	m_nvram->sk_w(clock);
777 }
778 
abc1600_floppies(device_slot_interface & device)779 static void abc1600_floppies(device_slot_interface &device)
780 {
781 	device.option_add("525qd", FLOPPY_525_QD);
782 }
783 
784 
785 //-------------------------------------------------
786 //  ABC1600BUS_INTERFACE( abcbus_intf )
787 //-------------------------------------------------
788 
WRITE_LINE_MEMBER(abc1600_state::nmi_w)789 WRITE_LINE_MEMBER( abc1600_state::nmi_w )
790 {
791 	if (state == ASSERT_LINE)
792 	{
793 		m_maincpu->set_input_line(M68K_IRQ_7, ASSERT_LINE);
794 	}
795 }
796 
797 
798 
799 //**************************************************************************
800 //  MACHINE INITIALIZATION
801 //**************************************************************************
802 
cpu_space_map(address_map & map)803 void abc1600_state::cpu_space_map(address_map &map)
804 {
805 	map(0xffff0, 0xfffff).m(m_maincpu, FUNC(m68008_device::autovectors_map));
806 	map(0xffff5, 0xffff5).lr8(NAME([this]() -> u8 { return m_cio->intack_r(); }));
807 	map(0xffffb, 0xffffb).lr8(NAME([this]() -> u8 { return m_dart->m1_r(); }));
808 	map(0xfffff, 0xfffff).lr8(NAME([this]() -> u8 { m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); return m68008_device::autovector(7); }));
809 }
810 
machine_start()811 void abc1600_state::machine_start()
812 {
813 	// state saving
814 	save_item(NAME(m_dmadis));
815 	save_item(NAME(m_sysscc));
816 	save_item(NAME(m_sysfs));
817 	save_item(NAME(m_partst));
818 	save_item(NAME(m_cs7));
819 	save_item(NAME(m_bus0));
820 	save_item(NAME(m_csb));
821 	save_item(NAME(m_atce));
822 	save_item(NAME(m_sccrq_a));
823 	save_item(NAME(m_sccrq_b));
824 	save_item(NAME(m_scc_irq));
825 	save_item(NAME(m_dart_irq));
826 }
827 
828 
machine_reset()829 void abc1600_state::machine_reset()
830 {
831 	// clear special control register
832 	for (int i = 0; i < 8; i++)
833 	{
834 		spec_contr_reg_w(i);
835 	}
836 
837 	// clear floppy registers
838 	fw0_w(0);
839 	fw1_w(0);
840 
841 	// clear NMI
842 	m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE);
843 }
844 
845 
846 
847 //**************************************************************************
848 //  MACHINE CONFIGURATION
849 //**************************************************************************
850 
851 //-------------------------------------------------
852 //  machine_config( abc1600 )
853 //-------------------------------------------------
854 
abc1600(machine_config & config)855 void abc1600_state::abc1600(machine_config &config)
856 {
857 	// basic machine hardware
858 	M68008(config, m_maincpu, 64_MHz_XTAL / 8);
859 	m_maincpu->set_addrmap(AS_PROGRAM, &abc1600_state::abc1600_mem);
860 	m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &abc1600_state::cpu_space_map);
861 
862 	// video hardware
863 	ABC1600_MOVER(config, ABC1600_MOVER_TAG, 0);
864 
865 	// devices
866 	ABC1600_MAC(config, m_mac, 0);
867 	m_mac->set_addrmap(AS_PROGRAM, &abc1600_state::mac_mem);
868 	m_mac->set_cpu_tag(m_maincpu);
869 
870 	Z80DMA(config, m_dma0, 64_MHz_XTAL / 16);
871 	m_dma0->out_busreq_callback().set(FUNC(abc1600_state::dbrq_w));
872 	m_dma0->out_bao_callback().set(m_dma1, FUNC(z80dma_device::bai_w));
873 	m_dma0->in_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma0_mreq_r));
874 	m_dma0->out_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma0_mreq_w));
875 	m_dma0->out_ieo_callback().set(m_bus0i, FUNC(abcbus_slot_device::prac_w));
876 	//m_dma0->out_ieo_callback().set(m_bus0x, FUNC(abcbus_slot_device::prac_w));
877 	m_dma0->in_iorq_callback().set(FUNC(abc1600_state::dma0_iorq_r));
878 	m_dma0->out_iorq_callback().set(FUNC(abc1600_state::dma0_iorq_w));
879 
880 	Z80DMA(config, m_dma1, 64_MHz_XTAL / 16);
881 	m_dma1->out_busreq_callback().set(FUNC(abc1600_state::dbrq_w));
882 	m_dma1->out_bao_callback().set(m_dma2, FUNC(z80dma_device::bai_w));
883 	m_dma1->in_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma1_mreq_r));
884 	m_dma1->out_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma1_mreq_w));
885 	m_dma1->out_ieo_callback().set(m_bus1, FUNC(abcbus_slot_device::prac_w));
886 	m_dma1->in_iorq_callback().set(FUNC(abc1600_state::dma1_iorq_r));
887 	m_dma1->out_iorq_callback().set(FUNC(abc1600_state::dma1_iorq_w));
888 
889 	Z80DMA(config, m_dma2, 64_MHz_XTAL / 16);
890 	m_dma2->out_busreq_callback().set(FUNC(abc1600_state::dbrq_w));
891 	m_dma2->in_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma2_mreq_r));
892 	m_dma2->out_mreq_callback().set(m_mac, FUNC(abc1600_mac_device::dma2_mreq_w));
893 	m_dma2->out_ieo_callback().set(m_bus2, FUNC(abcbus_slot_device::prac_w));
894 	m_dma2->in_iorq_callback().set(m_bus2, FUNC(abcbus_slot_device::read_tren));
895 	m_dma2->out_iorq_callback().set(m_bus2, FUNC(abcbus_slot_device::write_tren));
896 
897 	Z80DART(config, m_dart, 64_MHz_XTAL / 16);
898 	m_dart->out_int_callback().set(FUNC(abc1600_state::dart_irq_w));
899 	m_dart->out_txda_callback().set(RS232_PR_TAG, FUNC(rs232_port_device::write_txd));
900 	//m_dart->out_dtra_callback().set(RS232_PR_TAG, FUNC(rs232_port_device::write_dcd));
901 	//m_dart->out_rtsa_callback().set(RS232_PR_TAG, FUNC(rs232_port_device::write_cts));
902 	m_dart->out_txdb_callback().set(ABC_KEYBOARD_PORT_TAG, FUNC(abc_keyboard_port_device::txd_w));
903 
904 	abc_keyboard_port_device &kb(ABC_KEYBOARD_PORT(config, ABC_KEYBOARD_PORT_TAG, abc_keyboard_devices, "abc99"));
905 	kb.out_rx_handler().set(m_dart, FUNC(z80dart_device::rxb_w));
906 	kb.out_trxc_handler().set(m_dart, FUNC(z80dart_device::rxtxcb_w));
907 	kb.out_keydown_handler().set(m_dart, FUNC(z80dart_device::dcdb_w));
908 
909 	rs232_port_device &rs232pr(RS232_PORT(config, RS232_PR_TAG, default_rs232_devices, nullptr));
910 	rs232pr.rxd_handler().set(m_dart, FUNC(z80dart_device::rxa_w));
911 	//rs232pr.rts_handler().set(m_dart, FUNC(z80dart_device::ctsa_w));
912 	//rs232pr.dtr_handler().set(m_dart, FUNC(z80dart_device::dcda_w));
913 
914 	SCC8530N(config, m_scc, 64_MHz_XTAL / 16);
915 	m_scc->out_int_callback().set(FUNC(abc1600_state::scc_irq_w));
916 	m_scc->out_wreqa_callback().set(FUNC(abc1600_state::sccrq_a_w));
917 	m_scc->out_wreqb_callback().set(FUNC(abc1600_state::sccrq_b_w));
918 	m_scc->out_txda_callback().set(RS232_A_TAG, FUNC(rs232_port_device::write_txd));
919 	m_scc->out_dtra_callback().set(RS232_A_TAG, FUNC(rs232_port_device::write_dtr));
920 	m_scc->out_rtsa_callback().set(RS232_A_TAG, FUNC(rs232_port_device::write_rts));
921 	m_scc->out_txdb_callback().set(RS232_B_TAG, FUNC(rs232_port_device::write_txd));
922 	m_scc->out_dtrb_callback().set(RS232_B_TAG, FUNC(rs232_port_device::write_dtr));
923 	m_scc->out_rtsb_callback().set(RS232_B_TAG, FUNC(rs232_port_device::write_rts));
924 
925 	rs232_port_device &rs232a(RS232_PORT(config, RS232_A_TAG, default_rs232_devices, nullptr));
926 	rs232a.rxd_handler().set(m_scc, FUNC(scc8530_device::rxa_w));
927 	rs232a.cts_handler().set(m_scc, FUNC(scc8530_device::ctsa_w));
928 	rs232a.dcd_handler().set(m_scc, FUNC(scc8530_device::dcda_w));
929 	rs232a.ri_handler().set(m_scc, FUNC(scc8530_device::synca_w));
930 
931 	rs232_port_device &rs232b(RS232_PORT(config, RS232_B_TAG, default_rs232_devices, nullptr));
932 	rs232b.rxd_handler().set(m_scc, FUNC(scc8530_device::rxb_w));
933 	rs232b.cts_handler().set(m_scc, FUNC(scc8530_device::ctsb_w));
934 	rs232b.dcd_handler().set(m_scc, FUNC(scc8530_device::dcdb_w));
935 	rs232b.ri_handler().set(m_scc, FUNC(scc8530_device::syncb_w));
936 
937 	Z8536(config, m_cio, 64_MHz_XTAL / 16);
938 	m_cio->irq_wr_cb().set_inputline(MC68008P8_TAG, M68K_IRQ_2);
939 	m_cio->pa_rd_cb().set(FUNC(abc1600_state::cio_pa_r));
940 	m_cio->pb_rd_cb().set(FUNC(abc1600_state::cio_pb_r));
941 	m_cio->pb_wr_cb().set(FUNC(abc1600_state::cio_pb_w));
942 	m_cio->pc_rd_cb().set(FUNC(abc1600_state::cio_pc_r));
943 	m_cio->pc_wr_cb().set(FUNC(abc1600_state::cio_pc_w));
944 
945 	NMC9306(config, m_nvram, 0);
946 
947 	E0516(config, E050_C16PC_TAG, 32.768_kHz_XTAL);
948 
949 	FD1797(config, m_fdc, 64_MHz_XTAL / 64);
950 	m_fdc->intrq_wr_callback().set(m_cio, FUNC(z8536_device::pb7_w));
951 	m_fdc->drq_wr_callback().set(FUNC(abc1600_state::update_drdy0));
952 
953 	FLOPPY_CONNECTOR(config, SAB1797_02P_TAG":0", abc1600_floppies, nullptr, floppy_image_device::default_floppy_formats);
954 	FLOPPY_CONNECTOR(config, SAB1797_02P_TAG":1", abc1600_floppies, nullptr, floppy_image_device::default_floppy_formats);
955 	FLOPPY_CONNECTOR(config, SAB1797_02P_TAG":2", abc1600_floppies, "525qd", floppy_image_device::default_floppy_formats);
956 
957 	ABCBUS_SLOT(config, m_bus0i, 64_MHz_XTAL / 16, abc1600bus_cards, nullptr);
958 	m_bus0i->irq_callback().set(m_cio, FUNC(z8536_device::pa7_w));
959 	m_bus0i->pren_callback().set(FUNC(abc1600_state::update_pren0));
960 	m_bus0i->trrq_callback().set(FUNC(abc1600_state::update_drdy0));
961 
962 	ABCBUS_SLOT(config, m_bus0x, 64_MHz_XTAL / 16, abc1600bus_cards, nullptr);
963 	m_bus0x->irq_callback().set(m_cio, FUNC(z8536_device::pa6_w));
964 	m_bus0x->nmi_callback().set(FUNC(abc1600_state::nmi_w));
965 	m_bus0x->xint2_callback().set(m_cio, FUNC(z8536_device::pa2_w));
966 	m_bus0x->xint3_callback().set(m_cio, FUNC(z8536_device::pa3_w));
967 	m_bus0x->xint4_callback().set(m_cio, FUNC(z8536_device::pa4_w));
968 	m_bus0x->xint5_callback().set(m_cio, FUNC(z8536_device::pa5_w));
969 	m_bus0x->pren_callback().set(FUNC(abc1600_state::update_pren0));
970 	m_bus0x->trrq_callback().set(FUNC(abc1600_state::update_drdy0));
971 
972 	ABCBUS_SLOT(config, m_bus1, 64_MHz_XTAL / 16, abc1600bus_cards, nullptr);
973 	m_bus1->irq_callback().set(m_cio, FUNC(z8536_device::pa1_w));
974 	m_bus1->pren_callback().set(FUNC(abc1600_state::update_pren1));
975 	m_bus1->trrq_callback().set(FUNC(abc1600_state::update_drdy1));
976 
977 	ABCBUS_SLOT(config, m_bus2, 64_MHz_XTAL / 16, abc1600bus_cards, "4105");
978 	m_bus2->irq_callback().set(m_cio, FUNC(z8536_device::pa0_w));
979 	m_bus2->pren_callback().set(m_dma2, FUNC(z80dma_device::iei_w));
980 	m_bus2->trrq_callback().set(m_dma2, FUNC(z80dma_device::rdy_w));
981 
982 	// internal ram
983 	RAM(config, RAM_TAG).set_default_size("1M");
984 
985 	// software list
986 	SOFTWARE_LIST(config, "flop_list").set_original("abc1600");
987 }
988 
989 
990 
991 //**************************************************************************
992 //  ROMS
993 //**************************************************************************
994 
995 //-------------------------------------------------
996 //  ROM( abc1600 )
997 //-------------------------------------------------
998 
999 ROM_START( abc1600 )
1000 	ROM_REGION( 0x71c, "plds", 0 )
1001 	ROM_LOAD( "1020 6490349-01.8b",  0x104, 0x104, CRC(1fa065eb) SHA1(20a95940e39fa98e97e59ea1e548ac2e0c9a3444) ) // PAL16L8A expansion bus strobes
1002 	ROM_LOAD( "1021 6490350-01.5d",  0x208, 0x104, CRC(96f6f44b) SHA1(12d1cd153dcc99d1c4a6c834122f370d49723674) ) // PAL16L8 interrupt encoder and ROM/RAM control
1003 	ROM_LOAD( "1023 6490352-01.11e", 0x410, 0x104, CRC(a2f350ac) SHA1(77e08654a197080fa2111bc3031cd2c7699bf82b) ) // PAL16R6 interrupt acknowledge
1004 	ROM_LOAD( "1024 6490353-01.12e", 0x514, 0x104, CRC(67f1328a) SHA1(b585495fe14a7ae2fbb29f722dca106d59325002) ) // PAL16R4 expansion bus timing and control
1005 	ROM_LOAD( "1025 6490354-01.6e",  0x618, 0x104, CRC(9bda0468) SHA1(ad373995dcc18532274efad76fa80bd13c23df25) ) // PAL16R4 DMA transfer
1006 ROM_END
1007 
1008 
1009 
1010 //**************************************************************************
1011 //  SYSTEM DRIVERS
1012 //**************************************************************************
1013 
1014 //    YEAR  NAME     PARENT  COMPAT  MACHINE  INPUT    CLASS          INIT        COMPANY  FULLNAME    FLAGS
1015 COMP( 1985, abc1600, 0,      0,      abc1600, abc1600, abc1600_state, empty_init, "Luxor", "ABC 1600", MACHINE_NOT_WORKING )
1016