trunk/src/mess/machine/swtpc09.c
| r29208 | r29209 | |
| 24 | 24 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) |
| 25 | 25 | |
| 26 | 26 | |
| 27 | | /* channel_data structure holds info about each 6844 DMA channel */ |
| 28 | | typedef struct m6844_channel_data |
| 29 | | { |
| 30 | | int active; |
| 31 | | int address; |
| 32 | | int counter; |
| 33 | | UINT8 control; |
| 34 | | int start_address; |
| 35 | | int start_counter; |
| 36 | | } m6844_channel_data; |
| 37 | | |
| 38 | | /* 6844 description */ |
| 39 | | static m6844_channel_data m6844_channel[4]; |
| 40 | | static UINT8 m6844_priority; |
| 41 | | static UINT8 m6844_interrupt; |
| 42 | | static UINT8 m6844_chain; |
| 43 | | |
| 44 | 27 | /******* MC6840 PTM on MPID Board *******/ |
| 45 | 28 | /* 6840 PTM interface */ |
| 46 | 29 | const ptm6840_interface swtpc09_6840_intf = |
| r29208 | r29209 | |
| 206 | 189 | |
| 207 | 190 | offset = (m_fdc_dma_address_reg & 0x0f)<<16; |
| 208 | 191 | |
| 209 | | if (m6844_channel[0].active == 1) //active dma transfer |
| 192 | if (m_m6844_channel[0].active == 1) //active dma transfer |
| 210 | 193 | { |
| 211 | | if (!(m6844_channel[0].control & 0x01)) // dma write to memory |
| 194 | if (!(m_m6844_channel[0].control & 0x01)) // dma write to memory |
| 212 | 195 | { |
| 213 | 196 | UINT8 data = m_fdc->data_r(space, 0); |
| 214 | 197 | |
| 215 | | LOG(("swtpc09_dma_write_mem %05X %02X\n", m6844_channel[0].address + offset, data)); |
| 216 | | RAM[m6844_channel[0].address + offset] = data; |
| 198 | LOG(("swtpc09_dma_write_mem %05X %02X\n", m_m6844_channel[0].address + offset, data)); |
| 199 | RAM[m_m6844_channel[0].address + offset] = data; |
| 217 | 200 | } |
| 218 | 201 | else |
| 219 | 202 | { |
| 220 | | UINT8 data = RAM[m6844_channel[0].address + offset]; |
| 203 | UINT8 data = RAM[m_m6844_channel[0].address + offset]; |
| 221 | 204 | |
| 222 | 205 | m_fdc->data_w(space, 0, data); |
| 223 | | //LOG(("swtpc09_dma_read_mem %04X %02X\n", m6844_channel[0].address, data)); |
| 206 | //LOG(("swtpc09_dma_read_mem %04X %02X\n", m_m6844_channel[0].address, data)); |
| 224 | 207 | } |
| 225 | 208 | |
| 226 | | m6844_channel[0].address++; |
| 227 | | m6844_channel[0].counter--; |
| 209 | m_m6844_channel[0].address++; |
| 210 | m_m6844_channel[0].counter--; |
| 228 | 211 | |
| 229 | | if (m6844_channel[0].counter == 0) // dma transfer has finished |
| 212 | if (m_m6844_channel[0].counter == 0) // dma transfer has finished |
| 230 | 213 | { |
| 231 | | m6844_channel[0].control |= 0x80; // set dend flag |
| 232 | | if (m6844_interrupt & 0x01) // interrupt for channel 0 is enabled? |
| 214 | m_m6844_channel[0].control |= 0x80; // set dend flag |
| 215 | if (m_m6844_interrupt & 0x01) // interrupt for channel 0 is enabled? |
| 233 | 216 | { |
| 234 | | m6844_interrupt |= 0x80; // set bit 7 to indicate active interrupt |
| 217 | m_m6844_interrupt |= 0x80; // set bit 7 to indicate active interrupt |
| 235 | 218 | swtpc09_irq_handler(DMAC_IRQ, ASSERT_LINE); |
| 236 | 219 | } |
| 237 | 220 | } |
| r29208 | r29209 | |
| 630 | 613 | { |
| 631 | 614 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 conroller this is the map |
| 632 | 615 | { |
| 633 | | mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 616 | mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 634 | 617 | mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 635 | 618 | mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); |
| 636 | 619 | mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); |
| r29208 | r29209 | |
| 640 | 623 | } |
| 641 | 624 | else if (m_system_type == FLEX_DC4_PIAIDE) // 2k ram for piaide on s09 board |
| 642 | 625 | { |
| 643 | | //mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 644 | | //mem.install_legacy_readwrite_handler(*fdc, logical_address+0x020, logical_address+0x023, 0, 0, FUNC(wd17xx_r), FUNC(wd17xx_w)); |
| 626 | //mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 627 | //mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 645 | 628 | //mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); |
| 646 | 629 | //mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); |
| 647 | 630 | mem.install_ram(logical_address+0x000, logical_address+0x7ff, &RAM[0xf000]); |
| r29208 | r29209 | |
| 649 | 632 | mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); |
| 650 | 633 | } |
| 651 | 634 | else // assume DMF3 controller |
| 652 | | { |
| 653 | | mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); |
| 635 | { |
| 636 | mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); |
| 654 | 637 | mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); |
| 655 | 638 | mem.install_readwrite_handler(logical_address+0x024, logical_address+0x024, read8_delegate(FUNC(swtpc09_state::dmf3_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_control_reg_w),this)); |
| 656 | 639 | mem.install_readwrite_handler(logical_address+0x025, logical_address+0x025, read8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_w),this)); |
| r29208 | r29209 | |
| 688 | 671 | |
| 689 | 672 | /* MC6844 DMA controller I/O */ |
| 690 | 673 | |
| 691 | | READ8_HANDLER( m6844_r ) |
| 674 | READ8_MEMBER( swtpc09_state::m6844_r ) |
| 692 | 675 | { |
| 693 | 676 | UINT8 result = 0; |
| 694 | | swtpc09_state *state = space.machine().driver_data<swtpc09_state>(); |
| 695 | 677 | |
| 696 | 678 | |
| 697 | 679 | /* switch off the offset we were given */ |
| r29208 | r29209 | |
| 702 | 684 | case 0x04: |
| 703 | 685 | case 0x08: |
| 704 | 686 | case 0x0c: |
| 705 | | result = m6844_channel[offset / 4].address >> 8; |
| 687 | result = m_m6844_channel[offset / 4].address >> 8; |
| 706 | 688 | break; |
| 707 | 689 | |
| 708 | 690 | /* lower byte of address */ |
| r29208 | r29209 | |
| 710 | 692 | case 0x05: |
| 711 | 693 | case 0x09: |
| 712 | 694 | case 0x0d: |
| 713 | | result = m6844_channel[offset / 4].address & 0xff; |
| 695 | result = m_m6844_channel[offset / 4].address & 0xff; |
| 714 | 696 | break; |
| 715 | 697 | |
| 716 | 698 | /* upper byte of counter */ |
| r29208 | r29209 | |
| 718 | 700 | case 0x06: |
| 719 | 701 | case 0x0a: |
| 720 | 702 | case 0x0e: |
| 721 | | result = m6844_channel[offset / 4].counter >> 8; |
| 703 | result = m_m6844_channel[offset / 4].counter >> 8; |
| 722 | 704 | break; |
| 723 | 705 | |
| 724 | 706 | /* lower byte of counter */ |
| r29208 | r29209 | |
| 726 | 708 | case 0x07: |
| 727 | 709 | case 0x0b: |
| 728 | 710 | case 0x0f: |
| 729 | | result = m6844_channel[offset / 4].counter & 0xff; |
| 711 | result = m_m6844_channel[offset / 4].counter & 0xff; |
| 730 | 712 | break; |
| 731 | 713 | |
| 732 | 714 | /* channel control */ |
| r29208 | r29209 | |
| 734 | 716 | case 0x11: |
| 735 | 717 | case 0x12: |
| 736 | 718 | case 0x13: |
| 737 | | result = m6844_channel[offset - 0x10].control; |
| 719 | result = m_m6844_channel[offset - 0x10].control; |
| 738 | 720 | |
| 739 | 721 | /* a read here clears the DMA end flag */ |
| 740 | | m6844_channel[offset - 0x10].control &= ~0x80; |
| 741 | | if (m6844_interrupt && 0x80) // if interrupt is active, then clear |
| 722 | m_m6844_channel[offset - 0x10].control &= ~0x80; |
| 723 | if (m_m6844_interrupt && 0x80) // if interrupt is active, then clear |
| 742 | 724 | { |
| 743 | | state->swtpc09_irq_handler(0x01, CLEAR_LINE); |
| 744 | | m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 |
| 725 | swtpc09_irq_handler(0x01, CLEAR_LINE); |
| 726 | m_m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 |
| 745 | 727 | LOG(("swtpc09_6844_r interrupt cleared \n")); |
| 746 | 728 | } |
| 747 | 729 | break; |
| 748 | 730 | |
| 749 | 731 | /* priority control */ |
| 750 | 732 | case 0x14: |
| 751 | | result = m6844_priority; |
| 733 | result = m_m6844_priority; |
| 752 | 734 | break; |
| 753 | 735 | |
| 754 | 736 | /* interrupt control */ |
| 755 | 737 | case 0x15: |
| 756 | | result = m6844_interrupt; |
| 738 | result = m_m6844_interrupt; |
| 757 | 739 | break; |
| 758 | 740 | |
| 759 | 741 | /* chaining control */ |
| 760 | 742 | case 0x16: |
| 761 | | result = m6844_chain; |
| 743 | result = m_m6844_chain; |
| 762 | 744 | break; |
| 763 | 745 | |
| 764 | 746 | /* 0x17-0x1f not used */ |
| r29208 | r29209 | |
| 766 | 748 | } |
| 767 | 749 | //LOG(("swtpc09_6844_r %02X %02X\n", offset, result & 0xff)); |
| 768 | 750 | |
| 769 | | if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 751 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 770 | 752 | { |
| 771 | 753 | return ~result & 0xff; |
| 772 | 754 | } |
| r29208 | r29209 | |
| 777 | 759 | } |
| 778 | 760 | |
| 779 | 761 | |
| 780 | | WRITE8_HANDLER( m6844_w ) |
| 762 | WRITE8_MEMBER( swtpc09_state::m6844_w ) |
| 781 | 763 | { |
| 782 | 764 | int i; |
| 783 | | swtpc09_state *state = space.machine().driver_data<swtpc09_state>(); |
| 784 | 765 | |
| 785 | | if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 766 | if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 |
| 786 | 767 | data = ~data & 0xff; |
| 787 | 768 | |
| 788 | 769 | LOG(("swtpc09_6844_w %02X %02X\n", offset, data)); |
| r29208 | r29209 | |
| 794 | 775 | case 0x04: |
| 795 | 776 | case 0x08: |
| 796 | 777 | case 0x0c: |
| 797 | | m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff) | (data << 8); |
| 778 | m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff) | (data << 8); |
| 798 | 779 | break; |
| 799 | 780 | |
| 800 | 781 | /* lower byte of address */ |
| r29208 | r29209 | |
| 802 | 783 | case 0x05: |
| 803 | 784 | case 0x09: |
| 804 | 785 | case 0x0d: |
| 805 | | m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff00) | (data & 0xff); |
| 786 | m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff00) | (data & 0xff); |
| 806 | 787 | break; |
| 807 | 788 | |
| 808 | 789 | /* upper byte of counter */ |
| r29208 | r29209 | |
| 810 | 791 | case 0x06: |
| 811 | 792 | case 0x0a: |
| 812 | 793 | case 0x0e: |
| 813 | | m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff) | (data << 8); |
| 794 | m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff) | (data << 8); |
| 814 | 795 | break; |
| 815 | 796 | |
| 816 | 797 | /* lower byte of counter */ |
| r29208 | r29209 | |
| 818 | 799 | case 0x07: |
| 819 | 800 | case 0x0b: |
| 820 | 801 | case 0x0f: |
| 821 | | m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff); |
| 802 | m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff); |
| 822 | 803 | break; |
| 823 | 804 | |
| 824 | 805 | /* channel control */ |
| r29208 | r29209 | |
| 826 | 807 | case 0x11: |
| 827 | 808 | case 0x12: |
| 828 | 809 | case 0x13: |
| 829 | | m6844_channel[offset - 0x10].control = (m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f); |
| 810 | m_m6844_channel[offset - 0x10].control = (m_m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f); |
| 830 | 811 | break; |
| 831 | 812 | |
| 832 | 813 | /* priority control */ |
| 833 | 814 | case 0x14: |
| 834 | | m6844_priority = data; |
| 815 | m_m6844_priority = data; |
| 835 | 816 | |
| 836 | 817 | /* update each channel */ |
| 837 | 818 | for (i = 0; i < 4; i++) |
| 838 | 819 | { |
| 839 | 820 | /* if we're going active... */ |
| 840 | | if (!m6844_channel[i].active && (data & (1 << i))) |
| 821 | if (!m_m6844_channel[i].active && (data & (1 << i))) |
| 841 | 822 | { |
| 842 | 823 | /* mark us active */ |
| 843 | | m6844_channel[i].active = 1; |
| 824 | m_m6844_channel[i].active = 1; |
| 844 | 825 | LOG(("swtpc09_dma_channel active %02X\n", i)); |
| 845 | 826 | |
| 846 | 827 | /* set the DMA busy bit and clear the DMA end bit */ |
| 847 | | m6844_channel[i].control |= 0x40; |
| 848 | | m6844_channel[i].control &= ~0x80; |
| 828 | m_m6844_channel[i].control |= 0x40; |
| 829 | m_m6844_channel[i].control &= ~0x80; |
| 849 | 830 | |
| 850 | 831 | /* set the starting address, counter, and time */ |
| 851 | | m6844_channel[i].start_address = m6844_channel[i].address; |
| 852 | | m6844_channel[i].start_counter = m6844_channel[i].counter; |
| 832 | m_m6844_channel[i].start_address = m_m6844_channel[i].address; |
| 833 | m_m6844_channel[i].start_counter = m_m6844_channel[i].counter; |
| 853 | 834 | |
| 854 | 835 | |
| 855 | 836 | /* generate and play the sample */ |
| r29208 | r29209 | |
| 857 | 838 | } |
| 858 | 839 | |
| 859 | 840 | /* if we're going inactive... */ |
| 860 | | else if (m6844_channel[i].active && !(data & (1 << i))) |
| 841 | else if (m_m6844_channel[i].active && !(data & (1 << i))) |
| 861 | 842 | { |
| 862 | 843 | /* mark us inactive */ |
| 863 | | m6844_channel[i].active = 0; |
| 844 | m_m6844_channel[i].active = 0; |
| 864 | 845 | } |
| 865 | 846 | } |
| 866 | 847 | break; |
| 867 | 848 | |
| 868 | 849 | /* interrupt control */ |
| 869 | 850 | case 0x15: |
| 870 | | m6844_interrupt = (m6844_interrupt & 0x80) | (data & 0x7f); |
| 871 | | LOG(("swtpc09_m6844_interrupt_w %02X\n", m6844_interrupt)); |
| 851 | m_m6844_interrupt = (m_m6844_interrupt & 0x80) | (data & 0x7f); |
| 852 | LOG(("swtpc09_m_m6844_interrupt_w %02X\n", m_m6844_interrupt)); |
| 872 | 853 | break; |
| 873 | 854 | |
| 874 | 855 | /* chaining control */ |
| 875 | 856 | case 0x16: |
| 876 | | m6844_chain = data; |
| 857 | m_m6844_chain = data; |
| 877 | 858 | break; |
| 878 | 859 | |
| 879 | 860 | /* 0x17-0x1f not used */ |
| r29208 | r29209 | |
| 895 | 876 | /* reset the 6844 */ |
| 896 | 877 | for (i = 0; i < 4; i++) |
| 897 | 878 | { |
| 898 | | m6844_channel[i].active = 0; |
| 899 | | m6844_channel[i].control = 0x00; |
| 879 | m_m6844_channel[i].active = 0; |
| 880 | m_m6844_channel[i].control = 0x00; |
| 900 | 881 | } |
| 901 | | m6844_priority = 0x00; |
| 902 | | m6844_interrupt = 0x00; |
| 903 | | m6844_chain = 0x00; |
| 882 | m_m6844_priority = 0x00; |
| 883 | m_m6844_interrupt = 0x00; |
| 884 | m_m6844_chain = 0x00; |
| 904 | 885 | |
| 905 | 886 | } |
| 906 | 887 | |
| r29208 | r29209 | |
| 917 | 898 | /* reset the 6844 */ |
| 918 | 899 | for (i = 0; i < 4; i++) |
| 919 | 900 | { |
| 920 | | m6844_channel[i].active = 0; |
| 921 | | m6844_channel[i].control = 0x00; |
| 901 | m_m6844_channel[i].active = 0; |
| 902 | m_m6844_channel[i].control = 0x00; |
| 922 | 903 | } |
| 923 | | m6844_priority = 0x00; |
| 924 | | m6844_interrupt = 0x00; |
| 925 | | m6844_chain = 0x00; |
| 904 | m_m6844_priority = 0x00; |
| 905 | m_m6844_interrupt = 0x00; |
| 906 | m_m6844_chain = 0x00; |
| 926 | 907 | |
| 927 | 908 | } |
| 928 | 909 | |
| r29208 | r29209 | |
| 939 | 920 | /* reset the 6844 */ |
| 940 | 921 | for (i = 0; i < 4; i++) |
| 941 | 922 | { |
| 942 | | m6844_channel[i].active = 0; |
| 943 | | m6844_channel[i].control = 0x00; |
| 923 | m_m6844_channel[i].active = 0; |
| 924 | m_m6844_channel[i].control = 0x00; |
| 944 | 925 | } |
| 945 | | m6844_priority = 0x00; |
| 946 | | m6844_interrupt = 0x00; |
| 947 | | m6844_chain = 0x00; |
| 926 | m_m6844_priority = 0x00; |
| 927 | m_m6844_interrupt = 0x00; |
| 928 | m_m6844_chain = 0x00; |
| 948 | 929 | |
| 949 | 930 | } |
| 950 | 931 | |
| r29208 | r29209 | |
| 963 | 944 | /* reset the 6844 */ |
| 964 | 945 | for (i = 0; i < 4; i++) |
| 965 | 946 | { |
| 966 | | m6844_channel[i].active = 0; |
| 967 | | m6844_channel[i].control = 0x00; |
| 947 | m_m6844_channel[i].active = 0; |
| 948 | m_m6844_channel[i].control = 0x00; |
| 968 | 949 | } |
| 969 | | m6844_priority = 0x00; |
| 970 | | m6844_interrupt = 0x00; |
| 971 | | m6844_chain = 0x00; |
| 950 | m_m6844_priority = 0x00; |
| 951 | m_m6844_interrupt = 0x00; |
| 952 | m_m6844_chain = 0x00; |
| 972 | 953 | |
| 973 | 954 | } |