trunk/src/mess/drivers/ngen.c
| r243572 | r243573 | |
| 15 | 15 | channel 1 - X-Bus expansion modules (except disk and graphics) |
| 16 | 16 | channel 2 - graphics? |
| 17 | 17 | channel 3 - hard disk |
| 18 | On the CP-001/B26 channels 4 on are handled by the 80186. |
| 19 | channel 4 - floppy disk |
| 18 | 20 | |
| 19 | 21 | To get to "menu mode", press Space quickly after reset (might need good timing) |
| 20 | 22 | The bootstrap ROM version number is displayed, along with "B,D,L,M,P,T:" |
| r243572 | r243573 | |
| 79 | 81 | ngen_state(const machine_config &mconfig, device_type type, const char *tag) |
| 80 | 82 | : driver_device(mconfig, type, tag), |
| 81 | 83 | m_maincpu(*this,"maincpu"), |
| 84 | m_i386cpu(*this,"i386cpu"), |
| 82 | 85 | m_crtc(*this,"crtc"), |
| 83 | 86 | m_viduart(*this,"videouart"), |
| 84 | 87 | m_iouart(*this,"iouart"), |
| r243572 | r243573 | |
| 141 | 144 | virtual void machine_start(); |
| 142 | 145 | |
| 143 | 146 | private: |
| 144 | | required_device<i80186_cpu_device> m_maincpu; |
| 147 | optional_device<i80186_cpu_device> m_maincpu; |
| 148 | optional_device<i386_device> m_i386cpu; |
| 145 | 149 | required_device<mc6845_device> m_crtc; |
| 146 | 150 | required_device<i8251_device> m_viduart; |
| 147 | 151 | required_device<upd7201_device> m_iouart; |
| r243572 | r243573 | |
| 175 | 179 | UINT8 m_disk_page; |
| 176 | 180 | }; |
| 177 | 181 | |
| 178 | | class ngen386_state : public driver_device |
| 182 | class ngen386_state : public ngen_state |
| 179 | 183 | { |
| 180 | 184 | public: |
| 181 | 185 | ngen386_state(const machine_config &mconfig, device_type type, const char *tag) |
| 182 | | : driver_device(mconfig, type, tag), |
| 183 | | m_maincpu(*this,"maincpu"), |
| 184 | | m_pic(*this,"pic") |
| 186 | : ngen_state(mconfig, type, tag) |
| 185 | 187 | {} |
| 186 | 188 | private: |
| 187 | | required_device<i386_device> m_maincpu; |
| 188 | | required_device<pic8259_device> m_pic; |
| 189 | 189 | }; |
| 190 | 190 | |
| 191 | 191 | WRITE_LINE_MEMBER(ngen_state::pit_out0_w) |
| r243572 | r243573 | |
| 210 | 210 | |
| 211 | 211 | WRITE_LINE_MEMBER(ngen_state::cpu_timer_w) |
| 212 | 212 | { |
| 213 | | logerror("80186 Timer 1 state %i\n",state); |
| 213 | if(state != 0) |
| 214 | popmessage("80186 Timer 0 state %i\n",state); |
| 215 | m_pic->ir5_w(state); |
| 214 | 216 | } |
| 215 | 217 | |
| 216 | 218 | WRITE_LINE_MEMBER(ngen_state::timer_clk_out) |
| 217 | 219 | { |
| 218 | 220 | m_viduart->write_rxc(state); // Keyboard UART Rx/Tx clocks |
| 219 | 221 | m_viduart->write_txc(state); |
| 222 | // 80186 timer pins also? EXT bit is enabled for BTOS PIT test. |
| 223 | if(m_maincpu) |
| 224 | { |
| 225 | m_maincpu->tmrin0_w(state); |
| 226 | //m_maincpu->tmrin1_w(state); |
| 227 | } |
| 220 | 228 | } |
| 221 | 229 | |
| 222 | 230 | WRITE16_MEMBER(ngen_state::cpu_peripheral_cb) |
| r243572 | r243573 | |
| 273 | 281 | case 0x0f: |
| 274 | 282 | if(mem_mask & 0x00ff) |
| 275 | 283 | m_dmac->write(space,offset,data & 0xff); |
| 276 | | logerror("(PC=%06x) DMA write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 277 | 284 | break; |
| 278 | 285 | case 0x80: // DMA page offset? |
| 279 | 286 | case 0x81: |
| r243572 | r243573 | |
| 321 | 328 | m_viduart->control_w(space,0,data & 0xff); |
| 322 | 329 | break; |
| 323 | 330 | case 0x1a0: // serial? |
| 324 | | logerror("(PC=%06x) Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 331 | logerror("Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",offset,data,mem_mask); |
| 325 | 332 | break; |
| 326 | 333 | default: |
| 327 | | logerror("(PC=%06x) Unknown 80186 peripheral write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 334 | logerror("Unknown 80186 peripheral write offset %04x data %04x mask %04x\n",offset,data,mem_mask); |
| 328 | 335 | } |
| 329 | 336 | } |
| 330 | 337 | |
| r243572 | r243573 | |
| 351 | 358 | case 0x0f: |
| 352 | 359 | if(mem_mask & 0x00ff) |
| 353 | 360 | ret = m_dmac->read(space,offset); |
| 354 | | logerror("(PC=%06x) DMA read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret); |
| 361 | logerror("DMA read offset %04x mask %04x returning %04x\n",offset,mem_mask,ret); |
| 355 | 362 | break; |
| 356 | 363 | case 0x80: // DMA page offset? |
| 357 | 364 | case 0x81: |
| r243572 | r243573 | |
| 398 | 405 | case 0x1a0: // I/O control register? |
| 399 | 406 | ret = m_control; // end of DMA transfer? (maybe a per-channel EOP?) Bit 6 is set during a transfer? |
| 400 | 407 | break; |
| 401 | | default: |
| 402 | | logerror("(PC=%06x) Unknown 80186 peripheral read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret); |
| 408 | // default: |
| 409 | // logerror("Unknown 80186 peripheral read offset %04x mask %04x returning %04x\n",offset,mem_mask,ret); |
| 403 | 410 | } |
| 404 | 411 | return ret; |
| 405 | 412 | } |
| r243572 | r243573 | |
| 412 | 419 | WRITE16_MEMBER(ngen_state::xbus_w) |
| 413 | 420 | { |
| 414 | 421 | UINT16 addr = (data & 0x00ff) << 8; |
| 415 | | address_space& io = m_maincpu->device_t::memory().space(AS_IO); |
| 422 | cpu_device* cpu; |
| 423 | |
| 424 | if(m_maincpu) |
| 425 | cpu = m_maincpu; |
| 426 | else |
| 427 | cpu = m_i386cpu; |
| 428 | address_space& io = cpu->device_t::memory().space(AS_IO); |
| 416 | 429 | switch(m_xbus_current) |
| 417 | 430 | { |
| 418 | 431 | case 0x00: // Floppy/Hard disk module |
| 419 | 432 | io.install_readwrite_handler(addr,addr+0xff,0,0,read16_delegate(FUNC(ngen_state::fhd_r),this),write16_delegate(FUNC(ngen_state::hfd_w),this)); |
| 420 | 433 | break; |
| 421 | 434 | default: |
| 422 | | m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); // reached end of the modules |
| 435 | cpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); // reached end of the modules |
| 423 | 436 | break; |
| 424 | 437 | } |
| 425 | 438 | if(addr != 0) |
| r243572 | r243573 | |
| 442 | 455 | ret = 0x1070; // Floppy/Hard disk module |
| 443 | 456 | break; |
| 444 | 457 | default: |
| 445 | | m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); // reached the end of the modules |
| 458 | if(m_maincpu) |
| 459 | m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); // reached the end of the modules |
| 460 | else |
| 461 | m_i386cpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); |
| 446 | 462 | ret = 0x0080; |
| 447 | 463 | break; |
| 448 | 464 | } |
| r243572 | r243573 | |
| 458 | 474 | case 0x00: |
| 459 | 475 | case 0x01: |
| 460 | 476 | case 0x02: |
| 477 | if(mem_mask & 0x00ff) |
| 478 | m_fdc->write(space,offset,data & 0xff); |
| 479 | break; |
| 461 | 480 | case 0x03: |
| 462 | 481 | if(mem_mask & 0x00ff) |
| 482 | { |
| 463 | 483 | m_fdc->write(space,offset,data & 0xff); |
| 484 | m_fdc_timer->write_clk0(1); |
| 485 | m_fdc_timer->write_clk0(0); // Data register access clocks the FDC's PIT channel 0 |
| 486 | } |
| 464 | 487 | break; |
| 465 | 488 | case 0x04: |
| 466 | 489 | if(mem_mask & 0x00ff) |
| 467 | | fdc_control_w(space,offset,data & 0xff); |
| 490 | fdc_control_w(space,0,data & 0xff); |
| 468 | 491 | break; |
| 469 | 492 | case 0x05: |
| 470 | 493 | if(mem_mask & 0x00ff) |
| 471 | | hdc_control_w(space,offset,data & 0xff); |
| 494 | hdc_control_w(space,0,data & 0xff); |
| 472 | 495 | break; |
| 473 | 496 | case 0x07: |
| 474 | 497 | if(mem_mask & 0x00ff) |
| 475 | | disk_addr_ext(space,offset,data & 0xff); |
| 498 | disk_addr_ext(space,0,data & 0xff); |
| 476 | 499 | break; |
| 477 | 500 | case 0x08: |
| 478 | 501 | case 0x09: |
| r243572 | r243573 | |
| 512 | 535 | case 0x00: |
| 513 | 536 | case 0x01: |
| 514 | 537 | case 0x02: |
| 538 | if(mem_mask & 0x00ff) |
| 539 | ret = m_fdc->read(space,offset); |
| 540 | break; |
| 515 | 541 | case 0x03: |
| 516 | 542 | if(mem_mask & 0x00ff) |
| 543 | { |
| 517 | 544 | ret = m_fdc->read(space,offset); |
| 545 | m_fdc_timer->write_clk0(1); |
| 546 | m_fdc_timer->write_clk0(0); // Data register access clocks the FDC's PIT channel 0 |
| 547 | } |
| 518 | 548 | break; |
| 519 | 549 | case 0x08: |
| 520 | 550 | case 0x09: |
| r243572 | r243573 | |
| 610 | 640 | |
| 611 | 641 | WRITE_LINE_MEMBER( ngen_state::dma_hrq_changed ) |
| 612 | 642 | { |
| 613 | | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 643 | if(m_maincpu) |
| 644 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 645 | else |
| 646 | m_i386cpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 614 | 647 | } |
| 615 | 648 | |
| 616 | 649 | WRITE_LINE_MEMBER( ngen_state::dma_eop_changed ) |
| r243572 | r243573 | |
| 665 | 698 | |
| 666 | 699 | READ8_MEMBER(ngen_state::dma_read_word) |
| 667 | 700 | { |
| 668 | | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 701 | cpu_device* cpu; |
| 669 | 702 | UINT16 result; |
| 703 | |
| 704 | if(m_maincpu) |
| 705 | cpu = m_maincpu; |
| 706 | else |
| 707 | cpu = m_i386cpu; |
| 708 | address_space& prog_space = cpu->space(AS_PROGRAM); // get the right address space |
| 709 | |
| 670 | 710 | if(m_dma_channel == -1) |
| 671 | 711 | return 0xff; |
| 672 | 712 | offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFE0000; |
| r243572 | r243573 | |
| 680 | 720 | |
| 681 | 721 | WRITE8_MEMBER(ngen_state::dma_write_word) |
| 682 | 722 | { |
| 683 | | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 723 | cpu_device* cpu; |
| 724 | |
| 725 | if(m_maincpu) |
| 726 | cpu = m_maincpu; |
| 727 | else |
| 728 | cpu = m_i386cpu; |
| 729 | address_space& prog_space = cpu->space(AS_PROGRAM); // get the right address space |
| 730 | |
| 684 | 731 | if(m_dma_channel == -1) |
| 685 | 732 | return; |
| 686 | 733 | offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFE0000; |
| r243572 | r243573 | |
| 727 | 774 | m_fd0->get_device()->set_rpm(300); |
| 728 | 775 | } |
| 729 | 776 | |
| 777 | // boot ROMs from modules are not mapped anywhere, instead, they have to send the code from the boot ROM via DMA |
| 730 | 778 | static ADDRESS_MAP_START( ngen_mem, AS_PROGRAM, 16, ngen_state ) |
| 731 | 779 | AM_RANGE(0x00000, 0xf7fff) AM_RAM |
| 732 | 780 | AM_RANGE(0xf8000, 0xf9fff) AM_RAM AM_SHARE("vram") |
| 733 | 781 | AM_RANGE(0xfa000, 0xfbfff) AM_RAM AM_SHARE("fontram") |
| 734 | | AM_RANGE(0xfc000, 0xfcfff) AM_ROM AM_REGION("disk",0) |
| 782 | AM_RANGE(0xfc000, 0xfcfff) AM_RAM |
| 735 | 783 | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("bios",0) |
| 736 | 784 | ADDRESS_MAP_END |
| 737 | 785 | |
| r243572 | r243573 | |
| 751 | 799 | |
| 752 | 800 | static ADDRESS_MAP_START( ngen386_mem, AS_PROGRAM, 32, ngen_state ) |
| 753 | 801 | AM_RANGE(0x00000000, 0x000fdfff) AM_RAM |
| 802 | AM_RANGE(0x000f8000, 0x000f9fff) AM_RAM AM_SHARE("vram") |
| 803 | AM_RANGE(0x000fa000, 0x000fbfff) AM_RAM AM_SHARE("fontram") |
| 804 | AM_RANGE(0x000fc000, 0x000fcfff) AM_RAM |
| 754 | 805 | AM_RANGE(0x000fe000, 0x000fffff) AM_ROM AM_REGION("bios",0) |
| 755 | 806 | AM_RANGE(0xffffe000, 0xffffffff) AM_ROM AM_REGION("bios",0) |
| 756 | 807 | ADDRESS_MAP_END |
| 757 | 808 | |
| 758 | 809 | static ADDRESS_MAP_START( ngen386i_mem, AS_PROGRAM, 32, ngen_state ) |
| 759 | 810 | AM_RANGE(0x00000000, 0x000fbfff) AM_RAM |
| 811 | AM_RANGE(0x000f8000, 0x000f9fff) AM_RAM AM_SHARE("vram") |
| 812 | AM_RANGE(0x000fa000, 0x000fbfff) AM_RAM AM_SHARE("fontram") |
| 760 | 813 | AM_RANGE(0x000fc000, 0x000fffff) AM_ROM AM_REGION("bios",0) |
| 761 | 814 | AM_RANGE(0xffffc000, 0xffffffff) AM_ROM AM_REGION("bios",0) |
| 762 | 815 | ADDRESS_MAP_END |
| 763 | 816 | |
| 764 | 817 | static ADDRESS_MAP_START( ngen386_io, AS_IO, 32, ngen_state ) |
| 765 | | AM_RANGE(0xfd0c, 0xfd0f) AM_DEVREADWRITE8("pic",pic8259_device,read,write,0xffffffff) |
| 818 | AM_RANGE(0x0000, 0x0003) AM_READWRITE16(xbus_r, xbus_w, 0x0000ffff) |
| 819 | AM_RANGE(0xf800, 0xfeff) AM_READWRITE16(peripheral_r, peripheral_w,0xffffffff) |
| 766 | 820 | ADDRESS_MAP_END |
| 767 | 821 | |
| 768 | 822 | static INPUT_PORTS_START( ngen ) |
| r243572 | r243573 | |
| 782 | 836 | MCFG_CPU_PROGRAM_MAP(ngen_mem) |
| 783 | 837 | MCFG_CPU_IO_MAP(ngen_io) |
| 784 | 838 | MCFG_80186_CHIP_SELECT_CB(WRITE16(ngen_state, cpu_peripheral_cb)) |
| 785 | | MCFG_80186_TMROUT1_HANDLER(WRITELINE(ngen_state, cpu_timer_w)) |
| 839 | MCFG_80186_TMROUT0_HANDLER(WRITELINE(ngen_state, cpu_timer_w)) |
| 786 | 840 | MCFG_80186_IRQ_SLAVE_ACK(READ8(ngen_state, irq_cb)) |
| 787 | 841 | |
| 788 | 842 | MCFG_PIC8259_ADD( "pic", DEVWRITELINE("maincpu",i80186_cpu_device,int0_w), VCC, NULL ) |
| r243572 | r243573 | |
| 851 | 905 | |
| 852 | 906 | // keyboard UART (patent says i8251 is used for keyboard communications, it is located on the video board) |
| 853 | 907 | MCFG_DEVICE_ADD("videouart", I8251, 0) // main clock unknown, Rx/Tx clocks are 19.53kHz |
| 854 | | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 908 | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 855 | 909 | MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", rs232_port_device, write_txd)) |
| 856 | 910 | MCFG_RS232_PORT_ADD("keyboard", keyboard, "ngen") |
| 857 | 911 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("videouart", i8251_device, write_rxd)) |
| r243572 | r243573 | |
| 865 | 919 | MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("maincpu",i80186_cpu_device,drq1_w)) |
| 866 | 920 | MCFG_WD_FDC_FORCE_READY |
| 867 | 921 | MCFG_DEVICE_ADD("fdc_timer", PIT8253, 0) |
| 868 | | MCFG_PIT8253_CLK0(XTAL_20MHz / 20) |
| 869 | | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) // clocked on FDC data register access |
| 922 | MCFG_PIT8253_CLK0(0) |
| 923 | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) // clocked on FDC data register access |
| 870 | 924 | MCFG_PIT8253_CLK1(XTAL_20MHz / 20) |
| 871 | | MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) // 1MHz |
| 872 | | MCFG_PIT8253_CLK2(XTAL_20MHz / 10) |
| 873 | | MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 925 | // MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) // 1MHz |
| 926 | MCFG_PIT8253_CLK2(XTAL_20MHz / 20) |
| 927 | // MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) |
| 928 | |
| 874 | 929 | // TODO: WD1010 HDC (not implemented), use WD2010 for now |
| 875 | 930 | MCFG_DEVICE_ADD("hdc", WD2010, XTAL_20MHz / 4) |
| 931 | MCFG_WD2010_OUT_INTRQ_CB(DEVWRITELINE("pic",pic8259_device,ir2_w)) |
| 876 | 932 | MCFG_WD2010_IN_BCS_CB(READ8(ngen_state,hd_buffer_r)) |
| 877 | 933 | MCFG_WD2010_OUT_BCS_CB(WRITE8(ngen_state,hd_buffer_w)) |
| 878 | 934 | MCFG_WD2010_IN_DRDY_CB(VCC) |
| r243572 | r243573 | |
| 888 | 944 | MACHINE_CONFIG_END |
| 889 | 945 | |
| 890 | 946 | static MACHINE_CONFIG_START( ngen386, ngen386_state ) |
| 891 | | MCFG_CPU_ADD("maincpu", I386, XTAL_50MHz / 2) |
| 947 | MCFG_CPU_ADD("i386cpu", I386, XTAL_50MHz / 2) |
| 892 | 948 | MCFG_CPU_PROGRAM_MAP(ngen386_mem) |
| 893 | 949 | MCFG_CPU_IO_MAP(ngen386_io) |
| 894 | | MCFG_PIC8259_ADD( "pic", INPUTLINE("maincpu", 0), VCC, NULL ) |
| 950 | MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic", pic8259_device, inta_cb) |
| 951 | |
| 952 | MCFG_PIC8259_ADD( "pic", INPUTLINE("i386cpu",0), VCC, NULL ) |
| 953 | |
| 954 | MCFG_DEVICE_ADD("pit", PIT8254, 0) |
| 955 | MCFG_PIT8253_CLK0(78120/4) // 19.53kHz, /4 of the CPU timer output? |
| 956 | MCFG_PIT8253_OUT0_HANDLER(WRITELINE(ngen_state, pit_out0_w)) // RS232 channel B baud rate |
| 957 | MCFG_PIT8253_CLK1(XTAL_14_7456MHz/12) // correct? - based on patent |
| 958 | MCFG_PIT8253_OUT1_HANDLER(WRITELINE(ngen_state, pit_out1_w)) // RS232 channel A baud rate |
| 959 | MCFG_PIT8253_CLK2(XTAL_14_7456MHz/12) |
| 960 | MCFG_PIT8253_OUT2_HANDLER(WRITELINE(ngen_state, pit_out2_w)) |
| 961 | |
| 962 | MCFG_DEVICE_ADD("dmac", AM9517A, XTAL_14_7456MHz / 3) // NEC D8237A, divisor unknown |
| 963 | MCFG_I8237_OUT_HREQ_CB(WRITELINE(ngen_state, dma_hrq_changed)) |
| 964 | MCFG_I8237_OUT_EOP_CB(WRITELINE(ngen_state, dma_eop_changed)) |
| 965 | MCFG_I8237_IN_MEMR_CB(READ8(ngen_state, dma_read_word)) // DMA is always 16-bit |
| 966 | MCFG_I8237_OUT_MEMW_CB(WRITE8(ngen_state, dma_write_word)) |
| 967 | MCFG_I8237_OUT_DACK_0_CB(WRITELINE(ngen_state, dack0_w)) |
| 968 | MCFG_I8237_OUT_DACK_1_CB(WRITELINE(ngen_state, dack1_w)) |
| 969 | MCFG_I8237_OUT_DACK_2_CB(WRITELINE(ngen_state, dack2_w)) |
| 970 | MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ngen_state, dack3_w)) |
| 971 | MCFG_I8237_IN_IOR_0_CB(READ8(ngen_state, dma_0_dack_r)) |
| 972 | MCFG_I8237_IN_IOR_1_CB(READ8(ngen_state, dma_1_dack_r)) |
| 973 | MCFG_I8237_IN_IOR_2_CB(READ8(ngen_state, dma_2_dack_r)) |
| 974 | MCFG_I8237_IN_IOR_3_CB(READ8(ngen_state, dma_3_dack_r)) |
| 975 | MCFG_I8237_OUT_IOW_0_CB(WRITE8(ngen_state, dma_0_dack_w)) |
| 976 | MCFG_I8237_OUT_IOW_1_CB(WRITE8(ngen_state, dma_1_dack_w)) |
| 977 | MCFG_I8237_OUT_IOW_2_CB(WRITE8(ngen_state, dma_2_dack_w)) |
| 978 | MCFG_I8237_OUT_IOW_3_CB(WRITE8(ngen_state, dma_3_dack_w)) |
| 979 | |
| 980 | // I/O board |
| 981 | MCFG_UPD7201_ADD("iouart",0,0,0,0,0) // clocked by PIT channel 2? |
| 982 | MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd)) |
| 983 | MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd)) |
| 984 | MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr)) |
| 985 | MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_dtr)) |
| 986 | MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_rts)) |
| 987 | MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_rts)) |
| 988 | |
| 989 | MCFG_RS232_PORT_ADD("rs232_a", default_rs232_devices, NULL) |
| 990 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("iouart", upd7201_device, rxa_w)) |
| 991 | MCFG_RS232_CTS_HANDLER(DEVWRITELINE("iouart", upd7201_device, ctsa_w)) |
| 992 | MCFG_RS232_DCD_HANDLER(DEVWRITELINE("iouart", upd7201_device, dcda_w)) |
| 993 | MCFG_RS232_RI_HANDLER(DEVWRITELINE("iouart", upd7201_device, ria_w)) |
| 994 | |
| 995 | MCFG_RS232_PORT_ADD("rs232_b", default_rs232_devices, NULL) |
| 996 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("iouart", upd7201_device, rxb_w)) |
| 997 | MCFG_RS232_CTS_HANDLER(DEVWRITELINE("iouart", upd7201_device, ctsb_w)) |
| 998 | MCFG_RS232_DCD_HANDLER(DEVWRITELINE("iouart", upd7201_device, dcdb_w)) |
| 999 | MCFG_RS232_RI_HANDLER(DEVWRITELINE("iouart", upd7201_device, rib_w)) |
| 1000 | |
| 1001 | // TODO: SCN2652 MPCC (not implemented), used for RS-422 cluster communications? |
| 1002 | |
| 1003 | // video board |
| 1004 | MCFG_SCREEN_ADD("screen", RASTER) |
| 1005 | MCFG_SCREEN_SIZE(720,348) |
| 1006 | MCFG_SCREEN_VISIBLE_AREA(0,719,0,347) |
| 1007 | MCFG_SCREEN_REFRESH_RATE(60) |
| 1008 | MCFG_SCREEN_UPDATE_DEVICE("crtc",mc6845_device, screen_update) |
| 1009 | |
| 1010 | MCFG_MC6845_ADD("crtc", MC6845, NULL, 19980000 / 9) // divisor unknown -- /9 gives 60Hz output, so likely correct |
| 1011 | MCFG_MC6845_SHOW_BORDER_AREA(false) |
| 1012 | MCFG_MC6845_CHAR_WIDTH(9) |
| 1013 | MCFG_MC6845_UPDATE_ROW_CB(ngen_state, crtc_update_row) |
| 1014 | MCFG_VIDEO_SET_SCREEN("screen") |
| 1015 | |
| 1016 | // keyboard UART (patent says i8251 is used for keyboard communications, it is located on the video board) |
| 1017 | MCFG_DEVICE_ADD("videouart", I8251, 0) // main clock unknown, Rx/Tx clocks are 19.53kHz |
| 1018 | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 1019 | MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", rs232_port_device, write_txd)) |
| 1020 | MCFG_RS232_PORT_ADD("keyboard", keyboard, "ngen") |
| 1021 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("videouart", i8251_device, write_rxd)) |
| 1022 | |
| 1023 | MCFG_DEVICE_ADD("refresh_clock", CLOCK, 19200*16) // should be 19530Hz |
| 1024 | MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(ngen_state,timer_clk_out)) |
| 1025 | |
| 1026 | // floppy disk / hard disk module (WD2797 FDC, WD1010 HDC, plus an 8253 timer for each) |
| 1027 | MCFG_WD2797x_ADD("fdc", XTAL_20MHz / 20) |
| 1028 | MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(ngen_state,fdc_irq_w)) |
| 1029 | // MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("i386cpu",i80186_cpu_device,drq1_w)) |
| 1030 | MCFG_WD_FDC_FORCE_READY |
| 1031 | MCFG_DEVICE_ADD("fdc_timer", PIT8253, 0) |
| 1032 | MCFG_PIT8253_CLK0(0) |
| 1033 | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) // clocked on FDC data register access |
| 1034 | MCFG_PIT8253_CLK1(XTAL_20MHz / 20) |
| 1035 | // MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) // 1MHz |
| 1036 | MCFG_PIT8253_CLK2(XTAL_20MHz / 20) |
| 1037 | // MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir5_w)) |
| 1038 | |
| 1039 | // TODO: WD1010 HDC (not implemented), use WD2010 for now |
| 1040 | MCFG_DEVICE_ADD("hdc", WD2010, XTAL_20MHz / 4) |
| 1041 | MCFG_WD2010_OUT_INTRQ_CB(DEVWRITELINE("pic",pic8259_device,ir2_w)) |
| 1042 | MCFG_WD2010_IN_BCS_CB(READ8(ngen_state,hd_buffer_r)) |
| 1043 | MCFG_WD2010_OUT_BCS_CB(WRITE8(ngen_state,hd_buffer_w)) |
| 1044 | MCFG_WD2010_IN_DRDY_CB(VCC) |
| 1045 | MCFG_WD2010_IN_INDEX_CB(VCC) |
| 1046 | MCFG_WD2010_IN_WF_CB(VCC) |
| 1047 | MCFG_WD2010_IN_TK000_CB(VCC) |
| 1048 | MCFG_WD2010_IN_SC_CB(VCC) |
| 1049 | MCFG_DEVICE_ADD("hdc_timer", PIT8253, 0) |
| 1050 | MCFG_PIT8253_CLK2(XTAL_20MHz / 10) // 2MHz |
| 1051 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ngen_floppies, "525qd", floppy_image_device::default_floppy_formats) |
| 1052 | MCFG_HARDDISK_ADD("hard0") |
| 895 | 1053 | MACHINE_CONFIG_END |
| 896 | 1054 | |
| 897 | 1055 | static MACHINE_CONFIG_DERIVED( 386i, ngen386 ) |
| 898 | | MCFG_CPU_MODIFY("maincpu") |
| 1056 | MCFG_CPU_MODIFY("i386cpu") |
| 899 | 1057 | MCFG_CPU_PROGRAM_MAP(ngen386i_mem) |
| 900 | 1058 | MACHINE_CONFIG_END |
| 901 | 1059 | |