trunk/src/mess/drivers/ngen.c
| r242922 | r242923 | |
| 83 | 83 | m_dmac(*this,"dmac"), |
| 84 | 84 | m_pic(*this,"pic"), |
| 85 | 85 | m_pit(*this,"pit"), |
| 86 | m_disk_rom(*this,"disk"), |
| 86 | 87 | m_vram(*this,"vram"), |
| 87 | 88 | m_fontram(*this,"fontram"), |
| 88 | 89 | m_fdc(*this,"fdc"), |
| r242922 | r242923 | |
| 112 | 113 | DECLARE_READ8_MEMBER( dma_0_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; } |
| 113 | 114 | DECLARE_READ8_MEMBER( dma_1_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; } |
| 114 | 115 | DECLARE_READ8_MEMBER( dma_2_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; } |
| 115 | | DECLARE_READ8_MEMBER( dma_3_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; } |
| 116 | | DECLARE_WRITE8_MEMBER( dma_0_dack_w ){ popmessage("IOW: data %02x",data); } |
| 116 | DECLARE_READ8_MEMBER( dma_3_dack_r ); |
| 117 | DECLARE_WRITE8_MEMBER( dma_0_dack_w ){ popmessage("IOW0: data %02x",data); } |
| 117 | 118 | DECLARE_WRITE8_MEMBER( dma_1_dack_w ){ } |
| 118 | 119 | DECLARE_WRITE8_MEMBER( dma_2_dack_w ){ } |
| 119 | | DECLARE_WRITE8_MEMBER( dma_3_dack_w ){ } |
| 120 | DECLARE_WRITE8_MEMBER( dma_3_dack_w ){ popmessage("IOW3: data %02x",data); } |
| 120 | 121 | DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); |
| 121 | 122 | DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); |
| 122 | 123 | DECLARE_WRITE8_MEMBER(fdc_control_w); |
| 123 | 124 | DECLARE_READ8_MEMBER(irq_cb); |
| 125 | DECLARE_WRITE8_MEMBER(hdc_control_w); |
| 126 | DECLARE_WRITE8_MEMBER(disk_addr_ext); |
| 124 | 127 | |
| 125 | 128 | protected: |
| 126 | 129 | virtual void machine_reset(); |
| r242922 | r242923 | |
| 133 | 136 | required_device<am9517a_device> m_dmac; |
| 134 | 137 | required_device<pic8259_device> m_pic; |
| 135 | 138 | required_device<pit8254_device> m_pit; |
| 139 | optional_memory_region m_disk_rom; |
| 136 | 140 | optional_shared_ptr<UINT16> m_vram; |
| 137 | 141 | optional_shared_ptr<UINT16> m_fontram; |
| 138 | 142 | optional_device<wd2797_t> m_fdc; |
| r242922 | r242923 | |
| 149 | 153 | INT8 m_dma_channel; |
| 150 | 154 | UINT16 m_dma_high_byte; |
| 151 | 155 | UINT16 m_control; |
| 156 | UINT16 m_disk_rom_ptr; |
| 157 | UINT8 m_hdc_control; |
| 158 | UINT8 m_disk_page; |
| 152 | 159 | }; |
| 153 | 160 | |
| 154 | 161 | class ngen386_state : public driver_device |
| r242922 | r242923 | |
| 249 | 256 | case 0x0f: |
| 250 | 257 | if(mem_mask & 0x00ff) |
| 251 | 258 | m_dmac->write(space,offset,data & 0xff); |
| 252 | | //logerror("(PC=%06x) DMA write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 259 | logerror("(PC=%06x) DMA write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 253 | 260 | break; |
| 254 | 261 | case 0x80: // DMA page offset? |
| 255 | 262 | case 0x81: |
| r242922 | r242923 | |
| 388 | 395 | } |
| 389 | 396 | |
| 390 | 397 | // returns X-bus module ID (what is the low byte for?) |
| 391 | | // For now, we'll hard code a floppy disk module (or try to) |
| 392 | 398 | READ16_MEMBER(ngen_state::port00_r) |
| 393 | 399 | { |
| 394 | 400 | if(m_port00 > 0) |
| 395 | 401 | m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); |
| 396 | 402 | if(m_port00 == 0) |
| 397 | | return 0x0040; // module ID of 0x40 = dual floppy disk module (need hardware manual to find other module IDs) |
| 403 | return 0x1070; // module ID of 0x1070, according to the floppy/hard disk tech manual |
| 398 | 404 | else |
| 399 | 405 | return 0x0080; // invalid device? |
| 400 | 406 | } |
| r242922 | r242923 | |
| 409 | 415 | m_dmac->dreq3_w(state); |
| 410 | 416 | } |
| 411 | 417 | |
| 418 | // Floppy disk control register |
| 419 | // Bit 0 - enable drive and LED |
| 420 | // Bit 2 - floppy motor |
| 421 | // Bit 5 - side select |
| 422 | // Bit 6 - 1 = 2Mhz for seek, 0 = 1MHz for read/write |
| 423 | // Bit 7 - FDC reset |
| 412 | 424 | WRITE8_MEMBER(ngen_state::fdc_control_w) |
| 413 | 425 | { |
| 414 | 426 | m_fdc->set_floppy(m_fd0->get_device()); |
| 415 | | m_fd0->get_device()->mon_w((~data) & 0x80); |
| 416 | | m_fdc->dden_w(~data & 0x04); |
| 427 | m_fd0->get_device()->mon_w((~data) & 0x04); |
| 428 | m_fd0->get_device()->ss_w(~data & 0x20); |
| 429 | m_fdc->soft_reset(); |
| 417 | 430 | } |
| 418 | 431 | |
| 432 | // Hard disk control register |
| 433 | // bit 0 - Drive select 0 - selects module hard disk |
| 434 | // bit 1 - Drive select 1 - selects expansion module hard disk (if available) |
| 435 | // bit 2 - enable DMA transfer of module ROM contents to X-Bus master memory |
| 436 | // bits 3-5 - select head / expansion module head |
| 437 | // bit 6 - write enable, must be set to write to a hard disk |
| 438 | // bit 7 - HDC reset |
| 439 | WRITE8_MEMBER(ngen_state::hdc_control_w) |
| 440 | { |
| 441 | m_hdc_control = data; |
| 442 | if(m_hdc_control & 0x04) |
| 443 | { |
| 444 | m_disk_rom_ptr = 0; |
| 445 | popmessage("HDD: DMA ROM transfer start\n"); |
| 446 | m_dmac->dreq3_w(1); |
| 447 | //m_dmac->dreq3_w(0); |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | // page of system RAM to access |
| 452 | // bit 7 = disables read/write signals to the WD1010 |
| 453 | WRITE8_MEMBER(ngen_state::disk_addr_ext) |
| 454 | { |
| 455 | m_disk_page = data & 0x7f; |
| 456 | } |
| 457 | |
| 419 | 458 | WRITE_LINE_MEMBER( ngen_state::dma_hrq_changed ) |
| 420 | 459 | { |
| 421 | 460 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| r242922 | r242923 | |
| 430 | 469 | else |
| 431 | 470 | m_control &= ~0x02; |
| 432 | 471 | } |
| 472 | if(m_dma_channel == 3) |
| 473 | { |
| 474 | if(state) |
| 475 | { |
| 476 | if(m_hdc_control & 0x04) // ROM transfer? |
| 477 | m_hdc_control &= ~0x04; // switch it off when done |
| 478 | } |
| 479 | } |
| 433 | 480 | } |
| 434 | 481 | |
| 435 | 482 | void ngen_state::set_dma_channel(int channel, int state) |
| r242922 | r242923 | |
| 445 | 492 | WRITE_LINE_MEMBER( ngen_state::dack2_w ) { set_dma_channel(2, state); } |
| 446 | 493 | WRITE_LINE_MEMBER( ngen_state::dack3_w ) { set_dma_channel(3, state); } |
| 447 | 494 | |
| 495 | READ8_MEMBER(ngen_state::dma_3_dack_r) |
| 496 | { |
| 497 | UINT16 ret = 0xffff; |
| 498 | |
| 499 | if((m_hdc_control & 0x04) && m_disk_rom) |
| 500 | { |
| 501 | ret = m_disk_rom->base()[m_disk_rom_ptr++] << 8; |
| 502 | printf("DMA3 DACK: returning %02x\n",ret); |
| 503 | if(m_disk_rom_ptr < 0x1000) |
| 504 | { |
| 505 | m_dmac->dreq3_w(1); |
| 506 | //m_dmac->dreq3_w(0); |
| 507 | } |
| 508 | } |
| 509 | m_dma_high_byte = ret & 0xff00; |
| 510 | return ret; |
| 511 | } |
| 512 | |
| 448 | 513 | READ8_MEMBER(ngen_state::dma_read_word) |
| 449 | 514 | { |
| 450 | 515 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| r242922 | r242923 | |
| 513 | 578 | |
| 514 | 579 | static ADDRESS_MAP_START( ngen_io, AS_IO, 16, ngen_state ) |
| 515 | 580 | AM_RANGE(0x0000, 0x0001) AM_READWRITE(port00_r,port00_w) |
| 581 | |
| 582 | // TODO: allow for expansion modules to be allocated where asked to |
| 583 | // Floppy/Hard disk module |
| 516 | 584 | AM_RANGE(0x0100, 0x0107) AM_DEVREADWRITE8("fdc",wd2797_t,read,write,0x00ff) // a guess for now |
| 517 | 585 | AM_RANGE(0x0108, 0x0109) AM_WRITE8(fdc_control_w,0x00ff) |
| 586 | AM_RANGE(0x010a, 0x010b) AM_WRITE8(hdc_control_w,0x00ff) |
| 587 | AM_RANGE(0x010e, 0x010f) AM_WRITE8(disk_addr_ext,0x00ff) // X-Bus extended address register |
| 518 | 588 | AM_RANGE(0x0110, 0x0117) AM_DEVREADWRITE8("fdc_timer",pit8253_device,read,write,0x00ff) |
| 589 | // 0x0120-0x012f - WD1010 Winchester disk controller (unemulated) |
| 590 | AM_RANGE(0x0130, 0x0137) AM_DEVREADWRITE8("hdc_timer",pit8253_device,read,write,0x00ff) |
| 591 | |
| 519 | 592 | ADDRESS_MAP_END |
| 520 | 593 | |
| 521 | 594 | static ADDRESS_MAP_START( ngen386_mem, AS_PROGRAM, 32, ngen_state ) |
| r242922 | r242923 | |
| 620 | 693 | |
| 621 | 694 | // keyboard UART (patent says i8251 is used for keyboard communications, it is located on the video board) |
| 622 | 695 | MCFG_DEVICE_ADD("videouart", I8251, 0) // main clock unknown, Rx/Tx clocks are 19.53kHz |
| 623 | | MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 696 | // MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 624 | 697 | MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", rs232_port_device, write_txd)) |
| 625 | 698 | MCFG_RS232_PORT_ADD("keyboard", keyboard, "ngen") |
| 626 | 699 | MCFG_RS232_RXD_HANDLER(DEVWRITELINE("videouart", i8251_device, write_rxd)) |
| r242922 | r242923 | |
| 635 | 708 | MCFG_WD_FDC_FORCE_READY |
| 636 | 709 | MCFG_DEVICE_ADD("fdc_timer", PIT8253, 0) |
| 637 | 710 | MCFG_PIT8253_CLK0(XTAL_20MHz / 20) |
| 638 | | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 711 | MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 639 | 712 | MCFG_PIT8253_CLK1(XTAL_20MHz / 20) |
| 640 | | MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 713 | MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 641 | 714 | MCFG_PIT8253_CLK2(XTAL_20MHz / 20) |
| 642 | | MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w)) |
| 715 | MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("pic",pic8259_device,ir7_w)) |
| 643 | 716 | // TODO: WD1010 HDC (not implemented) |
| 644 | 717 | MCFG_DEVICE_ADD("hdc_timer", PIT8253, 0) |
| 645 | 718 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ngen_floppies, "525qd", floppy_image_device::default_floppy_formats) |