1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /*
4
5 Amstrad PC1512
6
7 http://www.seasip.info/AmstradXT
8 http://stason.org/TULARC/pc/hard-drives-hdd/tandon/TM262-21MB-5-25-HH-MFM-ST506.html
9
10 */
11
12 /*
13
14 TODO:
15
16 - adjust mouse speed
17 - pc1512 V3 VDU check fails
18 - Amstrad SM2400 internal modem
19 - Amstrad RP4 diagnostic ISA card (PC1512)
20 - Amstrad RP5-2 diagnostic ISA card (PC1640)
21 - 40291/8908 B ROM on PC1640 HD30 controller card
22
23 */
24
25 /*
26 HARD DISC INSTALLATION INSTRUCTIONS
27
28 Applies to both ten and twenty megabyte versions.
29
30 1. Turn on machine
31 2. Insert disc 1 (the red disc) and press a key.
32 3. Type fdisk (RETURN)
33 4. At each prompt press the RETURN key (another three times).
34 5. The A> will now appear so now type format c:/s (RETURN).
35 6. Now push the Y key (RETURN).
36 7. The hard disc will now begin to format, if you have a 10Mb machine then it will count up to 305
37 cylinders. If you have a 20 Mb machine then 610 cylinders will be counted.
38 8. Once this is done, take out disc 1 and insert disc 5 (the maroon disc).
39 9. Now type config(RETURN). This procedure will copy all five discs (order 5,1,2,3,4) onto the hard disc.
40 Once finished the screen will show some information about the size of the disc and the number of files and
41 directories present.
42 10. To now use the hard disc remove the floppy disc from the drive and store in a safe place with the other
43 four discs then restart the computer by pushing Alt Ctrl and Del.
44 11. After a short while the AMSTRAD PC info will come up and tell you when the machine was last used
45 and then after a little longer the screen will clear and will display this message,
46
47 F1=DOSPLUS.SYS
48 F2=DOS.SYS
49
50 Select operating system:
51
52 If you choose F1 then DOS Plus and GEM will be booted, or if you press F2 then MS-DOS will be booted.
53
54 PC1512-HD10: ?
55 PC1512-HD20: Tandon TM-262 [-chs 615,4,17 -ss 512]
56 */
57
58 /*
59 HARD DISC INSTALLATION ON PC1640
60
61 PC1640 hard disc comes ready installed with the necessary software. That is discs 1 to 4 that are
62 supplied ready with the machine.
63
64 Howevere in the case of a disc failure it may be necessary to reinstall the supplied software.
65
66 This is done in the following way:
67 1. Put disc one into drive A: and boot up the system
68 2. Put disc four into drive A: and type CD\SUPPLEME and press return.
69 3. Type HDFORMAT and press return.
70 4. Answer YES to the screen prompt.
71 5. When HDFORMAT is completed remove disc four and replace with disc one.
72 6. Type CD\ and press return.
73 7. Type FDISK and press return.
74 8. Press return key every time you are asked a question.
75 9. With disc one still in drive A: type FORMAT C:/S and press return.
76 10. When formatting is finished replace disc one with disc four.
77 11. Type CD\SUPPLEME and press return.
78 12. Type CONFIG and press return.
79
80 After typing CONFIG the machine will proceed to copy the four system discs to the hard disc.
81 After copying each disc you will be prompted to insert the next disc.
82 You do not noeed to know in which order to insert the discs because the machine will tell you which disc is
83 needed next.
84
85 The system is now installed and should be tested by rebooting the machine.
86
87 It should be noted that if the hard disc is ok but the software has been corrupted or deleted you can
88 reinstall the software without reformatting.
89 This is done by following steps 11 and 12.
90
91 PC1640-HD20: Amstrad 40095 (Alps DRMD20A12A), Tandon TM-262 [-chs 615,4,17 -ss 512]
92 PC1640-HD30: Western Digital 95038 [-chs 615,6,17 -ss 512]
93 */
94
95 #include "emu.h"
96 #include "includes/pc1512.h"
97 #include "bus/rs232/rs232.h"
98 #include "bus/isa/ega.h"
99 #include "screen.h"
100 #include "softlist.h"
101 #include "speaker.h"
102
103
104 //**************************************************************************
105 // SYSTEM STATUS REGISTER
106 //**************************************************************************
107
108 //-------------------------------------------------
109 // system_r -
110 //-------------------------------------------------
111
system_r(offs_t offset)112 uint8_t pc1512_base_state::system_r(offs_t offset)
113 {
114 uint8_t data = 0;
115
116 switch (offset)
117 {
118 case 0:
119 if (BIT(m_port61, 7))
120 {
121 /*
122
123 bit description
124
125 0 1
126 1 8087 NDP installed
127 2 1
128 3 1
129 4 DDM0
130 5 DDM1
131 6 second floppy disk drive installed
132 7 0
133
134 */
135
136 data = m_status1;
137 }
138 else
139 {
140 data = m_kbd;
141 m_kb_bits = 0;
142 m_kb->data_w(1);
143 m_pic->ir1_w(CLEAR_LINE);
144 }
145 break;
146
147 case 1:
148 data = m_port61;
149 break;
150
151 case 2:
152 /*
153
154 bit description
155
156 0 RAM0 / RAM4
157 1 RAM1
158 2 RAM2
159 3 RAM3
160 4 undefined
161 5 8253 PIT OUT2 output
162 6 external parity error (I/OCHCK from expansion bus)
163 7 on-board system RAM parity error
164
165 */
166
167 if (BIT(m_port61, 2))
168 data = m_status2 & 0x0f;
169 else
170 data = m_status2 >> 4;
171
172 data |= m_pit2 << 5;
173 break;
174 }
175
176 return data;
177 }
178
179
180 //-------------------------------------------------
181 // system_w -
182 //-------------------------------------------------
183
system_w(offs_t offset,uint8_t data)184 void pc1512_base_state::system_w(offs_t offset, uint8_t data)
185 {
186 switch (offset)
187 {
188 case 1:
189 /*
190
191 bit description
192
193 0 8253 GATE 2 (speaker modulate)
194 1 speaker drive
195 2 enable port C LSB / disable MSB
196 3 undefined
197 4 disable parity checking of on-board RAM
198 5 prevent external parity errors from causing NMI
199 6 enable incoming Keyboard Clock
200 7 enable Status-1/Disable Keyboard Code on Port A
201
202 */
203
204 m_port61 = data;
205
206 m_pit->write_gate2(BIT(data, 0));
207
208 m_speaker_drive = BIT(data, 1);
209 update_speaker();
210
211 m_kb->clock_w(BIT(data, 6));
212
213 if (BIT(data, 7))
214 {
215 m_kb_bits = 0;
216 m_kb->data_w(1);
217 m_pic->ir1_w(CLEAR_LINE);
218 }
219 break;
220
221 case 4:
222 /*
223
224 bit description
225
226 0
227 1 PA1 - 8087 NDP installed
228 2
229 3
230 4 PA4 - DDM0
231 5 PA5 - DDM1
232 6 PA6 - Second Floppy disk drive installed
233 7
234
235 */
236
237 if (BIT(data, 7))
238 m_status1 = data ^ 0x8d;
239 else
240 m_status1 = data;
241 break;
242
243 case 5:
244 /*
245
246 bit description
247
248 0 PC0 (LSB) - RAM0
249 1 PC1 (LSB) - RAM1
250 2 PC2 (LSB) - RAM2
251 3 PC3 (LSB) - RAM3
252 4 PC0 (MSB) - RAM4
253 5 PC1 (MSB) - Undefined
254 6 PC2 (MSB) - Undefined
255 7 PC3 (MSB) - Undefined
256
257 */
258
259 m_status2 = data;
260 break;
261
262 case 6:
263 machine_reset();
264 break;
265 }
266 }
267
268
269
270 //**************************************************************************
271 // MOUSE
272 //**************************************************************************
273
274 //-------------------------------------------------
275 // mouse_r -
276 //-------------------------------------------------
277
mouse_r(offs_t offset)278 uint8_t pc1512_base_state::mouse_r(offs_t offset)
279 {
280 uint8_t data = 0;
281
282 switch (offset)
283 {
284 case 0:
285 data = m_mouse_x;
286 break;
287
288 case 2:
289 data = m_mouse_y;
290 break;
291 }
292
293 return data;
294 }
295
296
297 //-------------------------------------------------
298 // mouse_w -
299 //-------------------------------------------------
300
mouse_w(offs_t offset,uint8_t data)301 void pc1512_base_state::mouse_w(offs_t offset, uint8_t data)
302 {
303 switch (offset)
304 {
305 case 0:
306 m_mouse_x = 0;
307 break;
308
309 case 2:
310 m_mouse_y = 0;
311 break;
312 }
313 }
314
315
316
317 //**************************************************************************
318 // DIRECT MEMORY ACCESS
319 //**************************************************************************
320
321 //-------------------------------------------------
322 // dma_page_w -
323 //-------------------------------------------------
324
dma_page_w(offs_t offset,uint8_t data)325 void pc1512_base_state::dma_page_w(offs_t offset, uint8_t data)
326 {
327 /*
328
329 bit description
330
331 0 Address bit A16
332 1 Address bit A17
333 2 Address bit A18
334 3 Address bit A19
335 4
336 5
337 6
338 7
339
340 */
341
342 switch (offset)
343 {
344 case 1:
345 m_dma_page[2] = data & 0x0f;
346 break;
347
348 case 2:
349 m_dma_page[3] = data & 0x0f;
350 break;
351
352 case 3:
353 m_dma_page[0] = m_dma_page[1] = data & 0x0f;
354 break;
355 }
356 }
357
358
359
360 //**************************************************************************
361 // INTERRUPTS
362 //**************************************************************************
363
364 //-------------------------------------------------
365 // nmi_mask_w -
366 //-------------------------------------------------
367
nmi_mask_w(uint8_t data)368 void pc1512_base_state::nmi_mask_w(uint8_t data)
369 {
370 m_nmi_enable = BIT(data, 7);
371 }
372
373
374
375 //**************************************************************************
376 // PRINTER
377 //**************************************************************************
378
379 //-------------------------------------------------
380 // printer_r -
381 //-------------------------------------------------
382
printer_r(offs_t offset)383 uint8_t pc1512_base_state::printer_r(offs_t offset)
384 {
385 uint8_t data = 0;
386
387 switch (offset)
388 {
389 case 0:
390 data = m_printer_data;
391 break;
392
393 case 1:
394 /*
395
396 bit description
397
398 0 LK1 fitted
399 1 LK2 fitted
400 2 LK3 fitted
401 3 printer error
402 4 printer selected
403 5 paper out
404 6 printer acknowledge
405 7 printer busy
406
407 */
408
409 data |= m_lk->read() & 0x07;
410
411 data |= m_centronics_fault << 3;
412 data |= m_centronics_select << 4;
413 data |= m_centronics_perror << 5;
414 data |= m_centronics_ack << 6;
415 data |= m_centronics_busy << 7;
416 break;
417
418 case 2:
419 /*
420
421 bit description
422
423 0 Data Strobe
424 1 Select Auto Feed
425 2 Reset Printer
426 3 Select Printer
427 4 Enable Int on ACK
428 5 1
429 6
430 7
431
432 */
433
434 data = m_printer_control | 0x20;
435 break;
436 }
437
438 return data;
439 }
440
441
442 //-------------------------------------------------
443 // printer_r -
444 //-------------------------------------------------
445
printer_r(offs_t offset)446 uint8_t pc1640_state::printer_r(offs_t offset)
447 {
448 uint8_t data = 0;
449
450 switch (offset)
451 {
452 case 2:
453 /*
454
455 bit description
456
457 0 Data Strobe
458 1 Select Auto Feed
459 2 Reset Printer
460 3 Select Printer
461 4 Enable Int on ACK
462 5 OPT
463 6 SW6
464 7 SW7
465
466 */
467
468 /*
469 Bit D5 is the option (OPT) bit and can return one of three different pieces of
470 information. Although not documented as such on the PC1512, Bit D5 was always a
471 "1", however on the PC1640 it will always be a zero if immediately prior to the
472 read of channel 037Ah the software performs an I/O read of an I/O channel
473 implemented on the PC1512 main board, having address line A7 high (for example,
474 the CGA channels). This is a simple test for software to detect whether it is
475 running on a PC1512 or a PC1640. A PC1512 will give a 1, whereas a PC1640 will
476 give a 0.
477
478 In addition to being a test of machine type the OPT bit, D5, can also reflect
479 the state of either SW9 or SW10. The OPT bit will reflect the state of switch
480 SW9 by an I/O read operation to an I/O channel not implemented on the main
481 board and having address lines A14 and A7 both low (for example channel 0278h)
482 immediately prior to the reading of channel 037Ah. The OPT bit is set to the
483 state of switch SW10 by an I/O read operation to an I/O channel not implemented
484 on the main board having address lines A14 high and A7 low (for example channel
485 4278h). Software testing OPT bit should disable interrupts before the initial
486 (dummy) channel read and the I/O read of channel 037A in order to avoid
487 additional (interrupt based) I/O operations between the setting and the testing
488 of the information read back in the OPT bit. For switches SW9 and SW10, a logic
489 "1" is returned when the switch is on the "on" position and a logic "0" if the
490 switch is in the "off" position.
491 */
492 data = m_printer_control;
493 data |= m_opt << 5;
494 data |= (m_sw->read() & 0x60) << 1;
495 break;
496
497 default:
498 data = pc1512_base_state::printer_r(offset);
499 break;
500 }
501
502 return data;
503 }
504
505
506 //-------------------------------------------------
507 // printer_w -
508 //-------------------------------------------------
509
printer_w(offs_t offset,uint8_t data)510 void pc1512_base_state::printer_w(offs_t offset, uint8_t data)
511 {
512 switch (offset)
513 {
514 case 0:
515 m_printer_data = data;
516 m_cent_data_out->write(data);
517 break;
518
519 case 2:
520 /*
521
522 bit description
523
524 0 Data Strobe
525 1 Select Auto Feed
526 2 Reset Printer
527 3 Select Printer
528 4 Enable Int on ACK
529 5
530 6
531 7
532
533 */
534
535 m_printer_control = data & 0x1f;
536
537 m_centronics->write_strobe(BIT(data, 0));
538 m_centronics->write_autofd(BIT(data, 1));
539 m_centronics->write_init(BIT(data, 2));
540
541 m_ack_int_enable = BIT(data, 4);
542 update_ack();
543 break;
544 }
545 }
546
547
548 //**************************************************************************
549 // PC1640 I/O ACCESS
550 //**************************************************************************
551
552 //-------------------------------------------------
553 // io_r -
554 //-------------------------------------------------
555
io_r(offs_t offset)556 uint8_t pc1640_state::io_r(offs_t offset)
557 {
558 uint8_t data = 0;
559 offs_t addr = offset & 0x3ff;
560 bool decoded = false;
561
562 if ( addr <= 0x00f) { data = m_dmac->read(offset & 0x0f); decoded = true; }
563 else if (addr >= 0x020 && addr <= 0x021) { data = m_pic->read(offset & 0x01); decoded = true; }
564 else if (addr >= 0x040 && addr <= 0x043) { data = m_pit->read(offset & 0x03); decoded = true; }
565 else if (addr >= 0x060 && addr <= 0x06f) { data = system_r(offset & 0x0f); decoded = true; }
566 else if (addr >= 0x070 && addr <= 0x073) { data = m_rtc->read(offset & 0x01); decoded = true; }
567 else if (addr >= 0x078 && addr <= 0x07f) { data = mouse_r(offset & 0x07); decoded = true; }
568 else if (addr >= 0x378 && addr <= 0x37b) { data = printer_r(offset & 0x03); decoded = true; }
569 else if (addr >= 0x3b0 && addr <= 0x3df) { decoded = true; }
570 else if (addr >= 0x3f4 && addr <= 0x3f4) { data = m_fdc->msr_r(); decoded = true; }
571 else if (addr >= 0x3f5 && addr <= 0x3f5) { data = m_fdc->fifo_r(); decoded = true; }
572 else if (addr >= 0x3f8 && addr <= 0x3ff) { data = m_uart->ins8250_r(offset & 0x07); decoded = true; }
573
574 if (decoded)
575 {
576 if (BIT(offset, 7))
577 {
578 m_opt = 0;
579 //logerror("OPT 0\n");
580 }
581 }
582 else if (!BIT(offset, 7))
583 {
584 uint16_t sw = m_sw->read();
585
586 if (!BIT(offset, 14))
587 {
588 m_opt = BIT(sw, 8);
589 logerror("OPT SW9 %u\n", m_opt);
590 }
591 else
592 {
593 m_opt = BIT(sw, 9);
594 logerror("OPT SW10 %u\n", m_opt);
595 }
596 }
597
598 return data;
599 }
600
601
602
603 //**************************************************************************
604 // ADDRESS MAPS
605 //**************************************************************************
606
607 //-------------------------------------------------
608 // ADDRESS_MAP( pc1512_mem )
609 //-------------------------------------------------
610
pc1512_mem(address_map & map)611 void pc1512_state::pc1512_mem(address_map &map)
612 {
613 map(0x00000, 0x9ffff).ram();
614 map(0xb8000, 0xbbfff).rw(m_vdu, FUNC(ams40041_device::video_ram_r), FUNC(ams40041_device::video_ram_w));
615 map(0xfc000, 0xfffff).rom().region(I8086_TAG, 0);
616 }
617
618
619 //-------------------------------------------------
620 // ADDRESS_MAP( pc1512_io )
621 //-------------------------------------------------
622
pc1512_io(address_map & map)623 void pc1512_state::pc1512_io(address_map &map)
624 {
625 // [RH] 29 Aug 2016: I can find no evidence to indicate that Amstrad had only 10 I/O lines, as the
626 // schematic calls for a stock 8086 and the I/O and data lines are multiplexed onto the same bus,
627 // plus address lines 20-10 are towards the middle of a standard ISA slot. If it turns out that this
628 // is not in fact accurate to hardware, please add this back in.
629 // map.global_mask(0x3ff);
630 map(0x000, 0x00f).rw(m_dmac, FUNC(am9517a_device::read), FUNC(am9517a_device::write));
631 map(0x020, 0x021).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
632 map(0x040, 0x043).rw(m_pit, FUNC(pit8253_device::read), FUNC(pit8253_device::write));
633 map(0x060, 0x06f).rw(FUNC(pc1512_state::system_r), FUNC(pc1512_state::system_w));
634 map(0x070, 0x071).mirror(0x02).rw(m_rtc, FUNC(mc146818_device::read), FUNC(mc146818_device::write));
635 map(0x078, 0x07f).rw(FUNC(pc1512_state::mouse_r), FUNC(pc1512_state::mouse_w));
636 map(0x080, 0x083).w(FUNC(pc1512_state::dma_page_w));
637 map(0x0a1, 0x0a1).w(FUNC(pc1512_state::nmi_mask_w));
638 map(0x378, 0x37b).rw(FUNC(pc1512_state::printer_r), FUNC(pc1512_state::printer_w));
639 map(0x3d0, 0x3df).rw(m_vdu, FUNC(ams40041_device::vdu_r), FUNC(ams40041_device::vdu_w));
640 map(0x3f2, 0x3f2).w(FUNC(pc1512_state::drive_select_w));
641 map(0x3f4, 0x3f5).m(m_fdc, FUNC(upd765a_device::map));
642 map(0x3f8, 0x3ff).rw(m_uart, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
643 }
644
645
646 //-------------------------------------------------
647 // ADDRESS_MAP( pc1640_mem )
648 //-------------------------------------------------
649
pc1640_mem(address_map & map)650 void pc1640_state::pc1640_mem(address_map &map)
651 {
652 map(0x00000, 0x9ffff).ram();
653 map(0xf0000, 0xf3fff).mirror(0xc000).rom().region(I8086_TAG, 0);
654 }
655
656
657 //-------------------------------------------------
658 // ADDRESS_MAP( pc1640_io )
659 //-------------------------------------------------
660
pc1640_io(address_map & map)661 void pc1640_state::pc1640_io(address_map &map)
662 {
663 map(0x0000, 0xffff).r(FUNC(pc1640_state::io_r));
664
665 map(0x000, 0x00f).w(m_dmac, FUNC(am9517a_device::write));
666 map(0x020, 0x021).w(m_pic, FUNC(pic8259_device::write));
667 map(0x040, 0x043).w(m_pit, FUNC(pit8253_device::write));
668 map(0x060, 0x06f).w(FUNC(pc1640_state::system_w));
669 map(0x070, 0x071).mirror(0x02).w(m_rtc, FUNC(mc146818_device::write));
670 map(0x078, 0x07f).w(FUNC(pc1640_state::mouse_w));
671 map(0x080, 0x083).w(FUNC(pc1640_state::dma_page_w));
672 map(0x0a1, 0x0a1).w(FUNC(pc1640_state::nmi_mask_w));
673 map(0x378, 0x37b).w(FUNC(pc1640_state::printer_w));
674 map(0x3f2, 0x3f2).w(FUNC(pc1640_state::drive_select_w));
675 map(0x3f5, 0x3f5).w(m_fdc, FUNC(upd765a_device::fifo_w));
676 map(0x3f8, 0x3ff).w(m_uart, FUNC(ins8250_device::ins8250_w));
677 }
678
679
680
681 //**************************************************************************
682 // INPUT PORTS
683 //**************************************************************************
684
685 //-------------------------------------------------
686 // INPUT_PORTS( pc1512 )
687 //-------------------------------------------------
688
689 static INPUT_PORTS_START( pc1512 )
690 PORT_START("LK")
DEF_STR(Language)691 PORT_DIPNAME( 0x07, 0x07, DEF_STR( Language ) )
692 PORT_DIPSETTING( 0x07, DEF_STR( English ) )
693 PORT_DIPSETTING( 0x06, DEF_STR( German ) )
694 PORT_DIPSETTING( 0x05, DEF_STR( French ) )
695 PORT_DIPSETTING( 0x04, DEF_STR( Spanish ) )
696 PORT_DIPSETTING( 0x03, "Danish" )
697 PORT_DIPSETTING( 0x02, "Swedish" )
698 PORT_DIPSETTING( 0x01, DEF_STR( Italian ) )
699 PORT_DIPSETTING( 0x00, "Diagnostic Mode" )
700 PORT_DIPNAME( 0x08, 0x08, "Memory Size")
701 PORT_DIPSETTING( 0x08, "512 KB" )
702 PORT_DIPSETTING( 0x00, "640 KB" )
703 PORT_DIPNAME( 0x10, 0x10, "ROM Size")
704 PORT_DIPSETTING( 0x10, "16 KB" )
705 PORT_DIPSETTING( 0x00, "32 KB" )
706 PORT_DIPNAME( 0x60, 0x60, "Character Set")
707 PORT_DIPSETTING( 0x60, "Default (Codepage 437)" )
708 PORT_DIPSETTING( 0x40, "Portuguese (Codepage 865)" )
709 PORT_DIPSETTING( 0x20, "Norwegian (Codepage 860)" )
710 PORT_DIPSETTING( 0x00, "Greek")
711 PORT_DIPNAME( 0x80, 0x80, "Floppy Ready Line")
712 PORT_DIPSETTING( 0x80, "Connected" )
713 PORT_DIPSETTING( 0x00, "Not connected" )
714 INPUT_PORTS_END
715
716
717 //-------------------------------------------------
718 // INPUT_PORTS( pc1640 )
719 //-------------------------------------------------
720
721 static INPUT_PORTS_START( pc1640 )
722 PORT_START("LK")
723 PORT_DIPNAME( 0x07, 0x07, DEF_STR( Language ) )
724 PORT_DIPSETTING( 0x07, DEF_STR( English ) )
725 PORT_DIPSETTING( 0x06, DEF_STR( German ) )
726 PORT_DIPSETTING( 0x05, DEF_STR( French ) )
727 PORT_DIPSETTING( 0x04, DEF_STR( Spanish ) )
728 PORT_DIPSETTING( 0x03, "Danish" )
729 PORT_DIPSETTING( 0x02, "Swedish" )
730 PORT_DIPSETTING( 0x01, DEF_STR( Italian ) )
731 PORT_DIPSETTING( 0x00, "Diagnostic Mode" )
732
733 PORT_START("SW")
734 PORT_DIPNAME( 0x0f, 0x09, "Initial Display Mode" ) PORT_DIPLOCATION("SW:1,2,3,4") PORT_CONDITION("SW", 0x200, EQUALS, 0x200)
735 PORT_DIPSETTING( 0x0b, "Internal MD, External CGA80" )
736 PORT_DIPSETTING( 0x0a, "Internal MD, External CGA40" )
737 PORT_DIPSETTING( 0x09, "Internal ECD350, External MDA/HERC" )
738 PORT_DIPSETTING( 0x08, "Internal ECD200, External MDA/HERC" )
739 PORT_DIPSETTING( 0x07, "Internal CD80, External MDA/HERC" )
740 PORT_DIPSETTING( 0x06, "Internal CD40, External MDA/HERC" )
741 PORT_DIPSETTING( 0x05, "External CGA80, Internal MD" )
742 PORT_DIPSETTING( 0x04, "External CGA40, Internal MD" )
743 PORT_DIPSETTING( 0x03, "External MDA/HERC, Internal ECD350" )
744 PORT_DIPSETTING( 0x02, "External MDA/HERC, Internal ECD200" )
745 PORT_DIPSETTING( 0x01, "External MDA/HERC, Internal CD80" )
746 PORT_DIPSETTING( 0x00, "External MDA/HERC, Internal CD40" )
747 PORT_DIPNAME( 0x10, 0x10, "MC6845 Mode" ) PORT_DIPLOCATION("SW:5") PORT_CONDITION("SW", 0x200, EQUALS, 0x200)
748 PORT_DIPSETTING( 0x10, "EGA" )
749 PORT_DIPSETTING( 0x00, "CGA/MDA/HERC" )
750 PORT_DIPNAME( 0x60, 0x00, "Font" ) PORT_DIPLOCATION("SW:6,7") PORT_CONDITION("SW", 0x300, EQUALS, 0x300)
751 PORT_DIPSETTING( 0x00, DEF_STR( English ) )
752 PORT_DIPSETTING( 0x60, "Danish" )
753 PORT_DIPSETTING( 0x40, "Portuguese" )
754 PORT_DIPSETTING( 0x20, "Greek" )
755 PORT_DIPNAME( 0x60, 0x60, "Default Display Mode" ) PORT_DIPLOCATION("SW:6,7") PORT_CONDITION("SW", 0x200, EQUALS, 0x000)
756 PORT_DIPSETTING( 0x60, "External EGA" )
757 PORT_DIPSETTING( 0x40, "External CGA in 40 Column Mode" )
758 PORT_DIPSETTING( 0x20, "External CGA in 80 Column Mode" )
759 PORT_DIPSETTING( 0x00, "External Monochrome Adapter" )
760 PORT_DIPNAME( 0x80, 0x00, "Monitor" ) PORT_DIPLOCATION("SW:8") PORT_CONDITION("SW", 0x200, EQUALS, 0x200)
761 PORT_DIPSETTING( 0x80, "CD (Standard RGB)" )
762 PORT_DIPSETTING( 0x00, "ECD (Enhanced RGB)" )
763 PORT_DIPNAME( 0x100, 0x100, "Foreign Fonts" ) PORT_DIPLOCATION("SW:9") PORT_CONDITION("SW", 0x200, EQUALS, 0x200)
764 PORT_DIPSETTING( 0x100, "Enabled" )
765 PORT_DIPSETTING( 0x000, "Disabled" )
766 PORT_DIPNAME( 0x200, 0x200, "Internal Graphics Adapter" ) PORT_DIPLOCATION("SW:10")
767 PORT_DIPSETTING( 0x200, "Enabled" )
768 PORT_DIPSETTING( 0x000, "Disabled" )
769 INPUT_PORTS_END
770
771
772
773 //**************************************************************************
774 // DEVICE CONFIGURATION
775 //**************************************************************************
776
777 //-------------------------------------------------
778 // PC1512_KEYBOARD_INTERFACE( kb_intf )
779 //-------------------------------------------------
780
781 WRITE_LINE_MEMBER( pc1512_base_state::kbdata_w )
782 {
783 m_kbdata = state;
784 }
785
WRITE_LINE_MEMBER(pc1512_base_state::kbclk_w)786 WRITE_LINE_MEMBER( pc1512_base_state::kbclk_w )
787 {
788 if (!BIT(m_port61, 7) && m_kbclk && !state)
789 {
790 m_kbd <<= 1;
791 m_kbd |= m_kbdata;
792 m_kb_bits++;
793
794 if (m_kb_bits == 8)
795 {
796 m_kb->data_w(0);
797 m_pic->ir1_w(ASSERT_LINE);
798 }
799 }
800
801 m_kbclk = state;
802 }
803
mouse_x_w(uint8_t data)804 void pc1512_base_state::mouse_x_w(uint8_t data)
805 {
806 if (data > m_mouse_x_old)
807 m_mouse_x+=3;
808 else
809 m_mouse_x-=3;
810
811 m_mouse_x_old = data;
812 }
813
mouse_y_w(uint8_t data)814 void pc1512_base_state::mouse_y_w(uint8_t data)
815 {
816 if (data > m_mouse_y_old)
817 m_mouse_y-=3;
818 else
819 m_mouse_y+=3;
820
821 m_mouse_y_old = data;
822 }
823
824 //-------------------------------------------------
825 // I8237_INTERFACE( dmac_intf )
826 //-------------------------------------------------
827
update_fdc_tc()828 void pc1512_base_state::update_fdc_tc()
829 {
830 if (m_nden)
831 m_fdc->tc_w(m_neop);
832 else
833 m_fdc->tc_w(false);
834 }
835
WRITE_LINE_MEMBER(pc1512_base_state::hrq_w)836 WRITE_LINE_MEMBER( pc1512_base_state::hrq_w )
837 {
838 m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
839
840 m_dmac->hack_w(state);
841 }
842
WRITE_LINE_MEMBER(pc1512_base_state::eop_w)843 WRITE_LINE_MEMBER( pc1512_base_state::eop_w )
844 {
845 if (m_dma_channel == 2)
846 {
847 m_neop = !state;
848 update_fdc_tc();
849 }
850 }
851
memr_r(offs_t offset)852 uint8_t pc1512_base_state::memr_r(offs_t offset)
853 {
854 address_space &program = m_maincpu->space(AS_PROGRAM);
855 offs_t page_offset = m_dma_page[m_dma_channel] << 16;
856
857 return program.read_byte(page_offset + offset);
858 }
859
memw_w(offs_t offset,uint8_t data)860 void pc1512_base_state::memw_w(offs_t offset, uint8_t data)
861 {
862 address_space &program = m_maincpu->space(AS_PROGRAM);
863 offs_t page_offset = m_dma_page[m_dma_channel] << 16;
864
865 program.write_byte(page_offset + offset, data);
866 }
867
ior1_r()868 uint8_t pc1512_base_state::ior1_r()
869 {
870 return m_bus->dack_r(1);
871 }
872
ior2_r()873 uint8_t pc1512_base_state::ior2_r()
874 {
875 if (m_nden)
876 return m_fdc->dma_r();
877 else
878 return m_bus->dack_r(2);
879 }
880
ior3_r()881 uint8_t pc1512_base_state::ior3_r()
882 {
883 return m_bus->dack_r(3);
884 }
885
iow0_w(uint8_t data)886 void pc1512_base_state::iow0_w(uint8_t data)
887 {
888 m_dreq0 = 0;
889 m_dmac->dreq0_w(m_dreq0);
890 }
891
iow1_w(uint8_t data)892 void pc1512_base_state::iow1_w(uint8_t data)
893 {
894 m_bus->dack_w(1, data);
895 }
896
iow2_w(uint8_t data)897 void pc1512_base_state::iow2_w(uint8_t data)
898 {
899 if (m_nden)
900 m_fdc->dma_w(data);
901 else
902 m_bus->dack_w(2, data);
903 }
904
iow3_w(uint8_t data)905 void pc1512_base_state::iow3_w(uint8_t data)
906 {
907 m_bus->dack_w(3, data);
908 }
909
WRITE_LINE_MEMBER(pc1512_base_state::dack0_w)910 WRITE_LINE_MEMBER( pc1512_base_state::dack0_w )
911 {
912 if (!state) m_dma_channel = 0;
913 }
914
WRITE_LINE_MEMBER(pc1512_base_state::dack1_w)915 WRITE_LINE_MEMBER( pc1512_base_state::dack1_w )
916 {
917 if (!state) m_dma_channel = 1;
918 }
919
WRITE_LINE_MEMBER(pc1512_base_state::dack2_w)920 WRITE_LINE_MEMBER( pc1512_base_state::dack2_w )
921 {
922 if (!state) m_dma_channel = 2;
923 }
924
WRITE_LINE_MEMBER(pc1512_base_state::dack3_w)925 WRITE_LINE_MEMBER( pc1512_base_state::dack3_w )
926 {
927 if (!state) m_dma_channel = 3;
928 }
929
930 //-------------------------------------------------
931 // pit8253_config pit_intf
932 //-------------------------------------------------
933
update_speaker()934 void pc1512_base_state::update_speaker()
935 {
936 m_speaker->level_w(m_speaker_drive & m_pit2);
937 }
938
WRITE_LINE_MEMBER(pc1512_base_state::pit1_w)939 WRITE_LINE_MEMBER( pc1512_base_state::pit1_w )
940 {
941 if (!m_pit1 && state && !m_dreq0)
942 {
943 m_dreq0 = 1;
944 m_dmac->dreq0_w(m_dreq0);
945 }
946
947 m_pit1 = state;
948 }
949
WRITE_LINE_MEMBER(pc1512_base_state::pit2_w)950 WRITE_LINE_MEMBER( pc1512_base_state::pit2_w )
951 {
952 m_pit2 = state;
953 update_speaker();
954 }
955
956 //-------------------------------------------------
957 // upd765_interface fdc_intf
958 //-------------------------------------------------
959
update_fdc_int()960 void pc1512_base_state::update_fdc_int()
961 {
962 if (m_nden)
963 m_pic->ir6_w(m_dint);
964 else
965 m_pic->ir6_w(CLEAR_LINE);
966 }
967
update_fdc_drq()968 void pc1512_base_state::update_fdc_drq()
969 {
970 if (m_nden)
971 m_dmac->dreq2_w(m_ddrq);
972 else
973 m_dmac->dreq2_w(0);
974 }
975
WRITE_LINE_MEMBER(pc1512_base_state::fdc_int_w)976 WRITE_LINE_MEMBER( pc1512_base_state::fdc_int_w )
977 {
978 m_dint = state;
979 update_fdc_int();
980 }
981
WRITE_LINE_MEMBER(pc1512_base_state::fdc_drq_w)982 WRITE_LINE_MEMBER( pc1512_base_state::fdc_drq_w )
983 {
984 m_ddrq = state;
985 update_fdc_drq();
986 }
987
drive_select_w(uint8_t data)988 void pc1512_base_state::drive_select_w(uint8_t data)
989 {
990 m_fdc->set_floppy((data & 0x03) < 2 ? m_floppy[data & 0x03]->get_device() : nullptr);
991 for (int n = 0; n < 2; n++)
992 {
993 floppy_image_device *img = m_floppy[n]->get_device();
994 if (img != nullptr)
995 img->mon_w((data & 0x03) == n && BIT(data, n + 4) ? 0 : 1);
996 }
997
998 m_fdc->reset_w(!BIT(data, 2));
999 m_nden = BIT(data, 3);
1000 update_fdc_int();
1001 update_fdc_drq();
1002 }
1003
1004 //-------------------------------------------------
1005 // centronics_interface centronics_intf
1006 //-------------------------------------------------
1007
update_ack()1008 void pc1512_base_state::update_ack()
1009 {
1010 if (m_ack_int_enable)
1011 m_pic->ir7_w(m_centronics_ack);
1012 else
1013 m_pic->ir7_w(CLEAR_LINE);
1014 }
1015
WRITE_LINE_MEMBER(pc1512_base_state::write_centronics_ack)1016 WRITE_LINE_MEMBER( pc1512_base_state::write_centronics_ack )
1017 {
1018 m_centronics_ack = state;
1019 update_ack();
1020 }
1021
WRITE_LINE_MEMBER(pc1512_base_state::write_centronics_busy)1022 WRITE_LINE_MEMBER( pc1512_base_state::write_centronics_busy )
1023 {
1024 m_centronics_busy = state;
1025 }
1026
WRITE_LINE_MEMBER(pc1512_base_state::write_centronics_perror)1027 WRITE_LINE_MEMBER( pc1512_base_state::write_centronics_perror )
1028 {
1029 m_centronics_perror = state;
1030 }
1031
WRITE_LINE_MEMBER(pc1512_base_state::write_centronics_select)1032 WRITE_LINE_MEMBER( pc1512_base_state::write_centronics_select )
1033 {
1034 m_centronics_select = state;
1035 }
1036
WRITE_LINE_MEMBER(pc1512_base_state::write_centronics_fault)1037 WRITE_LINE_MEMBER( pc1512_base_state::write_centronics_fault )
1038 {
1039 m_centronics_fault = state;
1040 }
1041
1042
1043 //-------------------------------------------------
1044 // isa8bus_interface isabus_intf
1045 //-------------------------------------------------
1046
pc1640_isa8_cards(device_slot_interface & device)1047 void pc1640_isa8_cards(device_slot_interface &device)
1048 {
1049 device.option_add_internal("iga", ISA8_PC1640_IGA);
1050 }
1051
FLOPPY_FORMATS_MEMBER(pc1512_base_state::floppy_formats)1052 FLOPPY_FORMATS_MEMBER( pc1512_base_state::floppy_formats )
1053 FLOPPY_PC_FORMAT
1054 FLOPPY_FORMATS_END
1055
1056 static void pc1512_floppies(device_slot_interface &device)
1057 {
1058 device.option_add("525dd", FLOPPY_525_DD); // Tandon TM65-2L
1059 }
1060
1061
1062
1063 //**************************************************************************
1064 // MACHINE INITIALIZATION
1065 //**************************************************************************
1066
machine_start()1067 void pc1512_base_state::machine_start()
1068 {
1069 save_item(NAME(m_pit1));
1070 save_item(NAME(m_pit2));
1071 save_item(NAME(m_status1));
1072 save_item(NAME(m_status2));
1073 save_item(NAME(m_port61));
1074 save_item(NAME(m_nmi_enable));
1075 save_item(NAME(m_kbd));
1076 save_item(NAME(m_kb_bits));
1077 save_item(NAME(m_kbclk));
1078 save_item(NAME(m_kbdata));
1079 save_item(NAME(m_mouse_x));
1080 save_item(NAME(m_mouse_y));
1081 save_item(NAME(m_mouse_x_old));
1082 save_item(NAME(m_mouse_y_old));
1083 save_item(NAME(m_dma_page));
1084 save_item(NAME(m_dma_channel));
1085 save_item(NAME(m_dreq0));
1086 save_item(NAME(m_nden));
1087 save_item(NAME(m_dint));
1088 save_item(NAME(m_ddrq));
1089 save_item(NAME(m_neop));
1090 save_item(NAME(m_ack_int_enable));
1091 save_item(NAME(m_centronics_ack));
1092 save_item(NAME(m_centronics_busy));
1093 save_item(NAME(m_centronics_perror));
1094 save_item(NAME(m_centronics_select));
1095 save_item(NAME(m_centronics_fault));
1096 save_item(NAME(m_printer_data));
1097 save_item(NAME(m_printer_control));
1098 save_item(NAME(m_speaker_drive));
1099 }
1100
machine_start()1101 void pc1512_state::machine_start()
1102 {
1103 pc1512_base_state::machine_start();
1104
1105 // set RAM size
1106 size_t ram_size = m_ram->size();
1107
1108 if (ram_size < 640 * 1024)
1109 {
1110 address_space &program = m_maincpu->space(AS_PROGRAM);
1111 program.unmap_readwrite(ram_size, 0x9ffff);
1112 }
1113 }
1114
machine_reset()1115 void pc1512_base_state::machine_reset()
1116 {
1117 m_nmi_enable = 0;
1118 drive_select_w(0);
1119
1120 m_kb_bits = 0;
1121 m_kb->data_w(1);
1122 m_pic->ir1_w(CLEAR_LINE);
1123 }
1124
machine_reset()1125 void pc1512_state::machine_reset()
1126 {
1127 pc1512_base_state::machine_reset();
1128
1129 m_pit2 = 1;
1130 }
1131
1132
1133 //-------------------------------------------------
1134 // MACHINE_START( pc1640 )
1135 //-------------------------------------------------
1136
machine_start()1137 void pc1640_state::machine_start()
1138 {
1139 pc1512_base_state::machine_start();
1140
1141 // state saving
1142 save_item(NAME(m_opt));
1143 }
1144
1145
1146 //**************************************************************************
1147 // MACHINE DRIVERS
1148 //**************************************************************************
1149
1150 //-------------------------------------------------
1151 // machine_config( pc1512 )
1152 //-------------------------------------------------
1153
pc1512(machine_config & config)1154 void pc1512_state::pc1512(machine_config &config)
1155 {
1156 I8086(config, m_maincpu, 24_MHz_XTAL / 3);
1157 m_maincpu->set_addrmap(AS_PROGRAM, &pc1512_state::pc1512_mem);
1158 m_maincpu->set_addrmap(AS_IO, &pc1512_state::pc1512_io);
1159 m_maincpu->set_irq_acknowledge_callback(I8259A2_TAG, FUNC(pic8259_device::inta_cb));
1160
1161 // video
1162 screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER));
1163 screen.set_raw(28.636363_MHz_XTAL, 912, 0, 910, 262, 0, 260);
1164 screen.set_screen_update(m_vdu, FUNC(ams40041_device::screen_update));
1165
1166 AMS40041(config, m_vdu, 28.636363_MHz_XTAL);
1167 m_vdu->set_screen(SCREEN_TAG);
1168 m_vdu->set_show_border_area(true);
1169
1170 // sound
1171 SPEAKER(config, "mono").front_center();
1172 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.80);
1173
1174 // devices
1175 PC1512_KEYBOARD(config, m_kb, 0);
1176 m_kb->clock_wr_callback().set(FUNC(pc1512_state::kbclk_w));
1177 m_kb->data_wr_callback().set(FUNC(pc1512_state::kbdata_w));
1178
1179 pc1512_mouse_port_device &mouse(PC1512_MOUSE_PORT(config, "mous", pc1512_mouse_port_devices, "mouse"));
1180 mouse.x_wr_callback().set(FUNC(pc1512_base_state::mouse_x_w));
1181 mouse.y_wr_callback().set(FUNC(pc1512_base_state::mouse_y_w));
1182 mouse.m1_wr_callback().set(m_kb, FUNC(pc1512_keyboard_device::m1_w));
1183 mouse.m2_wr_callback().set(m_kb, FUNC(pc1512_keyboard_device::m2_w));
1184
1185 AM9517A(config, m_dmac, 24_MHz_XTAL / 6);
1186 m_dmac->out_hreq_callback().set(FUNC(pc1512_state::hrq_w));
1187 m_dmac->out_eop_callback().set(FUNC(pc1512_state::eop_w));
1188 m_dmac->in_memr_callback().set(FUNC(pc1512_state::memr_r));
1189 m_dmac->out_memw_callback().set(FUNC(pc1512_state::memw_w));
1190 m_dmac->in_ior_callback<1>().set(FUNC(pc1512_state::ior1_r));
1191 m_dmac->in_ior_callback<2>().set(FUNC(pc1512_state::ior2_r));
1192 m_dmac->in_ior_callback<3>().set(FUNC(pc1512_state::ior3_r));
1193 m_dmac->out_iow_callback<0>().set(FUNC(pc1512_state::iow0_w));
1194 m_dmac->out_iow_callback<1>().set(FUNC(pc1512_state::iow1_w));
1195 m_dmac->out_iow_callback<2>().set(FUNC(pc1512_state::iow2_w));
1196 m_dmac->out_iow_callback<3>().set(FUNC(pc1512_state::iow3_w));
1197 m_dmac->out_dack_callback<0>().set(FUNC(pc1512_state::dack0_w));
1198 m_dmac->out_dack_callback<1>().set(FUNC(pc1512_state::dack1_w));
1199 m_dmac->out_dack_callback<2>().set(FUNC(pc1512_state::dack2_w));
1200 m_dmac->out_dack_callback<3>().set(FUNC(pc1512_state::dack3_w));
1201
1202 PIC8259(config, m_pic);
1203 m_pic->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
1204
1205 PIT8253(config, m_pit);
1206 m_pit->set_clk<0>(28.636363_MHz_XTAL / 24);
1207 m_pit->out_handler<0>().set(m_pic, FUNC(pic8259_device::ir0_w));
1208 m_pit->set_clk<1>(28.636363_MHz_XTAL / 24);
1209 m_pit->out_handler<1>().set(FUNC(pc1512_state::pit1_w));
1210 m_pit->set_clk<2>(28.636363_MHz_XTAL / 24);
1211 m_pit->out_handler<2>().set(FUNC(pc1512_state::pit2_w));
1212
1213 MC146818(config, m_rtc, 32.768_kHz_XTAL);
1214 m_rtc->irq().set(m_pic, FUNC(pic8259_device::ir2_w));
1215
1216 UPD765A(config, m_fdc, 24_MHz_XTAL / 6, false, false);
1217 // SED9420CAC (dedicated 16 MHz XTAL) is used as read data separator only
1218 m_fdc->intrq_wr_callback().set(FUNC(pc1512_state::fdc_int_w));
1219 m_fdc->drq_wr_callback().set(FUNC(pc1512_state::fdc_drq_w));
1220 FLOPPY_CONNECTOR(config, m_floppy[0], pc1512_floppies, "525dd", pc1512_base_state::floppy_formats);
1221 FLOPPY_CONNECTOR(config, m_floppy[1], pc1512_floppies, nullptr, pc1512_base_state::floppy_formats);
1222
1223 INS8250(config, m_uart, 1.8432_MHz_XTAL);
1224 m_uart->out_tx_callback().set(RS232_TAG, FUNC(rs232_port_device::write_txd));
1225 m_uart->out_dtr_callback().set(RS232_TAG, FUNC(rs232_port_device::write_dtr));
1226 m_uart->out_rts_callback().set(RS232_TAG, FUNC(rs232_port_device::write_rts));
1227 m_uart->out_int_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
1228
1229 CENTRONICS(config, m_centronics, centronics_devices, "printer");
1230 m_centronics->ack_handler().set(FUNC(pc1512_state::write_centronics_ack));
1231 m_centronics->busy_handler().set(FUNC(pc1512_state::write_centronics_busy));
1232 m_centronics->perror_handler().set(FUNC(pc1512_state::write_centronics_perror));
1233 m_centronics->select_handler().set(FUNC(pc1512_state::write_centronics_select));
1234 m_centronics->fault_handler().set(FUNC(pc1512_state::write_centronics_fault));
1235
1236 OUTPUT_LATCH(config, m_cent_data_out);
1237 m_centronics->set_output_latch(*m_cent_data_out);
1238
1239 rs232_port_device &rs232(RS232_PORT(config, RS232_TAG, default_rs232_devices, nullptr));
1240 rs232.rxd_handler().set(m_uart, FUNC(ins8250_uart_device::rx_w));
1241 rs232.dcd_handler().set(m_uart, FUNC(ins8250_uart_device::dcd_w));
1242 rs232.dsr_handler().set(m_uart, FUNC(ins8250_uart_device::dsr_w));
1243 rs232.ri_handler().set(m_uart, FUNC(ins8250_uart_device::ri_w));
1244 rs232.cts_handler().set(m_uart, FUNC(ins8250_uart_device::cts_w));
1245
1246 // ISA8 bus
1247 isa8_device &isa(ISA8(config, ISA_BUS_TAG, 0));
1248 isa.set_memspace(m_maincpu, AS_PROGRAM);
1249 isa.set_iospace(m_maincpu, AS_IO);
1250 isa.irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
1251 isa.irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
1252 isa.irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
1253 isa.irq5_callback().set(m_pic, FUNC(pic8259_device::ir5_w));
1254 isa.irq6_callback().set(m_pic, FUNC(pic8259_device::ir6_w));
1255 isa.irq7_callback().set(m_pic, FUNC(pic8259_device::ir7_w));
1256 isa.drq1_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq1_w));
1257 isa.drq2_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq2_w));
1258 isa.drq3_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq3_w));
1259 ISA8_SLOT(config, "isa1", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false); // FIXME: determine ISA clock
1260 ISA8_SLOT(config, "isa2", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false);
1261 ISA8_SLOT(config, "isa3", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false);
1262
1263 // internal ram
1264 RAM(config, RAM_TAG).set_default_size("512K").set_extra_options("544K,576K,608K,640K");
1265
1266 // software list
1267 SOFTWARE_LIST(config, "flop_list").set_original("pc1512_flop");
1268 SOFTWARE_LIST(config, "hdd_list").set_original("pc1512_hdd");
1269 }
1270
1271
1272 //-------------------------------------------------
1273 // machine_config( pc1512dd )
1274 //-------------------------------------------------
1275
pc1512dd(machine_config & config)1276 void pc1512_state::pc1512dd(machine_config &config)
1277 {
1278 pc1512(config);
1279 m_floppy[1]->set_default_option("525dd");
1280 }
1281
1282
1283 //-------------------------------------------------
1284 // machine_config( pc1512hd )
1285 //-------------------------------------------------
1286
pc1512hd(machine_config & config)1287 void pc1512_state::pc1512hd(machine_config &config)
1288 {
1289 pc1512(config);
1290 //subdevice<isa8_slot_device>("isa1")->set_default_option("wdxt_gen");
1291 subdevice<isa8_slot_device>("isa1")->set_default_option("hdc");
1292 }
1293
1294
1295 //-------------------------------------------------
1296 // machine_config( pc1640 )
1297 //-------------------------------------------------
1298
pc1640(machine_config & config)1299 void pc1640_state::pc1640(machine_config &config)
1300 {
1301 I8086(config, m_maincpu, 24_MHz_XTAL / 3);
1302 m_maincpu->set_addrmap(AS_PROGRAM, &pc1640_state::pc1640_mem);
1303 m_maincpu->set_addrmap(AS_IO, &pc1640_state::pc1640_io);
1304 m_maincpu->set_irq_acknowledge_callback(I8259A2_TAG, FUNC(pic8259_device::inta_cb));
1305
1306 // sound
1307 SPEAKER(config, "mono").front_center();
1308 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.80);
1309
1310 // devices
1311 PC1512_KEYBOARD(config, m_kb, 0);
1312 m_kb->clock_wr_callback().set(FUNC(pc1512_base_state::kbclk_w));
1313 m_kb->data_wr_callback().set(FUNC(pc1512_base_state::kbdata_w));
1314
1315 pc1512_mouse_port_device &mouse(PC1512_MOUSE_PORT(config, "mous", pc1512_mouse_port_devices, "mouse"));
1316 mouse.x_wr_callback().set(FUNC(pc1512_base_state::mouse_x_w));
1317 mouse.y_wr_callback().set(FUNC(pc1512_base_state::mouse_y_w));
1318 mouse.m1_wr_callback().set(m_kb, FUNC(pc1512_keyboard_device::m1_w));
1319 mouse.m2_wr_callback().set(m_kb, FUNC(pc1512_keyboard_device::m2_w));
1320
1321 AM9517A(config, m_dmac, 24_MHz_XTAL / 6);
1322 m_dmac->out_hreq_callback().set(FUNC(pc1640_state::hrq_w));
1323 m_dmac->out_eop_callback().set(FUNC(pc1640_state::eop_w));
1324 m_dmac->in_memr_callback().set(FUNC(pc1640_state::memr_r));
1325 m_dmac->out_memw_callback().set(FUNC(pc1640_state::memw_w));
1326 m_dmac->in_ior_callback<1>().set(FUNC(pc1640_state::ior1_r));
1327 m_dmac->in_ior_callback<2>().set(FUNC(pc1640_state::ior2_r));
1328 m_dmac->in_ior_callback<3>().set(FUNC(pc1640_state::ior3_r));
1329 m_dmac->out_iow_callback<0>().set(FUNC(pc1640_state::iow0_w));
1330 m_dmac->out_iow_callback<1>().set(FUNC(pc1640_state::iow1_w));
1331 m_dmac->out_iow_callback<2>().set(FUNC(pc1640_state::iow2_w));
1332 m_dmac->out_iow_callback<3>().set(FUNC(pc1640_state::iow3_w));
1333 m_dmac->out_dack_callback<0>().set(FUNC(pc1640_state::dack0_w));
1334 m_dmac->out_dack_callback<1>().set(FUNC(pc1640_state::dack1_w));
1335 m_dmac->out_dack_callback<2>().set(FUNC(pc1640_state::dack2_w));
1336 m_dmac->out_dack_callback<3>().set(FUNC(pc1640_state::dack3_w));
1337
1338 PIC8259(config, m_pic);
1339 m_pic->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
1340
1341 PIT8253(config, m_pit);
1342 m_pit->set_clk<0>(28.636363_MHz_XTAL / 24);
1343 m_pit->out_handler<0>().set(m_pic, FUNC(pic8259_device::ir0_w));
1344 m_pit->set_clk<1>(28.636363_MHz_XTAL / 24);
1345 m_pit->out_handler<1>().set(FUNC(pc1512_base_state::pit1_w));
1346 m_pit->set_clk<2>(28.636363_MHz_XTAL / 24);
1347 m_pit->out_handler<2>().set(FUNC(pc1512_base_state::pit2_w));
1348
1349 MC146818(config, m_rtc, 32.768_kHz_XTAL);
1350 m_rtc->irq().set(m_pic, FUNC(pic8259_device::ir2_w));
1351
1352 UPD765A(config, m_fdc, 24_MHz_XTAL / 6, false, false);
1353 // FDC91C36 (clocked by CK8K) is used as read data separator only
1354 m_fdc->intrq_wr_callback().set(FUNC(pc1512_base_state::fdc_int_w));
1355 m_fdc->drq_wr_callback().set(FUNC(pc1512_base_state::fdc_drq_w));
1356 FLOPPY_CONNECTOR(config, m_floppy[0], pc1512_floppies, "525dd", pc1512_base_state::floppy_formats);
1357 FLOPPY_CONNECTOR(config, m_floppy[1], pc1512_floppies, nullptr, pc1512_base_state::floppy_formats);
1358
1359 INS8250(config, m_uart, 1.8432_MHz_XTAL);
1360 m_uart->out_tx_callback().set(RS232_TAG, FUNC(rs232_port_device::write_txd));
1361 m_uart->out_dtr_callback().set(RS232_TAG, FUNC(rs232_port_device::write_dtr));
1362 m_uart->out_rts_callback().set(RS232_TAG, FUNC(rs232_port_device::write_rts));
1363 m_uart->out_int_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
1364
1365 CENTRONICS(config, m_centronics, centronics_devices, "printer");
1366 m_centronics->ack_handler().set(FUNC(pc1512_state::write_centronics_ack));
1367 m_centronics->busy_handler().set(FUNC(pc1512_state::write_centronics_busy));
1368 m_centronics->perror_handler().set(FUNC(pc1512_state::write_centronics_perror));
1369 m_centronics->select_handler().set(FUNC(pc1512_state::write_centronics_select));
1370 m_centronics->fault_handler().set(FUNC(pc1512_state::write_centronics_fault));
1371
1372 OUTPUT_LATCH(config, m_cent_data_out);
1373 m_centronics->set_output_latch(*m_cent_data_out);
1374
1375 rs232_port_device &rs232(RS232_PORT(config, RS232_TAG, default_rs232_devices, nullptr));
1376 rs232.rxd_handler().set(m_uart, FUNC(ins8250_uart_device::rx_w));
1377 rs232.dcd_handler().set(m_uart, FUNC(ins8250_uart_device::dcd_w));
1378 rs232.dsr_handler().set(m_uart, FUNC(ins8250_uart_device::dsr_w));
1379 rs232.ri_handler().set(m_uart, FUNC(ins8250_uart_device::ri_w));
1380 rs232.cts_handler().set(m_uart, FUNC(ins8250_uart_device::cts_w));
1381
1382 // ISA8 bus
1383 isa8_device &isa(ISA8(config, ISA_BUS_TAG, 0));
1384 isa.set_memspace(m_maincpu, AS_PROGRAM);
1385 isa.set_iospace(m_maincpu, AS_IO);
1386 isa.irq2_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
1387 isa.irq3_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
1388 isa.irq4_callback().set(m_pic, FUNC(pic8259_device::ir4_w));
1389 isa.irq5_callback().set(m_pic, FUNC(pic8259_device::ir5_w));
1390 isa.irq6_callback().set(m_pic, FUNC(pic8259_device::ir6_w));
1391 isa.irq7_callback().set(m_pic, FUNC(pic8259_device::ir7_w));
1392 isa.drq1_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq1_w));
1393 isa.drq2_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq2_w));
1394 isa.drq3_callback().set(I8237A5_TAG, FUNC(am9517a_device::dreq3_w));
1395 ISA8_SLOT(config, "isa1", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false); // FIXME: determine ISA bus clock
1396 ISA8_SLOT(config, "isa2", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false);
1397 ISA8_SLOT(config, "isa3", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false);
1398 ISA8_SLOT(config, "isa4", 0, ISA_BUS_TAG, pc_isa8_cards, nullptr, false);
1399 ISA8_SLOT(config, "isa5", 0, ISA_BUS_TAG, pc1640_isa8_cards, "iga", false);
1400
1401 // internal ram
1402 RAM(config, RAM_TAG).set_default_size("640K");
1403
1404 // software list
1405 SOFTWARE_LIST(config, "flop_list").set_original("pc1640_flop");
1406 SOFTWARE_LIST(config, "hdd_list").set_original("pc1640_hdd");
1407 }
1408
1409
1410 //-------------------------------------------------
1411 // machine_config( pc1640dd )
1412 //-------------------------------------------------
1413
pc1640dd(machine_config & config)1414 void pc1640_state::pc1640dd(machine_config &config)
1415 {
1416 pc1640(config);
1417 m_floppy[1]->set_default_option("525dd");
1418 }
1419
1420
1421 //-------------------------------------------------
1422 // machine_config( pc1640hd )
1423 //-------------------------------------------------
1424
pc1640hd(machine_config & config)1425 void pc1640_state::pc1640hd(machine_config &config)
1426 {
1427 pc1640(config);
1428 //subdevice<isa8_slot_device>("isa1")->set_default_option("wdxt_gen");
1429 subdevice<isa8_slot_device>("isa1")->set_default_option("hdc");
1430 }
1431
1432
1433
1434 //**************************************************************************
1435 // ROMS
1436 //**************************************************************************
1437
1438 //-------------------------------------------------
1439 // ROM( pc1512 )
1440 //-------------------------------------------------
1441
1442 ROM_START( pc1512 )
1443 ROM_REGION16_LE( 0x4000, I8086_TAG, 0)
1444 ROM_SYSTEM_BIOS( 0, "v1", "Version 1" )
1445 ROMX_LOAD( "40044.ic132", 0x0000, 0x2000, CRC(f72f1582) SHA1(7781d4717917262805d514b331ba113b1e05a247), ROM_SKIP(1) | ROM_BIOS(0) )
1446 ROMX_LOAD( "40043.ic129", 0x0001, 0x2000, CRC(668fcc94) SHA1(74002f5cc542df442eec9e2e7a18db3598d8c482), ROM_SKIP(1) | ROM_BIOS(0) )
1447 ROM_SYSTEM_BIOS( 1, "v2", "Version 2" )
1448 ROMX_LOAD( "40044v2.ic132", 0x0000, 0x2000, CRC(1aec54fa) SHA1(b12fd73cfc35a240ed6da4dcc4b6c9910be611e0), ROM_SKIP(1) | ROM_BIOS(1) )
1449 ROMX_LOAD( "40043v2.ic129", 0x0001, 0x2000, CRC(d2d4d2de) SHA1(c376fd1ad23025081ae16c7949e88eea7f56e1bb), ROM_SKIP(1) | ROM_BIOS(1) )
1450 ROM_SYSTEM_BIOS( 2, "v3", "Version 3" )
1451 ROMX_LOAD( "40044-2.ic132", 0x0000, 0x2000, CRC(ea527e6e) SHA1(b77fa44767a71a0b321a88bb0a394f1125b7c220), ROM_SKIP(1) | ROM_BIOS(2) )
1452 ROMX_LOAD( "40043-2.ic129", 0x0001, 0x2000, CRC(532c3854) SHA1(18a17b710f9eb079d9d7216d07807030f904ceda), ROM_SKIP(1) | ROM_BIOS(2) )
1453
1454 ROM_REGION( 0x2000, AMS40041_TAG, 0 )
1455 ROMX_LOAD( "40045.ic127", 0x0000, 0x2000, CRC(dd5e030f) SHA1(7d858bbb2e8d6143aa67ab712edf5f753c2788a7), ROM_BIOS(0) )
1456 ROMX_LOAD( "40078.ic127", 0x0000, 0x2000, CRC(ae9c0d04) SHA1(bc8dc4dcedeea5bc1c04986b1f105ad93cb2ebcd), ROM_BIOS(1) )
1457 ROMX_LOAD( "40078.ic127", 0x0000, 0x2000, CRC(ae9c0d04) SHA1(bc8dc4dcedeea5bc1c04986b1f105ad93cb2ebcd), ROM_BIOS(2) )
1458 ROM_END
1459
1460 #define rom_pc1512dd rom_pc1512
1461 #define rom_pc1512hd10 rom_pc1512
1462 #define rom_pc1512hd20 rom_pc1512
1463
1464
1465 //-------------------------------------------------
1466 // ROM( pc1640 )
1467 //-------------------------------------------------
1468
1469 ROM_START( pc1640 )
1470 ROM_REGION16_LE( 0x4000, I8086_TAG, 0)
1471 ROM_SYSTEM_BIOS( 0, "8809", "Week 9/1988" )
1472 ROMX_LOAD( "40044-1 8809.ic132", 0x0000, 0x2000, CRC(f1c074f3) SHA1(a055ea7e933d137623c22fe24004e870653c7952), ROM_SKIP(1) | ROM_BIOS(0) ) // 8809 B
1473 ROMX_LOAD( "40043-1 8809.ic129", 0x0001, 0x2000, CRC(e40a1513) SHA1(447eff2057e682e51b1c7593cb6fad0e53879fa8), ROM_SKIP(1) | ROM_BIOS(0) ) // 8809 B
1474 ROM_SYSTEM_BIOS( 1, "8738", "Week 38/1987" )
1475 ROMX_LOAD( "40044 8738.ic132", 0x0000, 0x2000, CRC(43832ea7) SHA1(eea4a8836f966940a88c88de6c5cc14852545f7d), ROM_SKIP(1) | ROM_BIOS(1) ) // 8738 D F
1476 ROMX_LOAD( "40043 8738.ic129", 0x0001, 0x2000, CRC(768498f9) SHA1(ac48cb892417d7998d604f3b79756140c554f476), ROM_SKIP(1) | ROM_BIOS(1) ) // 8738 D F
1477 ROM_SYSTEM_BIOS( 2, "88xx", "Week ?/1988" )
1478 ROMX_LOAD( "40044 88xx.ic132", 0x0000, 0x2000, CRC(6090f782) SHA1(e21ae524d5b4d00696d293dbd4fe4d7bca22e277), ROM_SKIP(1) | ROM_BIOS(2) )
1479 ROMX_LOAD( "40043 88xx.ic129", 0x0001, 0x2000, CRC(9219d0aa) SHA1(dde1a46c8f83e413d7070f1356fc91b9f595a8b6), ROM_SKIP(1) | ROM_BIOS(2) )
1480 ROM_END
1481
1482 #define rom_pc1640dd rom_pc1640
1483 #define rom_pc1640hd20 rom_pc1640
1484 #define rom_pc1640hd30 rom_pc1640
1485
1486
1487
1488 //**************************************************************************
1489 // SYSTEM DRIVERS
1490 //**************************************************************************
1491
1492 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
1493 COMP( 1986, pc1512, 0, 0, pc1512, pc1512, pc1512_state, empty_init, "Amstrad plc", "PC1512 SD", MACHINE_SUPPORTS_SAVE )
1494 COMP( 1986, pc1512dd, pc1512, 0, pc1512dd, pc1512, pc1512_state, empty_init, "Amstrad plc", "PC1512 DD", MACHINE_SUPPORTS_SAVE )
1495 COMP( 1986, pc1512hd10, pc1512, 0, pc1512hd, pc1512, pc1512_state, empty_init, "Amstrad plc", "PC1512 HD10", MACHINE_SUPPORTS_SAVE )
1496 COMP( 1986, pc1512hd20, pc1512, 0, pc1512hd, pc1512, pc1512_state, empty_init, "Amstrad plc", "PC1512 HD20", MACHINE_SUPPORTS_SAVE )
1497 COMP( 1987, pc1640, 0, 0, pc1640, pc1640, pc1640_state, empty_init, "Amstrad plc", "PC1640 SD", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
1498 COMP( 1987, pc1640dd, pc1640, 0, pc1640dd, pc1640, pc1640_state, empty_init, "Amstrad plc", "PC1640 DD", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
1499 COMP( 1987, pc1640hd20, pc1640, 0, pc1640hd, pc1640, pc1640_state, empty_init, "Amstrad plc", "PC1640 HD20", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
1500 COMP( 1987, pc1640hd30, pc1640, 0, pc1640hd, pc1640, pc1640_state, empty_init, "Amstrad plc", "PC1640 HD30", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
1501