trunk/src/mess/drivers/apc.c
| r18994 | r18995 | |
| 5 | 5 | preliminary driver by Angelo Salese |
| 6 | 6 | |
| 7 | 7 | TODO: |
| 8 | | - Bogus DMA check, patched out for now |
| 9 | 8 | - video emulation |
| 10 | | - Floppy device and IMD support |
| 9 | - Floppy device |
| 11 | 10 | - keyboard |
| 12 | 11 | - Understand interrupt sources |
| 13 | 12 | - NMI seems valid, dumps a x86 stack to vram? |
| r18994 | r18995 | |
| 47 | 46 | 0x61 - 0x67 (Mirror of pit8253?) |
| 48 | 47 | 0x68 - 0x6f parallel port |
| 49 | 48 | |
| 49 | ---------------------------------------------------------------------------- |
| 50 | 0xfe3c2: checks if the floppy has a valid string for booting (either "CP/M-86" |
| 51 | or "MS-DOS"), if not, branches with the successive jne. |
| 52 | |
| 50 | 53 | ***************************************************************************/ |
| 51 | 54 | |
| 52 | 55 | |
| r18994 | r18995 | |
| 54 | 57 | #include "cpu/i86/i86.h" |
| 55 | 58 | #include "machine/pic8259.h" |
| 56 | 59 | #include "machine/pit8253.h" |
| 57 | | #include "machine/8237dma.h" |
| 60 | #include "machine/am9517a.h" |
| 58 | 61 | #include "machine/upd765.h" |
| 59 | 62 | #include "video/upd7220.h" |
| 60 | 63 | #include "imagedev/flopdrv.h" |
| r18994 | r18995 | |
| 74 | 77 | m_i8259_m(*this, "pic8259_master"), |
| 75 | 78 | m_i8259_s(*this, "pic8259_slave"), |
| 76 | 79 | m_fdc(*this, "upd765"), |
| 77 | | m_dma(*this, "8237dma"), |
| 80 | m_dmac(*this, "i8237"), |
| 78 | 81 | m_video_ram_1(*this, "video_ram_1"), |
| 79 | 82 | m_video_ram_2(*this, "video_ram_2") |
| 80 | 83 | { } |
| r18994 | r18995 | |
| 86 | 89 | required_device<pic8259_device> m_i8259_m; |
| 87 | 90 | required_device<pic8259_device> m_i8259_s; |
| 88 | 91 | required_device<upd765a_device> m_fdc; |
| 89 | | required_device<i8237_device> m_dma; |
| 92 | required_device<am9517a_device> m_dmac; |
| 90 | 93 | UINT8 *m_char_rom; |
| 91 | 94 | |
| 92 | 95 | required_shared_ptr<UINT8> m_video_ram_1; |
| r18994 | r18995 | |
| 129 | 132 | DECLARE_DRIVER_INIT(apc); |
| 130 | 133 | DECLARE_PALETTE_INIT(apc); |
| 131 | 134 | |
| 132 | | int m_dma_channel; |
| 133 | | UINT8 m_dma_offset[2][4]; |
| 134 | | UINT8 m_at_pages[0x10]; |
| 135 | int m_dack; |
| 136 | UINT8 m_dma_offset[4]; |
| 135 | 137 | |
| 136 | 138 | protected: |
| 137 | 139 | // driver_device overrides |
| r18994 | r18995 | |
| 339 | 341 | |
| 340 | 342 | WRITE8_MEMBER(apc_state::apc_dma_segments_w) |
| 341 | 343 | { |
| 342 | | m_dma_offset[0][offset & 3] = data & 0x0f; |
| 344 | m_dma_offset[offset & 3] = data & 0x0f; |
| 343 | 345 | } |
| 344 | 346 | |
| 345 | 347 | /* |
| r18994 | r18995 | |
| 374 | 376 | |
| 375 | 377 | READ8_MEMBER(apc_state::apc_dma_r) |
| 376 | 378 | { |
| 377 | | return i8237_r(m_dma, space, BITSWAP8(offset,7,6,5,4,2,1,0,3)); |
| 379 | return machine().device<am9517a_device>("i8237")->read(space, BITSWAP8(offset,7,6,5,4,2,1,0,3), 0xff); |
| 378 | 380 | } |
| 379 | 381 | |
| 380 | 382 | WRITE8_MEMBER(apc_state::apc_dma_w) |
| 381 | 383 | { |
| 382 | | i8237_w(m_dma, space, BITSWAP8(offset,7,6,5,4,2,1,0,3), data); |
| 384 | machine().device<am9517a_device>("i8237")->write(space, BITSWAP8(offset,7,6,5,4,2,1,0,3), data, 0xff); |
| 383 | 385 | } |
| 384 | 386 | |
| 385 | 387 | |
| 386 | 388 | static ADDRESS_MAP_START( apc_map, AS_PROGRAM, 16, apc_state ) |
| 387 | | AM_RANGE(0x00000, 0x1ffff) AM_RAM |
| 389 | AM_RANGE(0x00000, 0x9ffff) AM_RAM |
| 388 | 390 | // AM_RANGE(0xa0000, 0xaffff) space for an external ROM |
| 389 | 391 | AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("ipl", 0) |
| 390 | 392 | ADDRESS_MAP_END |
| r18994 | r18995 | |
| 466 | 468 | |
| 467 | 469 | void apc_state::fdc_drq(bool state) |
| 468 | 470 | { |
| 469 | | printf("%02x DRQ\n",state); |
| 470 | | i8237_dreq0_w(m_dma, state); |
| 471 | // printf("%02x DRQ\n",state); |
| 472 | // i8237_dreq0_w(m_dma, state); |
| 473 | m_dmac->dreq1_w(state); |
| 474 | |
| 471 | 475 | } |
| 472 | 476 | |
| 473 | 477 | void apc_state::fdc_irq(bool state) |
| 474 | 478 | { |
| 475 | | printf("IRQ %d\n",state); |
| 479 | // printf("IRQ %d\n",state); |
| 476 | 480 | pic8259_ir3_w(machine().device("pic8259_slave"), state); |
| 477 | 481 | } |
| 478 | 482 | |
| r18994 | r18995 | |
| 620 | 624 | |
| 621 | 625 | WRITE_LINE_MEMBER(apc_state::apc_dma_hrq_changed) |
| 622 | 626 | { |
| 623 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 627 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 624 | 628 | |
| 625 | | printf("%02x HLDA\n",state); |
| 629 | m_dmac->hack_w(state); |
| 626 | 630 | |
| 627 | | /* Assert HLDA */ |
| 628 | | i8237_hlda_w( machine().device("dma8237"), state ); |
| 631 | // printf("%02x HLDA\n",state); |
| 629 | 632 | } |
| 630 | 633 | |
| 631 | 634 | WRITE_LINE_MEMBER( apc_state::apc_tc_w ) |
| 632 | 635 | { |
| 633 | 636 | /* floppy terminal count */ |
| 634 | | // m_fdc->tc_w(!state); |
| 637 | m_fdc->tc_w(state); |
| 638 | |
| 635 | 639 | printf("TC %02x\n",state); |
| 636 | 640 | } |
| 637 | 641 | |
| 638 | 642 | READ8_MEMBER(apc_state::apc_dma_read_byte) |
| 639 | 643 | { |
| 640 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 641 | | & 0xFF0000; |
| 644 | address_space &program = m_maincpu->space(AS_PROGRAM); |
| 645 | offs_t addr = (m_dma_offset[m_dack] << 16) | offset; |
| 642 | 646 | |
| 643 | | return space.read_byte(page_offset + offset); |
| 647 | printf("%08x\n",addr); |
| 648 | |
| 649 | return program.read_byte(addr); |
| 644 | 650 | } |
| 645 | 651 | |
| 646 | 652 | |
| 647 | 653 | WRITE8_MEMBER(apc_state::apc_dma_write_byte) |
| 648 | 654 | { |
| 649 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 650 | | & 0xFF0000; |
| 655 | address_space &program = m_maincpu->space(AS_PROGRAM); |
| 656 | offs_t addr = (m_dma_offset[m_dack] << 16) | offset; |
| 651 | 657 | |
| 652 | | space.write_byte(page_offset + offset, data); |
| 658 | // printf("%08x %02x\n",addr,data); |
| 659 | |
| 660 | program.write_byte(addr, data); |
| 653 | 661 | } |
| 654 | 662 | |
| 655 | 663 | static void set_dma_channel(running_machine &machine, int channel, int state) |
| 656 | 664 | { |
| 657 | 665 | apc_state *drvstate = machine.driver_data<apc_state>(); |
| 658 | | if (!state) drvstate->m_dma_channel = channel; |
| 666 | if (!state) drvstate->m_dack = channel; |
| 659 | 667 | } |
| 660 | 668 | |
| 661 | | WRITE_LINE_MEMBER(apc_state::apc_dack0_w){ printf("%02x 0\n",state); set_dma_channel(machine(), 0, state); } |
| 662 | | WRITE_LINE_MEMBER(apc_state::apc_dack1_w){ printf("%02x 1\n",state); set_dma_channel(machine(), 1, state); } |
| 663 | | WRITE_LINE_MEMBER(apc_state::apc_dack2_w){ printf("%02x 2\n",state); set_dma_channel(machine(), 2, state); } |
| 664 | | WRITE_LINE_MEMBER(apc_state::apc_dack3_w){ printf("%02x 3\n",state); set_dma_channel(machine(), 3, state); } |
| 669 | WRITE_LINE_MEMBER(apc_state::apc_dack0_w){ /*printf("%02x 0\n",state);*/ set_dma_channel(machine(), 0, state); } |
| 670 | WRITE_LINE_MEMBER(apc_state::apc_dack1_w){ /*printf("%02x 1\n",state);*/ set_dma_channel(machine(), 1, state); } |
| 671 | WRITE_LINE_MEMBER(apc_state::apc_dack2_w){ /*printf("%02x 2\n",state);*/ set_dma_channel(machine(), 2, state); } |
| 672 | WRITE_LINE_MEMBER(apc_state::apc_dack3_w){ /*printf("%02x 3\n",state);*/ set_dma_channel(machine(), 3, state); } |
| 665 | 673 | |
| 666 | 674 | READ8_MEMBER(apc_state::test_r) |
| 667 | 675 | { |
| 668 | | printf("2dd DACK R\n"); |
| 676 | // printf("2dd DACK R\n"); |
| 669 | 677 | |
| 670 | | return 0xff; |
| 678 | return m_fdc->dma_r(); |
| 671 | 679 | } |
| 672 | 680 | |
| 673 | 681 | WRITE8_MEMBER(apc_state::test_w) |
| r18994 | r18995 | |
| 675 | 683 | printf("2dd DACK W\n"); |
| 676 | 684 | } |
| 677 | 685 | |
| 678 | | static I8237_INTERFACE( dma8237_config ) |
| 686 | static I8237_INTERFACE( dmac_intf ) |
| 679 | 687 | { |
| 680 | 688 | DEVCB_DRIVER_LINE_MEMBER(apc_state, apc_dma_hrq_changed), |
| 681 | 689 | DEVCB_DRIVER_LINE_MEMBER(apc_state, apc_tc_w), |
| r18994 | r18995 | |
| 719 | 727 | MCFG_PIT8253_ADD( "pit8253", pit8253_config ) |
| 720 | 728 | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 721 | 729 | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 722 | | MCFG_I8237_ADD("8237dma", MAIN_CLOCK, dma8237_config) |
| 730 | MCFG_I8237_ADD("i8237", MAIN_CLOCK, dmac_intf) |
| 723 | 731 | |
| 724 | 732 | MCFG_UPD765A_ADD("upd765", true, true) |
| 725 | 733 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", apc_floppies, "8", 0, apc_floppy_formats) |