1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /*
4
5 Wang Professional Computer
6
7 http://www.seasip.info/VintagePC/wangpc.html
8
9 chdman -createblankhd q540.chd 512 8 17 512
10
11 */
12
13 /*
14
15 TODO:
16
17 - with quantum perfect cpu gets stuck @ 49c3 mov ss,cs:[52ah]
18 - hard disk
19
20 */
21
22 #include "emu.h"
23 #include "softlist.h"
24 #include "bus/centronics/ctronics.h"
25 #include "bus/rs232/rs232.h"
26 #include "bus/wangpc/wangpc.h"
27 #include "cpu/i86/i86.h"
28 #include "formats/pc_dsk.h"
29 #include "imagedev/floppy.h"
30 #include "machine/am9517a.h"
31 #include "machine/i8255.h"
32 #include "machine/im6402.h"
33 #include "machine/pit8253.h"
34 #include "machine/pic8259.h"
35 #include "machine/scn_pci.h"
36 #include "machine/ram.h"
37 #include "machine/upd765.h"
38 #include "machine/wangpckb.h"
39
40 #define I8086_TAG "i8086"
41 #define AM9517A_TAG "am9517a"
42 #define I8259A_TAG "i8259"
43 #define I8255A_TAG "i8255a"
44 #define I8253_TAG "i8253"
45 #define IM6402_TAG "im6402"
46 #define SCN2661_TAG "scn2661"
47 #define UPD765_TAG "upd765"
48 #define CENTRONICS_TAG "centronics"
49 #define RS232_TAG "rs232"
50 #define WANGPC_KEYBOARD_TAG "wangpckb"
51 #define LED_DIAGNOSTIC "led0"
52
53 class wangpc_state : public driver_device
54 {
55 public:
56 // constructor
wangpc_state(const machine_config & mconfig,device_type type,const char * tag)57 wangpc_state(const machine_config &mconfig, device_type type, const char *tag) :
58 driver_device(mconfig, type, tag),
59 m_maincpu(*this, I8086_TAG),
60 m_dmac(*this, AM9517A_TAG),
61 m_pic(*this, I8259A_TAG),
62 m_ppi(*this, I8255A_TAG),
63 m_pit(*this, I8253_TAG),
64 m_uart(*this, IM6402_TAG),
65 m_epci(*this, SCN2661_TAG),
66 m_fdc(*this, UPD765_TAG),
67 m_ram(*this, RAM_TAG),
68 m_floppy0(*this, UPD765_TAG ":0:525dd"),
69 m_floppy1(*this, UPD765_TAG ":1:525dd"),
70 m_centronics(*this, CENTRONICS_TAG),
71 m_cent_data_in(*this, "cent_data_in"),
72 m_cent_data_out(*this, "cent_data_out"),
73 m_bus(*this, "wangpcbus"),
74 m_sw(*this, "SW"),
75 m_led_diagnostic(*this, LED_DIAGNOSTIC),
76 m_timer2_irq(1),
77 m_centronics_ack(1),
78 m_dav(1),
79 m_dma_eop(1),
80 m_uart_dr(0),
81 m_uart_tbre(0),
82 m_fpu_irq(0),
83 m_bus_irq2(0),
84 m_enable_eop(0),
85 m_disable_dreq2(0),
86 m_fdc_drq(0),
87 m_fdc_dd0(0),
88 m_fdc_dd1(0),
89 m_fdc_tc(0),
90 m_ds1(false),
91 m_ds2(false)
92 {
93 }
94
95 void wangpc(machine_config &config);
96
97 private:
98 required_device<cpu_device> m_maincpu;
99 required_device<am9517a_device> m_dmac;
100 required_device<pic8259_device> m_pic;
101 required_device<i8255_device> m_ppi;
102 required_device<pit8253_device> m_pit;
103 required_device<im6402_device> m_uart;
104 required_device<scn_pci_device> m_epci;
105 required_device<upd765a_device> m_fdc;
106 required_device<ram_device> m_ram;
107 required_device<floppy_image_device> m_floppy0;
108 required_device<floppy_image_device> m_floppy1;
109 required_device<centronics_device> m_centronics;
110 required_device<input_buffer_device> m_cent_data_in;
111 required_device<output_latch_device> m_cent_data_out;
112 required_device<wangpcbus_device> m_bus;
113 required_ioport m_sw;
114 output_finder<> m_led_diagnostic;
115
116 virtual void machine_start() override;
117 virtual void machine_reset() override;
118
119 void select_drive();
120 void check_level1_interrupts();
121 void check_level2_interrupts();
122 void update_fdc_drq();
123 void update_fdc_tc();
124
125 void fdc_ctrl_w(uint8_t data);
126 uint8_t deselect_drive1_r();
127 void deselect_drive1_w(uint8_t data);
128 uint8_t select_drive1_r();
129 void select_drive1_w(uint8_t data);
130 uint8_t deselect_drive2_r();
131 void deselect_drive2_w(uint8_t data);
132 uint8_t select_drive2_r();
133 void select_drive2_w(uint8_t data);
134 uint8_t motor1_off_r();
135 void motor1_off_w(uint8_t data);
136 uint8_t motor1_on_r();
137 void motor1_on_w(uint8_t data);
138 uint8_t motor2_off_r();
139 void motor2_off_w(uint8_t data);
140 uint8_t motor2_on_r();
141 void motor2_on_w(uint8_t data);
142 uint8_t fdc_reset_r();
143 void fdc_reset_w(uint8_t data);
144 uint8_t fdc_tc_r();
145 void fdc_tc_w(uint8_t data);
146 void dma_page_w(offs_t offset, uint8_t data);
147 uint8_t status_r();
148 void timer0_irq_clr_w(uint8_t data);
149 uint8_t timer2_irq_clr_r();
150 void nmi_mask_w(uint8_t data);
151 uint8_t led_on_r();
152 void fpu_mask_w(uint8_t data);
153 uint8_t dma_eop_clr_r();
154 void uart_tbre_clr_w(uint8_t data);
155 uint8_t uart_r();
156 void uart_w(uint8_t data);
157 uint8_t centronics_r();
158 void centronics_w(uint8_t data);
159 uint8_t busy_clr_r();
160 void acknlg_clr_w(uint8_t data);
161 uint8_t led_off_r();
162 void parity_nmi_clr_w(uint8_t data);
163 uint8_t option_id_r();
164
165 DECLARE_WRITE_LINE_MEMBER( hrq_w );
166 DECLARE_WRITE_LINE_MEMBER( eop_w );
167 uint8_t memr_r(offs_t offset);
168 void memw_w(offs_t offset, uint8_t data);
169 uint8_t ior2_r();
170 void iow2_w(uint8_t data);
171 DECLARE_WRITE_LINE_MEMBER( dack0_w );
172 DECLARE_WRITE_LINE_MEMBER( dack1_w );
173 DECLARE_WRITE_LINE_MEMBER( dack2_w );
174 DECLARE_WRITE_LINE_MEMBER( dack3_w );
175 uint8_t ppi_pa_r();
176 uint8_t ppi_pb_r();
177 uint8_t ppi_pc_r();
178 void ppi_pc_w(uint8_t data);
179 DECLARE_WRITE_LINE_MEMBER( pit2_w );
180 DECLARE_WRITE_LINE_MEMBER( uart_dr_w );
181 DECLARE_WRITE_LINE_MEMBER( uart_tbre_w );
182 DECLARE_WRITE_LINE_MEMBER( epci_irq_w );
183 DECLARE_WRITE_LINE_MEMBER( write_centronics_ack );
184 DECLARE_WRITE_LINE_MEMBER( write_centronics_busy );
185 DECLARE_WRITE_LINE_MEMBER( write_centronics_fault );
186 DECLARE_WRITE_LINE_MEMBER( write_centronics_perror );
187 DECLARE_WRITE_LINE_MEMBER( bus_irq2_w );
188
189 DECLARE_FLOPPY_FORMATS( floppy_formats );
190
191 DECLARE_WRITE_LINE_MEMBER( fdc_irq );
192 DECLARE_WRITE_LINE_MEMBER( fdc_drq );
193
194 image_init_result on_disk0_load(floppy_image_device *image);
195 void on_disk0_unload(floppy_image_device *image);
196 image_init_result on_disk1_load(floppy_image_device *image);
197 void on_disk1_unload(floppy_image_device *image);
198
199 void wangpc_io(address_map &map);
200 void wangpc_mem(address_map &map);
201
202 uint8_t m_dma_page[4];
203 int m_dack;
204
205 int m_timer2_irq;
206 int m_centronics_ack;
207 int m_centronics_busy;
208 int m_centronics_fault;
209 int m_centronics_perror;
210 int m_dav;
211 int m_dma_eop;
212 int m_uart_dr;
213 int m_uart_tbre;
214 int m_fpu_irq;
215 int m_bus_irq2;
216
217 int m_enable_eop;
218 int m_disable_dreq2;
219 int m_fdc_drq;
220 int m_fdc_dd0;
221 int m_fdc_dd1;
222 int m_fdc_tc;
223 int m_ds1;
224 int m_ds2;
225
226 int m_led[6];
227 };
228
229
230
231 //**************************************************************************
232 // MACROS/CONSTANTS
233 //**************************************************************************
234
235 #define LOG 0
236
237
238
239 //**************************************************************************
240 // IMPLEMENTATION
241 //**************************************************************************
242
select_drive()243 void wangpc_state::select_drive()
244 {
245 floppy_image_device *floppy = nullptr;
246
247 if (m_ds1) floppy = m_floppy0;
248 if (m_ds2) floppy = m_floppy1;
249
250 m_fdc->set_floppy(floppy);
251 }
252
fdc_ctrl_w(uint8_t data)253 void wangpc_state::fdc_ctrl_w(uint8_t data)
254 {
255 /*
256
257 bit description
258
259 0 Enable /EOP
260 1 Disable /DREQ2
261 2 Clear drive 1 door disturbed interrupt
262 3 Clear drive 2 door disturbed interrupt
263 4
264 5
265 6
266 7
267
268 */
269
270 m_enable_eop = BIT(data, 0);
271 m_disable_dreq2 = BIT(data, 1);
272
273 if (BIT(data, 2)) m_fdc_dd0 = 0;
274 if (BIT(data, 3)) m_fdc_dd1 = 0;
275
276 if (LOG)
277 {
278 logerror("%s: Enable /EOP %u\n", machine().describe_context(), m_enable_eop);
279 logerror("%s: Disable /DREQ2 %u\n", machine().describe_context(), m_disable_dreq2);
280 }
281
282 update_fdc_tc();
283 update_fdc_drq();
284 }
285
286
deselect_drive1_r()287 uint8_t wangpc_state::deselect_drive1_r()
288 {
289 m_ds1 = false;
290 select_drive();
291
292 return 0xff;
293 }
294
deselect_drive1_w(uint8_t data)295 void wangpc_state::deselect_drive1_w(uint8_t data)
296 {
297 deselect_drive1_r();
298 }
299
select_drive1_r()300 uint8_t wangpc_state::select_drive1_r()
301 {
302 m_ds1 = true;
303 select_drive();
304
305 return 0xff;
306 }
307
select_drive1_w(uint8_t data)308 void wangpc_state::select_drive1_w(uint8_t data)
309 {
310 select_drive1_r();
311 }
312
deselect_drive2_r()313 uint8_t wangpc_state::deselect_drive2_r()
314 {
315 m_ds2 = false;
316 select_drive();
317
318 return 0xff;
319 }
320
deselect_drive2_w(uint8_t data)321 void wangpc_state::deselect_drive2_w(uint8_t data)
322 {
323 deselect_drive2_r();
324 }
325
select_drive2_r()326 uint8_t wangpc_state::select_drive2_r()
327 {
328 m_ds2 = true;
329 select_drive();
330
331 return 0xff;
332 }
333
select_drive2_w(uint8_t data)334 void wangpc_state::select_drive2_w(uint8_t data)
335 {
336 select_drive2_r();
337 }
338
motor1_off_r()339 uint8_t wangpc_state::motor1_off_r()
340 {
341 if (LOG) logerror("%s: Drive 1 motor OFF\n", machine().describe_context());
342
343 m_floppy0->mon_w(1);
344
345 return 0xff;
346 }
347
motor1_off_w(uint8_t data)348 void wangpc_state::motor1_off_w(uint8_t data)
349 {
350 motor1_off_r();
351 }
352
motor1_on_r()353 uint8_t wangpc_state::motor1_on_r()
354 {
355 if (LOG) logerror("%s: Drive 1 motor ON\n", machine().describe_context());
356
357 m_floppy0->mon_w(0);
358
359 return 0xff;
360 }
361
motor1_on_w(uint8_t data)362 void wangpc_state::motor1_on_w(uint8_t data)
363 {
364 motor1_on_r();
365 }
366
motor2_off_r()367 uint8_t wangpc_state::motor2_off_r()
368 {
369 if (LOG) logerror("%s: Drive 2 motor OFF\n", machine().describe_context());
370
371 m_floppy1->mon_w(1);
372
373 return 0xff;
374 }
375
motor2_off_w(uint8_t data)376 void wangpc_state::motor2_off_w(uint8_t data)
377 {
378 motor2_off_r();
379 }
380
motor2_on_r()381 uint8_t wangpc_state::motor2_on_r()
382 {
383 if (LOG) logerror("%s: Drive 2 motor ON\n", machine().describe_context());
384
385 m_floppy1->mon_w(0);
386
387 return 0xff;
388 }
389
motor2_on_w(uint8_t data)390 void wangpc_state::motor2_on_w(uint8_t data)
391 {
392 motor2_on_r();
393 }
394
fdc_reset_r()395 uint8_t wangpc_state::fdc_reset_r()
396 {
397 if (LOG) logerror("%s: FDC reset\n", machine().describe_context());
398
399 m_fdc->reset();
400
401 return 0xff;
402 }
403
fdc_reset_w(uint8_t data)404 void wangpc_state::fdc_reset_w(uint8_t data)
405 {
406 fdc_reset_r();
407 }
408
fdc_tc_r()409 uint8_t wangpc_state::fdc_tc_r()
410 {
411 if (LOG) logerror("%s: FDC TC\n", machine().describe_context());
412
413 m_fdc->tc_w(1);
414 m_fdc->tc_w(0);
415
416 return 0xff;
417 }
418
fdc_tc_w(uint8_t data)419 void wangpc_state::fdc_tc_w(uint8_t data)
420 {
421 fdc_tc_r();
422 }
423
424
425 //-------------------------------------------------
426 // dma_page_w -
427 //-------------------------------------------------
428
dma_page_w(offs_t offset,uint8_t data)429 void wangpc_state::dma_page_w(offs_t offset, uint8_t data)
430 {
431 if (LOG) logerror("%s: DMA page %u: %06x\n", machine().describe_context(), offset + 1, (data & 0x0f) << 16);
432
433 m_dma_page[offset + 1] = data & 0x0f;
434 }
435
436
437 //-------------------------------------------------
438 // status_r -
439 //-------------------------------------------------
440
status_r()441 uint8_t wangpc_state::status_r()
442 {
443 /*
444
445 bit description
446
447 0 Memory Parity Flag
448 1 I/O Error Flag
449 2 Unassigned
450 3 FDC Interrupt Flag
451 4 Door disturbed on drive 1
452 5 Door disturbed on drive 2
453 6 Door open on drive 1
454 7 Door open on drive 2
455
456 */
457
458 uint8_t data = 0x03;
459
460 // floppy interrupts
461 data |= m_fdc->get_irq() << 3;
462 data |= m_fdc_dd0 << 4;
463 data |= m_fdc_dd1 << 5;
464 data |= m_floppy0->exists() ? 0 : 0x40;
465 data |= m_floppy1->exists() ? 0 : 0x80;
466
467 return data;
468 }
469
470
471 //-------------------------------------------------
472 // timer0_int_clr_w -
473 //-------------------------------------------------
474
timer0_irq_clr_w(uint8_t data)475 void wangpc_state::timer0_irq_clr_w(uint8_t data)
476 {
477 //if (LOG) logerror("%s: Timer 0 IRQ clear\n", machine().describe_context());
478
479 m_pic->ir0_w(CLEAR_LINE);
480 }
481
482
483 //-------------------------------------------------
484 // timer2_irq_clr_r -
485 //-------------------------------------------------
486
timer2_irq_clr_r()487 uint8_t wangpc_state::timer2_irq_clr_r()
488 {
489 //if (LOG) logerror("%s: Timer 2 IRQ clear\n", machine().describe_context());
490
491 m_timer2_irq = 1;
492 check_level1_interrupts();
493
494 return 0xff;
495 }
496
497
498 //-------------------------------------------------
499 // nmi_mask_w -
500 //-------------------------------------------------
501
nmi_mask_w(uint8_t data)502 void wangpc_state::nmi_mask_w(uint8_t data)
503 {
504 if (LOG) logerror("%s: NMI mask %02x\n", machine().describe_context(), data);
505 }
506
507
508 //-------------------------------------------------
509 // led_on_r -
510 //-------------------------------------------------
511
led_on_r()512 uint8_t wangpc_state::led_on_r()
513 {
514 if (LOG) logerror("%s: Diagnostic LED on\n", machine().describe_context());
515
516 m_led_diagnostic = 1;
517
518 return 0xff;
519 }
520
521
522 //-------------------------------------------------
523 // fpu_mask_w -
524 //-------------------------------------------------
525
fpu_mask_w(uint8_t data)526 void wangpc_state::fpu_mask_w(uint8_t data)
527 {
528 if (LOG) logerror("%s: FPU mask %02x\n", machine().describe_context(), data);
529 }
530
531
532 //-------------------------------------------------
533 // dma_eop_clr_r -
534 //-------------------------------------------------
535
dma_eop_clr_r()536 uint8_t wangpc_state::dma_eop_clr_r()
537 {
538 if (LOG) logerror("%s: EOP clear\n", machine().describe_context());
539
540 m_dma_eop = 1;
541
542 check_level2_interrupts();
543
544 return 0xff;
545 }
546
547
548 //-------------------------------------------------
549 // uart_tbre_clr_w -
550 //-------------------------------------------------
551
uart_tbre_clr_w(uint8_t data)552 void wangpc_state::uart_tbre_clr_w(uint8_t data)
553 {
554 if (LOG) logerror("%s: TBRE clear\n", machine().describe_context());
555
556 m_uart_tbre = 0;
557
558 check_level2_interrupts();
559 }
560
561
562 //-------------------------------------------------
563 // uart_r -
564 //-------------------------------------------------
565
uart_r()566 uint8_t wangpc_state::uart_r()
567 {
568 m_uart_dr = 0;
569
570 check_level2_interrupts();
571
572 uint8_t data = m_uart->read();
573
574 if (LOG) logerror("%s: UART read %02x\n", machine().describe_context(), data);
575
576 return data;
577 }
578
579
580 //-------------------------------------------------
581 // uart_w -
582 //-------------------------------------------------
583
uart_w(uint8_t data)584 void wangpc_state::uart_w(uint8_t data)
585 {
586 if (LOG) logerror("%s: UART write %02x\n", machine().describe_context(), data);
587
588 switch (data)
589 {
590 case 0x10: m_led[0] = 1; break;
591 case 0x11: m_led[0] = 0; break;
592 case 0x12: m_led[1] = 1; break;
593 case 0x13: m_led[1] = 0; break;
594 case 0x14: m_led[2] = 1; break;
595 case 0x15: m_led[2] = 0; break;
596 case 0x16: m_led[3] = 1; break;
597 case 0x17: m_led[3] = 0; break;
598 case 0x18: m_led[4] = 1; break;
599 case 0x19: m_led[4] = 0; break;
600 case 0x1a: m_led[5] = 1; break;
601 case 0x1b: m_led[5] = 0; break;
602 case 0x1c: m_led[0] = m_led[1] = m_led[2] = m_led[3] = m_led[4] = m_led[5] = 1; break;
603 case 0x1d: m_led[0] = m_led[1] = m_led[2] = m_led[3] = m_led[4] = m_led[5] = 0; break;
604 }
605
606 if (LOG) popmessage("%u%u%u%u%u%u", m_led[0], m_led[1], m_led[2], m_led[3], m_led[4], m_led[5]);
607
608 m_uart_tbre = 0;
609 check_level2_interrupts();
610
611 m_uart->write(data);
612 }
613
614
615 //-------------------------------------------------
616 // centronics_r -
617 //-------------------------------------------------
618
centronics_r()619 uint8_t wangpc_state::centronics_r()
620 {
621 m_dav = 1;
622 check_level1_interrupts();
623
624 return m_cent_data_in->read();
625 }
626
627
628 //-------------------------------------------------
629 // centronics_w -
630 //-------------------------------------------------
631
centronics_w(uint8_t data)632 void wangpc_state::centronics_w(uint8_t data)
633 {
634 m_centronics_ack = 1;
635 check_level1_interrupts();
636
637 m_cent_data_out->write(data);
638
639 m_centronics->write_strobe(0);
640 m_centronics->write_strobe(1);
641 }
642
643
644 //-------------------------------------------------
645 // busy_clr_r -
646 //-------------------------------------------------
647
busy_clr_r()648 uint8_t wangpc_state::busy_clr_r()
649 {
650 if (LOG) logerror("%s: BUSY clear\n", machine().describe_context());
651
652 m_centronics_busy = 0;
653 check_level1_interrupts();
654
655 return 0xff;
656 }
657
658
659 //-------------------------------------------------
660 // acknlg_clr_w -
661 //-------------------------------------------------
662
acknlg_clr_w(uint8_t data)663 void wangpc_state::acknlg_clr_w(uint8_t data)
664 {
665 if (LOG) logerror("%s: ACKNLG clear\n", machine().describe_context());
666
667 m_centronics_ack = 1;
668 check_level1_interrupts();
669 }
670
671
672 //-------------------------------------------------
673 // led_off_r -
674 //-------------------------------------------------
675
led_off_r()676 uint8_t wangpc_state::led_off_r()
677 {
678 if (LOG) logerror("%s: Diagnostic LED off\n", machine().describe_context());
679
680 m_led_diagnostic = 0;
681
682 return 0xff;
683 }
684
685
686 //-------------------------------------------------
687 // parity_nmi_clr_w -
688 //-------------------------------------------------
689
parity_nmi_clr_w(uint8_t data)690 void wangpc_state::parity_nmi_clr_w(uint8_t data)
691 {
692 if (LOG) logerror("%s: Parity NMI clear\n", machine().describe_context());
693 }
694
695
696 //-------------------------------------------------
697 // option_id_r -
698 //-------------------------------------------------
699
option_id_r()700 uint8_t wangpc_state::option_id_r()
701 {
702 /*
703
704 bit description
705
706 0
707 1
708 2
709 3
710 4
711 5
712 6
713 7 FDC Interrupt Flag
714
715 */
716
717 uint8_t data = 0;
718
719 // FDC interrupt
720 data |= (m_fdc_dd0 || m_fdc_dd1 || (int) m_fdc->get_irq()) << 7;
721
722 return data;
723 }
724
725
726
727 //**************************************************************************
728 // ADDRESS MAPS
729 //**************************************************************************
730
731 //-------------------------------------------------
732 // ADDRESS_MAP( wangpc_mem )
733 //-------------------------------------------------
734
wangpc_mem(address_map & map)735 void wangpc_state::wangpc_mem(address_map &map)
736 {
737 map.unmap_value_high();
738 map(0x00000, 0x1ffff).ram();
739 map(0x40000, 0xf3fff).rw(m_bus, FUNC(wangpcbus_device::mrdc_r), FUNC(wangpcbus_device::amwc_w));
740 map(0xfc000, 0xfffff).rom().region(I8086_TAG, 0);
741 }
742
743
744 //-------------------------------------------------
745 // ADDRESS_MAP( wangpc_io )
746 //-------------------------------------------------
747
wangpc_io(address_map & map)748 void wangpc_state::wangpc_io(address_map &map)
749 {
750 map.unmap_value_high();
751 map(0x1000, 0x1000).w(FUNC(wangpc_state::fdc_ctrl_w));
752 map(0x1004, 0x1004).rw(FUNC(wangpc_state::deselect_drive1_r), FUNC(wangpc_state::deselect_drive1_w));
753 map(0x1006, 0x1006).rw(FUNC(wangpc_state::select_drive1_r), FUNC(wangpc_state::select_drive1_w));
754 map(0x1008, 0x1008).rw(FUNC(wangpc_state::deselect_drive2_r), FUNC(wangpc_state::deselect_drive2_w));
755 map(0x100a, 0x100a).rw(FUNC(wangpc_state::select_drive2_r), FUNC(wangpc_state::select_drive2_w));
756 map(0x100c, 0x100c).rw(FUNC(wangpc_state::motor1_off_r), FUNC(wangpc_state::motor1_off_w));
757 map(0x100e, 0x100e).rw(FUNC(wangpc_state::motor1_on_r), FUNC(wangpc_state::motor1_on_w));
758 map(0x1010, 0x1010).rw(FUNC(wangpc_state::motor2_off_r), FUNC(wangpc_state::motor2_off_w));
759 map(0x1012, 0x1012).rw(FUNC(wangpc_state::motor2_on_r), FUNC(wangpc_state::motor2_on_w));
760 map(0x1014, 0x1017).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff);
761 map(0x1018, 0x1018).mirror(0x0002).rw(FUNC(wangpc_state::fdc_reset_r), FUNC(wangpc_state::fdc_reset_w));
762 map(0x101c, 0x101c).mirror(0x0002).rw(FUNC(wangpc_state::fdc_tc_r), FUNC(wangpc_state::fdc_tc_w));
763 map(0x1020, 0x1027).rw(m_ppi, FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0x00ff);
764 map(0x1028, 0x1029); //.w(FUNC(wangpc_state::)); (?)
765 map(0x1040, 0x1047).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write)).umask16(0x00ff);
766 map(0x1060, 0x1063).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
767 map(0x1080, 0x1087).r(m_epci, FUNC(scn_pci_device::read)).umask16(0x00ff);
768 map(0x1088, 0x108f).w(m_epci, FUNC(scn_pci_device::write)).umask16(0x00ff);
769 map(0x10a0, 0x10bf).rw(m_dmac, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask16(0x00ff);
770 map(0x10c2, 0x10c7).w(FUNC(wangpc_state::dma_page_w)).umask16(0x00ff);
771 map(0x10e0, 0x10e0).rw(FUNC(wangpc_state::status_r), FUNC(wangpc_state::timer0_irq_clr_w));
772 map(0x10e2, 0x10e2).rw(FUNC(wangpc_state::timer2_irq_clr_r), FUNC(wangpc_state::nmi_mask_w));
773 map(0x10e4, 0x10e4).rw(FUNC(wangpc_state::led_on_r), FUNC(wangpc_state::fpu_mask_w));
774 map(0x10e6, 0x10e6).rw(FUNC(wangpc_state::dma_eop_clr_r), FUNC(wangpc_state::uart_tbre_clr_w));
775 map(0x10e8, 0x10e8).rw(FUNC(wangpc_state::uart_r), FUNC(wangpc_state::uart_w));
776 map(0x10ea, 0x10ea).rw(FUNC(wangpc_state::centronics_r), FUNC(wangpc_state::centronics_w));
777 map(0x10ec, 0x10ec).rw(FUNC(wangpc_state::busy_clr_r), FUNC(wangpc_state::acknlg_clr_w));
778 map(0x10ee, 0x10ee).rw(FUNC(wangpc_state::led_off_r), FUNC(wangpc_state::parity_nmi_clr_w));
779 map(0x10fe, 0x10fe).r(FUNC(wangpc_state::option_id_r));
780 map(0x1100, 0x1fff).rw(m_bus, FUNC(wangpcbus_device::sad_r), FUNC(wangpcbus_device::sad_w));
781 }
782
783
784
785 //**************************************************************************
786 // INPUT PORTS
787 //**************************************************************************
788
789 //-------------------------------------------------
790 // INPUT_PORTS( wangpc )
791 //-------------------------------------------------
792
793 static INPUT_PORTS_START( wangpc )
794 // keyboard defined in machine/wangpckb.c
795
796 PORT_START("SW")
797 PORT_DIPNAME( 0x0f, 0x0f, "CPU Baud Rate" ) PORT_DIPLOCATION("SW:1,2,3,4")
798 PORT_DIPSETTING( 0x0f, "19200" )
799 PORT_DIPSETTING( 0x0e, "9600" )
800 PORT_DIPSETTING( 0x0d, "7200" )
801 PORT_DIPSETTING( 0x0c, "4800" )
802 PORT_DIPSETTING( 0x0b, "3600" )
803 PORT_DIPSETTING( 0x0a, "2400" )
804 PORT_DIPSETTING( 0x09, "2000" )
805 PORT_DIPSETTING( 0x08, "1800" )
806 PORT_DIPSETTING( 0x07, "1200" )
807 PORT_DIPSETTING( 0x06, "600" )
808 PORT_DIPSETTING( 0x05, "300" )
809 PORT_DIPSETTING( 0x04, "150" )
810 PORT_DIPSETTING( 0x03, "134.5" )
811 PORT_DIPSETTING( 0x02, "110" )
812 PORT_DIPSETTING( 0x01, "75" )
813 PORT_DIPSETTING( 0x00, "50 (Loop on Power-Up)" )
814 INPUT_PORTS_END
815
816
817
818 //**************************************************************************
819 // DEVICE CONFIGURATION
820 //**************************************************************************
821
822 //-------------------------------------------------
823 // I8237
824 //-------------------------------------------------
825
update_fdc_tc()826 void wangpc_state::update_fdc_tc()
827 {
828 if (m_enable_eop)
829 m_fdc->tc_w(m_fdc_tc);
830 else
831 m_fdc->tc_w(0);
832 }
833
WRITE_LINE_MEMBER(wangpc_state::hrq_w)834 WRITE_LINE_MEMBER( wangpc_state::hrq_w )
835 {
836 m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
837
838 m_dmac->hack_w(state);
839 }
840
WRITE_LINE_MEMBER(wangpc_state::eop_w)841 WRITE_LINE_MEMBER( wangpc_state::eop_w )
842 {
843 if (m_dack == 2)
844 {
845 m_fdc_tc = state;
846 update_fdc_tc();
847 }
848
849 if (state)
850 {
851 if (LOG) logerror("EOP set\n");
852
853 m_dma_eop = 0;
854 check_level2_interrupts();
855 }
856
857 m_bus->tc_w(state);
858 }
859
memr_r(offs_t offset)860 uint8_t wangpc_state::memr_r(offs_t offset)
861 {
862 address_space &program = m_maincpu->space(AS_PROGRAM);
863 offs_t addr = (m_dma_page[m_dack] << 16) | offset;
864
865 return program.read_byte(addr);
866 }
867
memw_w(offs_t offset,uint8_t data)868 void wangpc_state::memw_w(offs_t offset, uint8_t data)
869 {
870 address_space &program = m_maincpu->space(AS_PROGRAM);
871 offs_t addr = (m_dma_page[m_dack] << 16) | offset;
872
873 program.write_byte(addr, data);
874 }
875
ior2_r()876 uint8_t wangpc_state::ior2_r()
877 {
878 if (m_disable_dreq2)
879 return m_bus->dack_r(2);
880 else
881 return m_fdc->dma_r();
882 }
883
iow2_w(uint8_t data)884 void wangpc_state::iow2_w(uint8_t data)
885 {
886 if (m_disable_dreq2)
887 m_bus->dack_w(2, data);
888 else
889 m_fdc->dma_w(data);
890 }
891
WRITE_LINE_MEMBER(wangpc_state::dack0_w)892 WRITE_LINE_MEMBER( wangpc_state::dack0_w )
893 {
894 if (!state) m_dack = 0;
895 }
896
WRITE_LINE_MEMBER(wangpc_state::dack1_w)897 WRITE_LINE_MEMBER( wangpc_state::dack1_w )
898 {
899 if (!state) m_dack = 1;
900 }
901
WRITE_LINE_MEMBER(wangpc_state::dack2_w)902 WRITE_LINE_MEMBER( wangpc_state::dack2_w )
903 {
904 if (!state) m_dack = 2;
905 }
906
WRITE_LINE_MEMBER(wangpc_state::dack3_w)907 WRITE_LINE_MEMBER( wangpc_state::dack3_w )
908 {
909 if (!state) m_dack = 3;
910 }
911
912 //-------------------------------------------------
913 // pic8259_interface pic_intf
914 //-------------------------------------------------
915
check_level1_interrupts()916 void wangpc_state::check_level1_interrupts()
917 {
918 int state = !m_timer2_irq || !m_epci->rxrdy_r() || !m_epci->txemt_dschg_r() || !m_centronics_ack || !m_dav || m_centronics_busy;
919
920 m_pic->ir1_w(state);
921 }
922
check_level2_interrupts()923 void wangpc_state::check_level2_interrupts()
924 {
925 int state = !m_dma_eop || m_uart_dr || m_uart_tbre || m_fdc_dd0 || m_fdc_dd1 || m_fdc->get_irq() || m_fpu_irq || m_bus_irq2;
926
927 m_pic->ir2_w(state);
928 }
929
930 //-------------------------------------------------
931 // I8255A INTERFACE
932 //-------------------------------------------------
933
ppi_pa_r()934 uint8_t wangpc_state::ppi_pa_r()
935 {
936 /*
937
938 bit description
939
940 0 /POWER ON
941 1 /SMART
942 2 /DATA AVAILABLE
943 3 SLCT
944 4 BUSY
945 5 /FAULT
946 6 PE
947 7 ACKNOWLEDGE
948
949 */
950
951 uint8_t data = 0x08 | 0x02 | 0x01;
952
953 data |= m_dav << 2;
954 data |= m_centronics_busy << 4;
955 data |= m_centronics_fault << 5;
956 data |= m_centronics_perror << 6;
957 data |= m_centronics_ack << 7;
958
959 return data;
960 }
961
ppi_pb_r()962 uint8_t wangpc_state::ppi_pb_r()
963 {
964 /*
965
966 bit description
967
968 0 /TIMER 2 INTERRUPT
969 1 /SERIAL INTERRUPT
970 2 /PARALLEL PORT INTERRUPT
971 3 /DMA INTERRUPT
972 4 KBD INTERRUPT TRANSMIT
973 5 KBD INTERRUPT RECEIVE
974 6 FLOPPY DISK INTERRUPT
975 7 8087 INTERRUPT
976
977 */
978
979 uint8_t data = 0;
980
981 // timer 2 interrupt
982 data |= m_timer2_irq;
983
984 // serial interrupt
985 data |= (m_epci->rxrdy_r() & m_epci->txemt_dschg_r()) << 1;
986
987 // parallel port interrupt
988 data |= m_centronics_ack << 2;
989
990 // DMA interrupt
991 data |= m_dma_eop << 3;
992
993 // keyboard interrupt
994 data |= m_uart_tbre << 4;
995 data |= m_uart_dr << 5;
996
997 // FDC interrupt
998 data |= m_fdc->get_irq() << 6;
999
1000 // 8087 interrupt
1001 data |= m_fpu_irq << 7;
1002
1003 return data;
1004 }
1005
ppi_pc_r()1006 uint8_t wangpc_state::ppi_pc_r()
1007 {
1008 /*
1009
1010 bit description
1011
1012 0
1013 1
1014 2
1015 3
1016 4 SW1
1017 5 SW2
1018 6 SW3
1019 7 SW4
1020
1021 */
1022
1023 return m_sw->read() << 4;
1024 }
1025
ppi_pc_w(uint8_t data)1026 void wangpc_state::ppi_pc_w(uint8_t data)
1027 {
1028 /*
1029
1030 bit description
1031
1032 0 /USR0 (pin 14)
1033 1 /USR1 (pin 36)
1034 2 /RESET (pin 31)
1035 3 Unassigned
1036 4
1037 5
1038 6
1039 7
1040
1041 */
1042
1043 m_centronics->write_autofd(BIT(data, 0));
1044 m_centronics->write_select_in(BIT(data, 1));
1045 m_centronics->write_init(BIT(data, 2));
1046 }
1047
WRITE_LINE_MEMBER(wangpc_state::pit2_w)1048 WRITE_LINE_MEMBER( wangpc_state::pit2_w )
1049 {
1050 if (state)
1051 {
1052 m_timer2_irq = 0;
1053 check_level1_interrupts();
1054 }
1055 }
1056
1057 //-------------------------------------------------
1058 // IM6402_INTERFACE( uart_intf )
1059 //-------------------------------------------------
1060
WRITE_LINE_MEMBER(wangpc_state::uart_dr_w)1061 WRITE_LINE_MEMBER( wangpc_state::uart_dr_w )
1062 {
1063 if (state)
1064 {
1065 if (LOG) logerror("DR set\n");
1066
1067 m_uart_dr = 1;
1068 check_level2_interrupts();
1069 }
1070 }
1071
WRITE_LINE_MEMBER(wangpc_state::uart_tbre_w)1072 WRITE_LINE_MEMBER( wangpc_state::uart_tbre_w )
1073 {
1074 if (state)
1075 {
1076 if (LOG) logerror("TBRE set\n");
1077
1078 m_uart_tbre = 1;
1079 check_level2_interrupts();
1080 }
1081 }
1082
1083
1084 //-------------------------------------------------
1085 // SCN2661_INTERFACE( epci_intf )
1086 //-------------------------------------------------
1087
WRITE_LINE_MEMBER(wangpc_state::epci_irq_w)1088 WRITE_LINE_MEMBER( wangpc_state::epci_irq_w )
1089 {
1090 check_level1_interrupts();
1091 }
1092
1093
1094 //-------------------------------------------------
1095 // upd765_interface fdc_intf
1096 //-------------------------------------------------
1097
wangpc_floppies(device_slot_interface & device)1098 static void wangpc_floppies(device_slot_interface &device)
1099 {
1100 device.option_add("525dd", FLOPPY_525_DD);
1101 }
1102
FLOPPY_FORMATS_MEMBER(wangpc_state::floppy_formats)1103 FLOPPY_FORMATS_MEMBER( wangpc_state::floppy_formats )
1104 FLOPPY_PC_FORMAT
1105 FLOPPY_FORMATS_END
1106
1107 WRITE_LINE_MEMBER( wangpc_state::fdc_irq )
1108 {
1109 if (LOG) logerror("FDC INT %u\n", state);
1110
1111 check_level2_interrupts();
1112 }
1113
WRITE_LINE_MEMBER(wangpc_state::fdc_drq)1114 WRITE_LINE_MEMBER( wangpc_state::fdc_drq )
1115 {
1116 if (LOG) logerror("FDC DRQ %u\n", state);
1117
1118 m_fdc_drq = state;
1119 update_fdc_drq();
1120 }
1121
update_fdc_drq()1122 void wangpc_state::update_fdc_drq()
1123 {
1124 if (m_disable_dreq2)
1125 m_dmac->dreq2_w(1);
1126 else
1127 m_dmac->dreq2_w(!m_fdc_drq);
1128 }
1129
1130
1131 //-------------------------------------------------
1132 // centronics_interface centronics_intf
1133 //-------------------------------------------------
1134
WRITE_LINE_MEMBER(wangpc_state::write_centronics_ack)1135 WRITE_LINE_MEMBER( wangpc_state::write_centronics_ack )
1136 {
1137 if (LOG) logerror("ACKNLG %u\n", state);
1138
1139 m_centronics_ack = state;
1140
1141 check_level1_interrupts();
1142 }
1143
WRITE_LINE_MEMBER(wangpc_state::write_centronics_busy)1144 WRITE_LINE_MEMBER( wangpc_state::write_centronics_busy )
1145 {
1146 if (LOG) logerror("BUSY %u\n", state);
1147
1148 m_centronics_busy = state;
1149
1150 check_level1_interrupts();
1151 }
1152
WRITE_LINE_MEMBER(wangpc_state::write_centronics_fault)1153 WRITE_LINE_MEMBER( wangpc_state::write_centronics_fault )
1154 {
1155 m_centronics_fault = state;
1156 }
1157
WRITE_LINE_MEMBER(wangpc_state::write_centronics_perror)1158 WRITE_LINE_MEMBER( wangpc_state::write_centronics_perror )
1159 {
1160 m_centronics_perror = state;
1161 }
1162
1163 //-------------------------------------------------
1164 // WANGPC_BUS_INTERFACE( kb_intf )
1165 //-------------------------------------------------
1166
WRITE_LINE_MEMBER(wangpc_state::bus_irq2_w)1167 WRITE_LINE_MEMBER( wangpc_state::bus_irq2_w )
1168 {
1169 if (LOG) logerror("Bus IRQ2 %u\n", state);
1170
1171 m_bus_irq2 = state;
1172
1173 check_level2_interrupts();
1174 }
1175
1176
1177
1178 //**************************************************************************
1179 // MACHINE INITIALIZATION
1180 //**************************************************************************
1181
1182 //-------------------------------------------------
1183 // MACHINE_START( wangpc )
1184 //-------------------------------------------------
1185
machine_start()1186 void wangpc_state::machine_start()
1187 {
1188 // connect floppy callbacks
1189 m_floppy0->setup_load_cb(floppy_image_device::load_cb(&wangpc_state::on_disk0_load, this));
1190 m_floppy0->setup_unload_cb(floppy_image_device::unload_cb(&wangpc_state::on_disk0_unload, this));
1191 m_floppy1->setup_load_cb(floppy_image_device::load_cb(&wangpc_state::on_disk1_load, this));
1192 m_floppy1->setup_unload_cb(floppy_image_device::unload_cb(&wangpc_state::on_disk1_unload, this));
1193
1194 m_led_diagnostic.resolve();
1195
1196 // state saving
1197 save_item(NAME(m_dma_page));
1198 save_item(NAME(m_dack));
1199 save_item(NAME(m_timer2_irq));
1200 save_item(NAME(m_centronics_ack));
1201 save_item(NAME(m_centronics_busy));
1202 save_item(NAME(m_centronics_fault));
1203 save_item(NAME(m_centronics_perror));
1204 save_item(NAME(m_dav));
1205 save_item(NAME(m_dma_eop));
1206 save_item(NAME(m_uart_dr));
1207 save_item(NAME(m_uart_tbre));
1208 save_item(NAME(m_fpu_irq));
1209 save_item(NAME(m_bus_irq2));
1210 save_item(NAME(m_enable_eop));
1211 save_item(NAME(m_disable_dreq2));
1212 save_item(NAME(m_fdc_drq));
1213 save_item(NAME(m_ds1));
1214 save_item(NAME(m_ds2));
1215 }
1216
1217
machine_reset()1218 void wangpc_state::machine_reset()
1219 {
1220 // initialize UART
1221 m_uart->cls1_w(1);
1222 m_uart->cls2_w(1);
1223 m_uart->pi_w(1);
1224 m_uart->sbs_w(1);
1225 m_uart->crl_w(1);
1226 }
1227
1228
1229 //-------------------------------------------------
1230 // on_disk0_change -
1231 //-------------------------------------------------
1232
on_disk0_load(floppy_image_device * image)1233 image_init_result wangpc_state::on_disk0_load(floppy_image_device *image)
1234 {
1235 on_disk0_unload(image);
1236
1237 return image_init_result::PASS;
1238 }
1239
on_disk0_unload(floppy_image_device * image)1240 void wangpc_state::on_disk0_unload(floppy_image_device *image)
1241 {
1242 if (LOG) logerror("Door 1 disturbed\n");
1243
1244 m_fdc_dd0 = 1;
1245 check_level2_interrupts();
1246 }
1247
1248
1249 //-------------------------------------------------
1250 // on_disk1_change -
1251 //-------------------------------------------------
1252
on_disk1_load(floppy_image_device * image)1253 image_init_result wangpc_state::on_disk1_load(floppy_image_device *image)
1254 {
1255 on_disk1_unload(image);
1256
1257 return image_init_result::PASS;
1258 }
1259
on_disk1_unload(floppy_image_device * image)1260 void wangpc_state::on_disk1_unload(floppy_image_device *image)
1261 {
1262 if (LOG) logerror("Door 2 disturbed\n");
1263
1264 m_fdc_dd1 = 1;
1265 check_level2_interrupts();
1266 }
1267
1268
1269
1270 //**************************************************************************
1271 // MACHINE DRIVERS
1272 //**************************************************************************
1273
1274 //-------------------------------------------------
1275 // machine_config( wangpc )
1276 //-------------------------------------------------
1277
wangpc(machine_config & config)1278 void wangpc_state::wangpc(machine_config &config)
1279 {
1280 I8086(config, m_maincpu, 8000000);
1281 m_maincpu->set_addrmap(AS_PROGRAM, &wangpc_state::wangpc_mem);
1282 m_maincpu->set_addrmap(AS_IO, &wangpc_state::wangpc_io);
1283 m_maincpu->set_irq_acknowledge_callback(I8259A_TAG, FUNC(pic8259_device::inta_cb));
1284 //config.m_perfect_cpu_quantum = subtag(I8086_TAG);
1285
1286 // devices
1287 AM9517A(config, m_dmac, 4000000);
1288 m_dmac->out_hreq_callback().set(FUNC(wangpc_state::hrq_w));
1289 m_dmac->out_eop_callback().set(FUNC(wangpc_state::eop_w));
1290 m_dmac->in_memr_callback().set(FUNC(wangpc_state::memr_r));
1291 m_dmac->out_memw_callback().set(FUNC(wangpc_state::memw_w));
1292 m_dmac->in_ior_callback<1>().set(m_bus, FUNC(wangpcbus_device::dack1_r));
1293 m_dmac->in_ior_callback<2>().set(FUNC(wangpc_state::ior2_r));
1294 m_dmac->in_ior_callback<3>().set(m_bus, FUNC(wangpcbus_device::dack3_r));
1295 m_dmac->out_iow_callback<1>().set(m_bus, FUNC(wangpcbus_device::dack1_w));
1296 m_dmac->out_iow_callback<2>().set(FUNC(wangpc_state::iow2_w));
1297 m_dmac->out_iow_callback<3>().set(m_bus, FUNC(wangpcbus_device::dack3_w));
1298 m_dmac->out_dack_callback<0>().set(FUNC(wangpc_state::dack0_w));
1299 m_dmac->out_dack_callback<1>().set(FUNC(wangpc_state::dack1_w));
1300 m_dmac->out_dack_callback<2>().set(FUNC(wangpc_state::dack2_w));
1301 m_dmac->out_dack_callback<3>().set(FUNC(wangpc_state::dack3_w));
1302
1303 PIC8259(config, m_pic, 0);
1304 m_pic->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
1305
1306 I8255A(config, m_ppi, 0);
1307 m_ppi->in_pa_callback().set(FUNC(wangpc_state::ppi_pa_r));
1308 m_ppi->in_pb_callback().set(FUNC(wangpc_state::ppi_pb_r));
1309 m_ppi->in_pc_callback().set(FUNC(wangpc_state::ppi_pc_r));
1310 m_ppi->out_pc_callback().set(FUNC(wangpc_state::ppi_pc_w));
1311
1312 PIT8253(config, m_pit, 0);
1313 m_pit->set_clk<0>(500000);
1314 m_pit->out_handler<0>().set(m_pic, FUNC(pic8259_device::ir0_w));
1315 m_pit->set_clk<1>(2000000);
1316 m_pit->set_clk<2>(500000);
1317 m_pit->out_handler<2>().set(FUNC(wangpc_state::pit2_w));
1318
1319 IM6402(config, m_uart, 62500*16, 62500*16);
1320 m_uart->tro_callback().set("wangpckb", FUNC(wangpc_keyboard_device::write_rxd));
1321 m_uart->dr_callback().set(FUNC(wangpc_state::uart_dr_w));
1322 m_uart->tbre_callback().set(FUNC(wangpc_state::uart_tbre_w));
1323
1324 SCN2661C(config, m_epci, 5'068'800);
1325 m_epci->txd_handler().set(RS232_TAG, FUNC(rs232_port_device::write_txd));
1326 m_epci->rxrdy_handler().set(FUNC(wangpc_state::epci_irq_w));
1327 m_epci->rts_handler().set(RS232_TAG, FUNC(rs232_port_device::write_rts));
1328 m_epci->dtr_handler().set(RS232_TAG, FUNC(rs232_port_device::write_dtr));
1329 m_epci->txemt_dschg_handler().set(FUNC(wangpc_state::epci_irq_w));
1330
1331 UPD765A(config, m_fdc, 8'000'000, false, false);
1332 m_fdc->intrq_wr_callback().set(FUNC(wangpc_state::fdc_irq));
1333 m_fdc->drq_wr_callback().set(FUNC(wangpc_state::fdc_drq));
1334 FLOPPY_CONNECTOR(config, UPD765_TAG ":0", wangpc_floppies, "525dd", wangpc_state::floppy_formats);
1335 FLOPPY_CONNECTOR(config, UPD765_TAG ":1", wangpc_floppies, "525dd", wangpc_state::floppy_formats);
1336
1337 CENTRONICS(config, m_centronics, centronics_devices, "printer");
1338 m_centronics->set_data_input_buffer(m_cent_data_in);
1339 m_centronics->ack_handler().set(FUNC(wangpc_state::write_centronics_ack));
1340 m_centronics->busy_handler().set(FUNC(wangpc_state::write_centronics_busy));
1341 m_centronics->fault_handler().set(FUNC(wangpc_state::write_centronics_fault));
1342 m_centronics->perror_handler().set(FUNC(wangpc_state::write_centronics_perror));
1343
1344 INPUT_BUFFER(config, m_cent_data_in);
1345
1346 OUTPUT_LATCH(config, m_cent_data_out);
1347 m_centronics->set_output_latch(*m_cent_data_out);
1348
1349 rs232_port_device &rs232(RS232_PORT(config, RS232_TAG, default_rs232_devices, nullptr));
1350 rs232.rxd_handler().set(m_epci, FUNC(scn_pci_device::rxd_w));
1351 rs232.cts_handler().set(m_epci, FUNC(scn_pci_device::cts_w));
1352 rs232.dsr_handler().set(m_epci, FUNC(scn_pci_device::dsr_w));
1353 rs232.dcd_handler().set(m_epci, FUNC(scn_pci_device::dcd_w));
1354
1355 WANGPC_KEYBOARD(config, "wangpckb").txd_handler().set(m_uart, FUNC(im6402_device::write_rri));
1356
1357 // bus
1358 WANGPC_BUS(config, m_bus, 0);
1359 m_bus->irq2_wr_callback().set(FUNC(wangpc_state::bus_irq2_w));
1360 m_bus->irq3_wr_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
1361 m_bus->irq4_wr_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
1362 m_bus->irq5_wr_callback().set(m_pic, FUNC(pic8259_device::ir5_w));
1363 m_bus->irq6_wr_callback().set(m_pic, FUNC(pic8259_device::ir6_w));
1364 m_bus->irq7_wr_callback().set(m_pic, FUNC(pic8259_device::ir7_w));
1365 m_bus->drq1_wr_callback().set(m_dmac, FUNC(am9517a_device::dreq1_w));
1366 m_bus->drq2_wr_callback().set(m_dmac, FUNC(am9517a_device::dreq2_w));
1367 m_bus->drq3_wr_callback().set(m_dmac, FUNC(am9517a_device::dreq3_w));
1368 m_bus->ioerror_wr_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
1369 WANGPC_BUS_SLOT(config, "slot1", m_bus, wangpc_cards, nullptr, 1);
1370 WANGPC_BUS_SLOT(config, "slot2", m_bus, wangpc_cards, "mvc", 2);
1371 WANGPC_BUS_SLOT(config, "slot3", m_bus, wangpc_cards, nullptr, 3);
1372 WANGPC_BUS_SLOT(config, "slot4", m_bus, wangpc_cards, nullptr, 4);
1373 WANGPC_BUS_SLOT(config, "slot5", m_bus, wangpc_cards, nullptr, 5);
1374
1375 // internal ram
1376 RAM(config, RAM_TAG).set_default_size("128K");
1377
1378 // software list
1379 SOFTWARE_LIST(config, "flop_list").set_original("wangpc");
1380 }
1381
1382
1383
1384 //**************************************************************************
1385 // ROM DEFINITIONS
1386 //**************************************************************************
1387
1388 //-------------------------------------------------
1389 // ROM( wangpc )
1390 //-------------------------------------------------
1391
1392 ROM_START( wangpc )
1393 ROM_REGION16_LE( 0x4000, I8086_TAG, 0)
1394 ROM_LOAD16_BYTE( "0001 r2.l94", 0x0001, 0x2000, CRC(f9f41304) SHA1(1815295809ef11573d724ede47446f9ac7aee713) )
1395 ROM_LOAD16_BYTE( "379-0000 r2.l115", 0x0000, 0x2000, CRC(67b37684) SHA1(70d9f68eb88cc2bc9f53f949cc77411c09a4266e) )
1396 ROM_END
1397
1398
1399
1400 //**************************************************************************
1401 // GAME DRIVERS
1402 //**************************************************************************
1403
1404 COMP( 1985, wangpc, 0, 0, wangpc, wangpc, wangpc_state, empty_init, "Wang Laboratories", "Wang Professional Computer", MACHINE_SUPPORTS_SAVE )
1405