trunk/src/mess/drivers/a2600.c
r18247 | r18248 | |
113 | 113 | void modeDPC_decrement_counter(UINT8 data_fetcher); |
114 | 114 | virtual void machine_reset(); |
115 | 115 | DECLARE_MACHINE_START(a2600); |
116 | | DECLARE_MACHINE_START(a2600p); |
117 | 116 | TIMER_CALLBACK_MEMBER(modeDPC_timer_callback); |
118 | 117 | DECLARE_WRITE8_MEMBER(switch_A_w); |
119 | 118 | DECLARE_READ8_MEMBER(switch_A_r); |
120 | 119 | DECLARE_WRITE8_MEMBER(switch_B_w); |
121 | 120 | DECLARE_WRITE_LINE_MEMBER(irq_callback); |
122 | 121 | DECLARE_READ8_MEMBER(riot_input_port_8_r); |
| 122 | |
| 123 | protected: |
| 124 | int next_bank(); |
| 125 | void modeF8_switch(UINT16 offset, UINT8 data); |
| 126 | void modeFA_switch(UINT16 offset, UINT8 data); |
| 127 | void modeF6_switch(UINT16 offset, UINT8 data); |
| 128 | void modeF4_switch(UINT16 offset, UINT8 data); |
| 129 | void mode3F_switch(UINT16 offset, UINT8 data); |
| 130 | void modeUA_switch(UINT16 offset, UINT8 data); |
| 131 | void modeE0_switch(UINT16 offset, UINT8 data); |
| 132 | void modeE7_switch(UINT16 offset, UINT8 data); |
| 133 | void modeE7_RAM_switch(UINT16 offset, UINT8 data); |
| 134 | void modeDC_switch(UINT16 offset, UINT8 data); |
| 135 | void mode3E_switch(UINT16 offset, UINT8 data); |
| 136 | void mode3E_RAM_switch(UINT16 offset, UINT8 data); |
| 137 | void modeFV_switch(UINT16 offset, UINT8 data); |
| 138 | void modeJVP_switch(UINT16 offset, UINT8 data); |
| 139 | |
| 140 | UINT8 *m_cart; |
123 | 141 | }; |
124 | 142 | |
125 | 143 | |
r18247 | r18248 | |
579 | 597 | } |
580 | 598 | |
581 | 599 | |
582 | | static int next_bank(a2600_state *state) |
| 600 | int a2600_state::next_bank() |
583 | 601 | { |
584 | | return state->m_current_bank = (state->m_current_bank + 1) % 16; |
| 602 | return m_current_bank = (m_current_bank + 1) % 16; |
585 | 603 | } |
586 | 604 | |
587 | 605 | |
588 | | static void modeF8_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 606 | void a2600_state::modeF8_switch(UINT16 offset, UINT8 data) |
589 | 607 | { |
590 | | a2600_state *state = machine.driver_data<a2600_state>(); |
591 | | state->m_bank_base[1] = CART + 0x1000 * offset; |
592 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 608 | m_bank_base[1] = m_cart + 0x1000 * offset; |
| 609 | membank("bank1")->set_base(m_bank_base[1]); |
593 | 610 | } |
594 | | static void modeFA_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 611 | |
| 612 | void a2600_state::modeFA_switch(UINT16 offset, UINT8 data) |
595 | 613 | { |
596 | | a2600_state *state = machine.driver_data<a2600_state>(); |
597 | | state->m_bank_base[1] = CART + 0x1000 * offset; |
598 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 614 | m_bank_base[1] = m_cart + 0x1000 * offset; |
| 615 | membank("bank1")->set_base(m_bank_base[1]); |
599 | 616 | } |
600 | | static void modeF6_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 617 | |
| 618 | void a2600_state::modeF6_switch(UINT16 offset, UINT8 data) |
601 | 619 | { |
602 | | a2600_state *state = machine.driver_data<a2600_state>(); |
603 | | state->m_bank_base[1] = CART + 0x1000 * offset; |
604 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 620 | m_bank_base[1] = m_cart + 0x1000 * offset; |
| 621 | membank("bank1")->set_base(m_bank_base[1]); |
605 | 622 | } |
606 | | static void modeF4_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 623 | |
| 624 | void a2600_state::modeF4_switch(UINT16 offset, UINT8 data) |
607 | 625 | { |
608 | | a2600_state *state = machine.driver_data<a2600_state>(); |
609 | | state->m_bank_base[1] = CART + 0x1000 * offset; |
610 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 626 | m_bank_base[1] = m_cart + 0x1000 * offset; |
| 627 | membank("bank1")->set_base(m_bank_base[1]); |
611 | 628 | } |
612 | | static void mode3F_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 629 | |
| 630 | void a2600_state::mode3F_switch(UINT16 offset, UINT8 data) |
613 | 631 | { |
614 | | a2600_state *state = machine.driver_data<a2600_state>(); |
615 | | state->m_bank_base[1] = CART + 0x800 * (data & (state->m_number_banks - 1)); |
616 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 632 | m_bank_base[1] = m_cart + 0x800 * (data & (m_number_banks - 1)); |
| 633 | membank("bank1")->set_base(m_bank_base[1]); |
617 | 634 | } |
618 | | static void modeUA_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 635 | |
| 636 | void a2600_state::modeUA_switch(UINT16 offset, UINT8 data) |
619 | 637 | { |
620 | | a2600_state *state = machine.driver_data<a2600_state>(); |
621 | | state->m_bank_base[1] = CART + (offset >> 6) * 0x1000; |
622 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 638 | m_bank_base[1] = m_cart + (offset >> 6) * 0x1000; |
| 639 | membank("bank1")->set_base(m_bank_base[1]); |
623 | 640 | } |
624 | | static void modeE0_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 641 | |
| 642 | void a2600_state::modeE0_switch(UINT16 offset, UINT8 data) |
625 | 643 | { |
626 | | a2600_state *state = machine.driver_data<a2600_state>(); |
627 | 644 | int bank = 1 + (offset >> 3); |
628 | 645 | char bank_name[10]; |
629 | 646 | sprintf(bank_name,"bank%d",bank); |
630 | | state->m_bank_base[bank] = CART + 0x400 * (offset & 7); |
631 | | state->membank(bank_name)->set_base(state->m_bank_base[bank]); |
| 647 | m_bank_base[bank] = m_cart + 0x400 * (offset & 7); |
| 648 | membank(bank_name)->set_base(m_bank_base[bank]); |
632 | 649 | } |
633 | | static void modeE7_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 650 | |
| 651 | void a2600_state::modeE7_switch(UINT16 offset, UINT8 data) |
634 | 652 | { |
635 | | a2600_state *state = machine.driver_data<a2600_state>(); |
636 | | state->m_bank_base[1] = CART + 0x800 * offset; |
637 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 653 | m_bank_base[1] = m_cart + 0x800 * offset; |
| 654 | membank("bank1")->set_base(m_bank_base[1]); |
638 | 655 | } |
639 | | static void modeE7_RAM_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 656 | |
| 657 | void a2600_state::modeE7_RAM_switch(UINT16 offset, UINT8 data) |
640 | 658 | { |
641 | | a2600_state *state = machine.driver_data<a2600_state>(); |
642 | | state->membank("bank9")->set_base(state->m_extra_RAM->base() + (4 + offset) * 256 ); |
| 659 | membank("bank9")->set_base(m_extra_RAM->base() + (4 + offset) * 256 ); |
643 | 660 | } |
644 | | static void modeDC_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 661 | |
| 662 | void a2600_state::modeDC_switch(UINT16 offset, UINT8 data) |
645 | 663 | { |
646 | | a2600_state *state = machine.driver_data<a2600_state>(); |
647 | | state->m_bank_base[1] = CART + 0x1000 * next_bank(state); |
648 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 664 | m_bank_base[1] = m_cart + 0x1000 * next_bank(); |
| 665 | membank("bank1")->set_base(m_bank_base[1]); |
649 | 666 | } |
650 | | static void mode3E_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 667 | |
| 668 | void a2600_state::mode3E_switch(UINT16 offset, UINT8 data) |
651 | 669 | { |
652 | | a2600_state *state = machine.driver_data<a2600_state>(); |
653 | | state->m_bank_base[1] = CART + 0x800 * (data & (state->m_number_banks - 1)); |
654 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
655 | | state->m_mode3E_ram_enabled = 0; |
| 670 | m_bank_base[1] = m_cart + 0x800 * (data & (m_number_banks - 1)); |
| 671 | membank("bank1")->set_base(m_bank_base[1]); |
| 672 | m_mode3E_ram_enabled = 0; |
656 | 673 | } |
657 | | static void mode3E_RAM_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 674 | |
| 675 | void a2600_state::mode3E_RAM_switch(UINT16 offset, UINT8 data) |
658 | 676 | { |
659 | | a2600_state *state = machine.driver_data<a2600_state>(); |
660 | | state->m_ram_base = state->m_extra_RAM->base() + 0x200 * ( data & 0x3F ); |
661 | | state->membank("bank1")->set_base(state->m_ram_base ); |
662 | | state->m_mode3E_ram_enabled = 1; |
| 677 | m_ram_base = m_extra_RAM->base() + 0x200 * ( data & 0x3F ); |
| 678 | membank("bank1")->set_base(m_ram_base); |
| 679 | m_mode3E_ram_enabled = 1; |
663 | 680 | } |
664 | | static void modeFV_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 681 | |
| 682 | void a2600_state::modeFV_switch(UINT16 offset, UINT8 data) |
665 | 683 | { |
666 | | a2600_state *state = machine.driver_data<a2600_state>(); |
667 | | //printf("ModeFV %04x\n",offset); |
668 | | if (!state->m_FVlocked && ( machine.device("maincpu")->safe_pc() & 0x1F00 ) == 0x1F00 ) |
| 684 | if (!m_FVlocked && ( machine().device("maincpu")->safe_pc() & 0x1F00 ) == 0x1F00 ) |
669 | 685 | { |
670 | | state->m_FVlocked = 1; |
671 | | state->m_current_bank = state->m_current_bank ^ 0x01; |
672 | | state->m_bank_base[1] = CART + 0x1000 * state->m_current_bank; |
673 | | state->membank("bank1")->set_base(state->m_bank_base[1]); |
| 686 | m_FVlocked = 1; |
| 687 | m_current_bank = m_current_bank ^ 0x01; |
| 688 | m_bank_base[1] = m_cart + 0x1000 * m_current_bank; |
| 689 | membank("bank1")->set_base(m_bank_base[1]); |
674 | 690 | } |
675 | 691 | } |
676 | | static void modeJVP_switch(running_machine &machine, UINT16 offset, UINT8 data) |
| 692 | |
| 693 | void a2600_state::modeJVP_switch(UINT16 offset, UINT8 data) |
677 | 694 | { |
678 | | a2600_state *state = machine.driver_data<a2600_state>(); |
679 | 695 | switch( offset ) |
680 | 696 | { |
681 | 697 | case 0x00: |
682 | 698 | case 0x20: |
683 | | state->m_current_bank ^= 1; |
| 699 | m_current_bank ^= 1; |
684 | 700 | break; |
685 | 701 | default: |
686 | | printf("%04X: write to unknown mapper address %02X\n", machine.device("maincpu")->safe_pc(), 0xfa0 + offset ); |
| 702 | printf("%04X: write to unknown mapper address %02X\n", machine().device("maincpu")->safe_pc(), 0xfa0 + offset ); |
687 | 703 | break; |
688 | 704 | } |
689 | | state->m_bank_base[1] = CART + 0x1000 * state->m_current_bank; |
690 | | state->membank("bank1")->set_base(state->m_bank_base[1] ); |
| 705 | m_bank_base[1] = m_cart + 0x1000 * m_current_bank; |
| 706 | membank("bank1")->set_base(m_bank_base[1] ); |
691 | 707 | } |
692 | 708 | |
693 | 709 | |
694 | 710 | /* These read handlers will return the byte from the new bank */ |
695 | 711 | READ8_MEMBER(a2600_state::modeF8_switch_r) |
696 | 712 | { |
697 | | modeF8_switch(machine(), offset, 0); |
| 713 | modeF8_switch(offset, 0); |
698 | 714 | return m_bank_base[1][0xff8 + offset]; |
699 | 715 | } |
700 | 716 | |
701 | 717 | READ8_MEMBER(a2600_state::modeFA_switch_r) |
702 | 718 | { |
703 | | modeFA_switch(machine(), offset, 0); |
| 719 | modeFA_switch(offset, 0); |
704 | 720 | return m_bank_base[1][0xff8 + offset]; |
705 | 721 | } |
706 | 722 | |
707 | 723 | READ8_MEMBER(a2600_state::modeF6_switch_r) |
708 | 724 | { |
709 | | modeF6_switch(machine(), offset, 0); |
| 725 | modeF6_switch(offset, 0); |
710 | 726 | return m_bank_base[1][0xff6 + offset]; |
711 | 727 | } |
712 | 728 | |
713 | 729 | READ8_MEMBER(a2600_state::modeF4_switch_r) |
714 | 730 | { |
715 | | modeF4_switch(machine(), offset, 0); |
| 731 | modeF4_switch(offset, 0); |
716 | 732 | return m_bank_base[1][0xff4 + offset]; |
717 | 733 | } |
718 | 734 | |
719 | 735 | READ8_MEMBER(a2600_state::modeE0_switch_r) |
720 | 736 | { |
721 | | modeE0_switch(machine(), offset, 0); |
| 737 | modeE0_switch(offset, 0); |
722 | 738 | return m_bank_base[4][0x3e0 + offset]; |
723 | 739 | } |
724 | 740 | |
725 | 741 | READ8_MEMBER(a2600_state::modeE7_switch_r) |
726 | 742 | { |
727 | | modeE7_switch(machine(), offset, 0); |
| 743 | modeE7_switch(offset, 0); |
728 | 744 | return m_bank_base[1][0xfe0 + offset]; |
729 | 745 | } |
730 | 746 | |
731 | 747 | READ8_MEMBER(a2600_state::modeE7_RAM_switch_r) |
732 | 748 | { |
733 | | modeE7_RAM_switch(machine(), offset, 0); |
| 749 | modeE7_RAM_switch(offset, 0); |
734 | 750 | return 0; |
735 | 751 | } |
736 | 752 | |
737 | 753 | READ8_MEMBER(a2600_state::modeUA_switch_r) |
738 | 754 | { |
739 | | modeUA_switch(machine(), offset, 0); |
| 755 | modeUA_switch(offset, 0); |
740 | 756 | return 0; |
741 | 757 | } |
742 | 758 | |
743 | 759 | READ8_MEMBER(a2600_state::modeDC_switch_r) |
744 | 760 | { |
745 | | modeDC_switch(machine(), offset, 0); |
| 761 | modeDC_switch(offset, 0); |
746 | 762 | return m_bank_base[1][0xff0 + offset]; |
747 | 763 | } |
748 | 764 | |
749 | 765 | READ8_MEMBER(a2600_state::modeFV_switch_r) |
750 | 766 | { |
751 | | modeFV_switch(machine(), offset, 0); |
| 767 | modeFV_switch(offset, 0); |
752 | 768 | return m_bank_base[1][0xfd0 + offset]; |
753 | 769 | } |
754 | 770 | |
755 | 771 | READ8_MEMBER(a2600_state::modeJVP_switch_r) |
756 | 772 | { |
757 | | modeJVP_switch(machine(), offset, 0); |
| 773 | modeJVP_switch(offset, 0); |
758 | 774 | return m_riot_ram[ 0x20 + offset ]; |
759 | 775 | } |
760 | 776 | |
761 | 777 | |
762 | | WRITE8_MEMBER(a2600_state::modeF8_switch_w){ modeF8_switch(machine(), offset, data); } |
763 | | WRITE8_MEMBER(a2600_state::modeFA_switch_w){ modeFA_switch(machine(), offset, data); } |
764 | | WRITE8_MEMBER(a2600_state::modeF6_switch_w){ modeF6_switch(machine(), offset, data); } |
765 | | WRITE8_MEMBER(a2600_state::modeF4_switch_w){ modeF4_switch(machine(), offset, data); } |
766 | | WRITE8_MEMBER(a2600_state::modeE0_switch_w){ modeE0_switch(machine(), offset, data); } |
767 | | WRITE8_MEMBER(a2600_state::modeE7_switch_w){ modeE7_switch(machine(), offset, data); } |
768 | | WRITE8_MEMBER(a2600_state::modeE7_RAM_switch_w){ modeE7_RAM_switch(machine(), offset, data); } |
769 | | WRITE8_MEMBER(a2600_state::mode3F_switch_w){ mode3F_switch(machine(), offset, data); } |
770 | | WRITE8_MEMBER(a2600_state::modeUA_switch_w){ modeUA_switch(machine(), offset, data); } |
771 | | WRITE8_MEMBER(a2600_state::modeDC_switch_w){ modeDC_switch(machine(), offset, data); } |
772 | | WRITE8_MEMBER(a2600_state::mode3E_switch_w){ mode3E_switch(machine(), offset, data); } |
773 | | WRITE8_MEMBER(a2600_state::mode3E_RAM_switch_w){ mode3E_RAM_switch(machine(), offset, data); } |
| 778 | WRITE8_MEMBER(a2600_state::modeF8_switch_w){ modeF8_switch(offset, data); } |
| 779 | WRITE8_MEMBER(a2600_state::modeFA_switch_w){ modeFA_switch(offset, data); } |
| 780 | WRITE8_MEMBER(a2600_state::modeF6_switch_w){ modeF6_switch(offset, data); } |
| 781 | WRITE8_MEMBER(a2600_state::modeF4_switch_w){ modeF4_switch(offset, data); } |
| 782 | WRITE8_MEMBER(a2600_state::modeE0_switch_w){ modeE0_switch(offset, data); } |
| 783 | WRITE8_MEMBER(a2600_state::modeE7_switch_w){ modeE7_switch(offset, data); } |
| 784 | WRITE8_MEMBER(a2600_state::modeE7_RAM_switch_w){ modeE7_RAM_switch(offset, data); } |
| 785 | WRITE8_MEMBER(a2600_state::mode3F_switch_w){ mode3F_switch(offset, data); } |
| 786 | WRITE8_MEMBER(a2600_state::modeUA_switch_w){ modeUA_switch(offset, data); } |
| 787 | WRITE8_MEMBER(a2600_state::modeDC_switch_w){ modeDC_switch(offset, data); } |
| 788 | WRITE8_MEMBER(a2600_state::mode3E_switch_w){ mode3E_switch(offset, data); } |
| 789 | WRITE8_MEMBER(a2600_state::mode3E_RAM_switch_w){ mode3E_RAM_switch(offset, data); } |
774 | 790 | WRITE8_MEMBER(a2600_state::mode3E_RAM_w) |
775 | 791 | { |
776 | 792 | if ( m_mode3E_ram_enabled ) |
r18247 | r18248 | |
778 | 794 | m_ram_base[offset] = data; |
779 | 795 | } |
780 | 796 | } |
781 | | WRITE8_MEMBER(a2600_state::modeFV_switch_w){ modeFV_switch(machine(), offset, data); } |
| 797 | WRITE8_MEMBER(a2600_state::modeFV_switch_w){ modeFV_switch(offset, data); } |
782 | 798 | WRITE8_MEMBER(a2600_state::modeJVP_switch_w) |
783 | 799 | { |
784 | | modeJVP_switch(machine(), offset, data); m_riot_ram[ 0x20 + offset ] = data; |
| 800 | modeJVP_switch(offset, data); m_riot_ram[ 0x20 + offset ] = data; |
785 | 801 | } |
786 | 802 | |
787 | 803 | |
r18247 | r18248 | |
1585 | 1601 | }; |
1586 | 1602 | |
1587 | 1603 | |
1588 | | static void common_init(running_machine &machine) |
1589 | | { |
1590 | | a2600_state *state = machine.driver_data<a2600_state>(); |
1591 | | screen_device *screen = machine.first_screen(); |
1592 | | state->m_current_screen_height = screen->height(); |
1593 | | state->m_extra_RAM = machine.memory().region_alloc("user2", 0x8600, 1, ENDIANNESS_LITTLE); |
1594 | | memset( state->m_riot_ram, 0x00, 0x80 ); |
1595 | | state->m_current_reset_bank_counter = 0xFF; |
1596 | | state->m_dpc.oscillator = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(a2600_state::modeDPC_timer_callback),state)); |
1597 | | } |
1598 | | |
1599 | 1604 | MACHINE_START_MEMBER(a2600_state,a2600) |
1600 | 1605 | { |
1601 | | common_init(machine()); |
| 1606 | screen_device *screen = machine().first_screen(); |
| 1607 | m_current_screen_height = screen->height(); |
| 1608 | m_extra_RAM = machine().memory().region_alloc("user2", 0x8600, 1, ENDIANNESS_LITTLE); |
| 1609 | memset( m_riot_ram, 0x00, 0x80 ); |
| 1610 | m_current_reset_bank_counter = 0xFF; |
| 1611 | m_dpc.oscillator = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a2600_state::modeDPC_timer_callback),this)); |
| 1612 | m_cart = CART_MEMBER; |
1602 | 1613 | } |
1603 | 1614 | |
1604 | | MACHINE_START_MEMBER(a2600_state,a2600p) |
1605 | | { |
1606 | | common_init(machine()); |
1607 | | } |
1608 | 1615 | |
1609 | 1616 | #ifdef UNUSED_FUNCTIONS |
1610 | 1617 | // try to detect 2600 controller setup. returns 32bits with left/right controller info |
r18247 | r18248 | |
2269 | 2276 | MCFG_CPU_ADD("maincpu", M6502, MASTER_CLOCK_PAL / 3) /* actually M6507 */ |
2270 | 2277 | MCFG_CPU_PROGRAM_MAP(a2600_mem) |
2271 | 2278 | |
2272 | | MCFG_MACHINE_START_OVERRIDE(a2600_state,a2600p) |
| 2279 | MCFG_MACHINE_START_OVERRIDE(a2600_state,a2600) |
2273 | 2280 | |
2274 | 2281 | /* video hardware */ |
2275 | 2282 | MCFG_TIA_VIDEO_ADD("tia_video", a2600_tia_interface_pal) |