trunk/src/mame/machine/megadriv.c
r22017 | r22018 | |
32 | 32 | |
33 | 33 | timer_device* megadriv_scanline_timer; |
34 | 34 | |
35 | | struct genesis_z80_vars |
36 | | { |
37 | | int z80_is_reset; |
38 | | int z80_has_bus; |
39 | | UINT32 z80_bank_addr; |
40 | | UINT8* z80_prgram; |
41 | | }; |
42 | 35 | |
43 | | genesis_z80_vars genz80; |
44 | | |
45 | 36 | void megadriv_z80_hold(running_machine &machine) |
46 | 37 | { |
47 | | if ((genz80.z80_has_bus == 1) && (genz80.z80_is_reset == 0)) |
| 38 | md_base_state *state = machine.driver_data<md_base_state>(); |
| 39 | if ((state->m_genz80.z80_has_bus == 1) && (state->m_genz80.z80_is_reset == 0)) |
48 | 40 | machine.device(":genesis_snd_z80")->execute().set_input_line(0, HOLD_LINE); |
49 | 41 | } |
50 | 42 | |
r22017 | r22018 | |
53 | 45 | machine.device(":genesis_snd_z80")->execute().set_input_line(0, CLEAR_LINE); |
54 | 46 | } |
55 | 47 | |
56 | | static void megadriv_z80_bank_w(UINT16 data) |
| 48 | static void megadriv_z80_bank_w(address_space &space, UINT16 data) |
57 | 49 | { |
58 | | genz80.z80_bank_addr = ( ( genz80.z80_bank_addr >> 1 ) | ( data << 23 ) ) & 0xff8000; |
| 50 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
| 51 | state->m_genz80.z80_bank_addr = ((state->m_genz80.z80_bank_addr >> 1) | (data << 23)) & 0xff8000; |
59 | 52 | } |
60 | 53 | |
61 | 54 | static WRITE16_HANDLER( megadriv_68k_z80_bank_write ) |
62 | 55 | { |
63 | 56 | //logerror("%06x: 68k writing bit to bank register %01x\n", space.device().safe_pc(),data&0x01); |
64 | | megadriv_z80_bank_w(data&0x01); |
| 57 | megadriv_z80_bank_w(space, data & 0x01); |
65 | 58 | } |
66 | 59 | |
67 | 60 | static WRITE8_HANDLER(megadriv_z80_z80_bank_w) |
68 | 61 | { |
69 | 62 | //logerror("%04x: z80 writing bit to bank register %01x\n", space.device().safe_pc(),data&0x01); |
70 | | megadriv_z80_bank_w(data&0x01); |
| 63 | megadriv_z80_bank_w(space, data & 0x01); |
71 | 64 | } |
72 | 65 | |
73 | 66 | |
r22017 | r22018 | |
85 | 78 | { |
86 | 79 | device_t *device = machine().device("ymsnd"); |
87 | 80 | //mame_printf_debug("megadriv_68k_YM2612_read %02x %04x\n",offset,mem_mask); |
88 | | if ( (genz80.z80_has_bus==0) && (genz80.z80_is_reset==0) ) |
| 81 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
89 | 82 | { |
90 | 83 | return ym2612_r(device, space, offset); |
91 | 84 | } |
r22017 | r22018 | |
103 | 96 | { |
104 | 97 | device_t *device = machine().device("ymsnd"); |
105 | 98 | //mame_printf_debug("megadriv_68k_YM2612_write %02x %04x %04x\n",offset,data,mem_mask); |
106 | | if ( (genz80.z80_has_bus==0) && (genz80.z80_is_reset==0) ) |
| 99 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
107 | 100 | { |
108 | 101 | ym2612_w(device, space, offset, data); |
109 | 102 | } |
r22017 | r22018 | |
570 | 563 | |
571 | 564 | static READ16_HANDLER( megadriv_68k_read_z80_ram ) |
572 | 565 | { |
| 566 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
573 | 567 | //mame_printf_debug("read z80 ram %04x\n",mem_mask); |
574 | 568 | |
575 | | if ( (genz80.z80_has_bus==0) && (genz80.z80_is_reset==0) ) |
| 569 | if ((state->m_genz80.z80_has_bus == 0) && (state->m_genz80.z80_is_reset == 0)) |
576 | 570 | { |
577 | | return genz80.z80_prgram[(offset<<1)^1] | (genz80.z80_prgram[(offset<<1)]<<8); |
| 571 | return state->m_genz80.z80_prgram[(offset<<1)^1] | (state->m_genz80.z80_prgram[(offset<<1)]<<8); |
578 | 572 | } |
579 | 573 | else |
580 | 574 | { |
r22017 | r22018 | |
585 | 579 | |
586 | 580 | static WRITE16_HANDLER( megadriv_68k_write_z80_ram ) |
587 | 581 | { |
| 582 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
588 | 583 | //logerror("write z80 ram\n"); |
589 | 584 | |
590 | | if ((genz80.z80_has_bus==0) && (genz80.z80_is_reset==0)) |
| 585 | if ((state->m_genz80.z80_has_bus == 0) && (state->m_genz80.z80_is_reset == 0)) |
591 | 586 | { |
592 | 587 | if (!ACCESSING_BITS_0_7) // byte (MSB) access |
593 | 588 | { |
594 | | genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 589 | state->m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
595 | 590 | } |
596 | 591 | else if (!ACCESSING_BITS_8_15) |
597 | 592 | { |
598 | | genz80.z80_prgram[(offset<<1)^1] = (data & 0x00ff); |
| 593 | state->m_genz80.z80_prgram[(offset<<1)^1] = (data & 0x00ff); |
599 | 594 | } |
600 | 595 | else // for WORD access only the MSB is used, LSB is ignored |
601 | 596 | { |
602 | | genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
| 597 | state->m_genz80.z80_prgram[(offset<<1)] = (data & 0xff00) >> 8; |
603 | 598 | } |
604 | 599 | } |
605 | 600 | else |
r22017 | r22018 | |
611 | 606 | |
612 | 607 | static READ16_HANDLER( megadriv_68k_check_z80_bus ) |
613 | 608 | { |
| 609 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
614 | 610 | UINT16 retvalue; |
615 | 611 | |
616 | 612 | /* Double Dragon, Shadow of the Beast, Super Off Road, and Time Killers have buggy |
r22017 | r22018 | |
626 | 622 | /* Check if the 68k has the z80 bus */ |
627 | 623 | if (!ACCESSING_BITS_0_7) // byte (MSB) access |
628 | 624 | { |
629 | | if (genz80.z80_has_bus || genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 625 | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
630 | 626 | else retvalue = (nextvalue & 0xfeff); |
631 | 627 | |
632 | 628 | //logerror("%06x: 68000 check z80 Bus (byte MSB access) returning %04x mask %04x\n", space.device().safe_pc(),retvalue, mem_mask); |
r22017 | r22018 | |
636 | 632 | else if (!ACCESSING_BITS_8_15) // is this valid? |
637 | 633 | { |
638 | 634 | //logerror("%06x: 68000 check z80 Bus (byte LSB access) %04x\n", space.device().safe_pc(),mem_mask); |
639 | | if (genz80.z80_has_bus || genz80.z80_is_reset) retvalue = 0x0001; |
| 635 | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = 0x0001; |
640 | 636 | else retvalue = 0x0000; |
641 | 637 | |
642 | 638 | return retvalue; |
r22017 | r22018 | |
644 | 640 | else |
645 | 641 | { |
646 | 642 | //logerror("%06x: 68000 check z80 Bus (word access) %04x\n", space.device().safe_pc(),mem_mask); |
647 | | if (genz80.z80_has_bus || genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
| 643 | if (state->m_genz80.z80_has_bus || state->m_genz80.z80_is_reset) retvalue = nextvalue | 0x0100; |
648 | 644 | else retvalue = (nextvalue & 0xfeff); |
649 | 645 | |
650 | 646 | // mame_printf_debug("%06x: 68000 check z80 Bus (word access) %04x %04x\n", space.device().safe_pc(),mem_mask, retvalue); |
r22017 | r22018 | |
655 | 651 | |
656 | 652 | static TIMER_CALLBACK( megadriv_z80_run_state ) |
657 | 653 | { |
| 654 | md_base_state *state = machine.driver_data<md_base_state>(); |
658 | 655 | /* Is the z80 RESET line pulled? */ |
659 | | if ( genz80.z80_is_reset ) |
| 656 | if (state->m_genz80.z80_is_reset) |
660 | 657 | { |
661 | 658 | machine.device("genesis_snd_z80" )->reset(); |
662 | 659 | machine.device<cpu_device>( "genesis_snd_z80" )->suspend(SUSPEND_REASON_HALT, 1 ); |
r22017 | r22018 | |
665 | 662 | else |
666 | 663 | { |
667 | 664 | /* Check if z80 has the bus */ |
668 | | if ( genz80.z80_has_bus ) |
| 665 | if (state->m_genz80.z80_has_bus) |
669 | 666 | { |
670 | 667 | machine.device<cpu_device>( "genesis_snd_z80" )->resume(SUSPEND_REASON_HALT ); |
671 | 668 | } |
r22017 | r22018 | |
679 | 676 | |
680 | 677 | static WRITE16_HANDLER( megadriv_68k_req_z80_bus ) |
681 | 678 | { |
| 679 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
682 | 680 | /* Request the Z80 bus, allows 68k to read/write Z80 address space */ |
683 | 681 | if (!ACCESSING_BITS_0_7) // byte access |
684 | 682 | { |
685 | 683 | if (data & 0x0100) |
686 | 684 | { |
687 | 685 | //logerror("%06x: 68000 request z80 Bus (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
688 | | genz80.z80_has_bus = 0; |
| 686 | state->m_genz80.z80_has_bus = 0; |
689 | 687 | } |
690 | 688 | else |
691 | 689 | { |
692 | 690 | //logerror("%06x: 68000 return z80 Bus (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
693 | | genz80.z80_has_bus = 1; |
| 691 | state->m_genz80.z80_has_bus = 1; |
694 | 692 | } |
695 | 693 | } |
696 | 694 | else if (!ACCESSING_BITS_8_15) // is this valid? |
r22017 | r22018 | |
698 | 696 | if (data & 0x0001) |
699 | 697 | { |
700 | 698 | //logerror("%06x: 68000 request z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
701 | | genz80.z80_has_bus = 0; |
| 699 | state->m_genz80.z80_has_bus = 0; |
702 | 700 | } |
703 | 701 | else |
704 | 702 | { |
705 | 703 | //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
706 | | genz80.z80_has_bus = 1; |
| 704 | state->m_genz80.z80_has_bus = 1; |
707 | 705 | } |
708 | 706 | } |
709 | 707 | else // word access |
r22017 | r22018 | |
711 | 709 | if (data & 0x0100) |
712 | 710 | { |
713 | 711 | //logerror("%06x: 68000 request z80 Bus (word access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
714 | | genz80.z80_has_bus = 0; |
| 712 | state->m_genz80.z80_has_bus = 0; |
715 | 713 | } |
716 | 714 | else |
717 | 715 | { |
718 | 716 | //logerror("%06x: 68000 return z80 Bus (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
719 | | genz80.z80_has_bus = 1; |
| 717 | state->m_genz80.z80_has_bus = 1; |
720 | 718 | } |
721 | 719 | } |
722 | 720 | |
723 | 721 | /* If the z80 is running, sync the z80 execution state */ |
724 | | if ( ! genz80.z80_is_reset ) |
725 | | space.machine().scheduler().timer_set( attotime::zero, FUNC(megadriv_z80_run_state )); |
| 722 | if (!state->m_genz80.z80_is_reset) |
| 723 | space.machine().scheduler().timer_set(attotime::zero, FUNC(megadriv_z80_run_state)); |
726 | 724 | } |
727 | 725 | |
728 | 726 | static WRITE16_HANDLER ( megadriv_68k_req_z80_reset ) |
729 | 727 | { |
| 728 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
730 | 729 | if (!ACCESSING_BITS_0_7) // byte access |
731 | 730 | { |
732 | 731 | if (data & 0x0100) |
733 | 732 | { |
734 | 733 | //logerror("%06x: 68000 clear z80 reset (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
735 | | genz80.z80_is_reset = 0; |
| 734 | state->m_genz80.z80_is_reset = 0; |
736 | 735 | } |
737 | 736 | else |
738 | 737 | { |
739 | 738 | //logerror("%06x: 68000 start z80 reset (byte MSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
740 | | genz80.z80_is_reset = 1; |
| 739 | state->m_genz80.z80_is_reset = 1; |
741 | 740 | } |
742 | 741 | } |
743 | 742 | else if (!ACCESSING_BITS_8_15) // is this valid? |
r22017 | r22018 | |
745 | 744 | if (data & 0x0001) |
746 | 745 | { |
747 | 746 | //logerror("%06x: 68000 clear z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
748 | | genz80.z80_is_reset = 0; |
| 747 | state->m_genz80.z80_is_reset = 0; |
749 | 748 | } |
750 | 749 | else |
751 | 750 | { |
752 | 751 | //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
753 | | genz80.z80_is_reset = 1; |
| 752 | state->m_genz80.z80_is_reset = 1; |
754 | 753 | } |
755 | 754 | } |
756 | 755 | else // word access |
r22017 | r22018 | |
758 | 757 | if (data & 0x0100) |
759 | 758 | { |
760 | 759 | //logerror("%06x: 68000 clear z80 reset (word access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
761 | | genz80.z80_is_reset = 0; |
| 760 | state->m_genz80.z80_is_reset = 0; |
762 | 761 | } |
763 | 762 | else |
764 | 763 | { |
765 | 764 | //logerror("%06x: 68000 start z80 reset (byte LSB access) %04x %04x\n", space.device().safe_pc(),data,mem_mask); |
766 | | genz80.z80_is_reset = 1; |
| 765 | state->m_genz80.z80_is_reset = 1; |
767 | 766 | } |
768 | 767 | } |
769 | 768 | space.machine().scheduler().timer_set( attotime::zero, FUNC(megadriv_z80_run_state )); |
r22017 | r22018 | |
776 | 775 | // z80 area of the 68k if games misbehave |
777 | 776 | static READ8_HANDLER( z80_read_68k_banked_data ) |
778 | 777 | { |
| 778 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
779 | 779 | address_space &space68k = space.machine().device<legacy_cpu_device>("maincpu")->space(); |
780 | | UINT8 ret = space68k.read_byte(genz80.z80_bank_addr+offset); |
| 780 | UINT8 ret = space68k.read_byte(state->m_genz80.z80_bank_addr+offset); |
781 | 781 | return ret; |
782 | 782 | } |
783 | 783 | |
784 | 784 | static WRITE8_HANDLER( z80_write_68k_banked_data ) |
785 | 785 | { |
| 786 | md_base_state *state = space.machine().driver_data<md_base_state>(); |
786 | 787 | address_space &space68k = space.machine().device<legacy_cpu_device>("maincpu")->space(); |
787 | | space68k.write_byte(genz80.z80_bank_addr+offset,data); |
| 788 | space68k.write_byte(state->m_genz80.z80_bank_addr+offset,data); |
788 | 789 | } |
789 | 790 | |
790 | 791 | |
r22017 | r22018 | |
930 | 931 | |
931 | 932 | if (machine.device("genesis_snd_z80") != NULL) |
932 | 933 | { |
933 | | genz80.z80_is_reset = 1; |
934 | | genz80.z80_has_bus = 1; |
935 | | genz80.z80_bank_addr = 0; |
| 934 | state->m_genz80.z80_is_reset = 1; |
| 935 | state->m_genz80.z80_has_bus = 1; |
| 936 | state->m_genz80.z80_bank_addr = 0; |
936 | 937 | genesis_scanline_counter = -1; |
937 | | machine.scheduler().timer_set( attotime::zero, FUNC(megadriv_z80_run_state )); |
| 938 | machine.scheduler().timer_set(attotime::zero, FUNC(megadriv_z80_run_state)); |
938 | 939 | } |
939 | 940 | |
940 | 941 | megadrive_reset_io(machine); |
r22017 | r22018 | |
1223 | 1224 | if (machine().device("genesis_snd_z80")) |
1224 | 1225 | { |
1225 | 1226 | //printf("GENESIS Sound Z80 cpu found '%s'\n", machine().device("genesis_snd_z80")->tag()); |
1226 | | genz80.z80_prgram = auto_alloc_array(machine(), UINT8, 0x2000); |
1227 | | membank("bank1")->set_base(genz80.z80_prgram); |
| 1227 | m_genz80.z80_prgram = auto_alloc_array(machine(), UINT8, 0x2000); |
| 1228 | membank("bank1")->set_base(m_genz80.z80_prgram); |
1228 | 1229 | } |
1229 | 1230 | |
1230 | 1231 | /* Look to see if this system has the 32x Master SH2 */ |
r22017 | r22018 | |
1366 | 1367 | /* sets the megadrive z80 to it's normal ports / map */ |
1367 | 1368 | void megatech_set_megadrive_z80_as_megadrive_z80(running_machine &machine, const char* tag) |
1368 | 1369 | { |
| 1370 | md_base_state *state = machine.driver_data<md_base_state>(); |
1369 | 1371 | device_t *ym = machine.device("ymsnd"); |
1370 | 1372 | |
1371 | 1373 | /* INIT THE PORTS *********************************************************************************************/ |
r22017 | r22018 | |
1376 | 1378 | |
1377 | 1379 | |
1378 | 1380 | machine.device(tag)->memory().space(AS_PROGRAM).install_readwrite_bank(0x0000, 0x1fff, "bank1"); |
1379 | | machine.root_device().membank("bank1")->set_base(genz80.z80_prgram ); |
| 1381 | machine.root_device().membank("bank1")->set_base(state->m_genz80.z80_prgram); |
1380 | 1382 | |
1381 | | machine.device(tag)->memory().space(AS_PROGRAM).install_ram(0x0000, 0x1fff, genz80.z80_prgram); |
| 1383 | machine.device(tag)->memory().space(AS_PROGRAM).install_ram(0x0000, 0x1fff, state->m_genz80.z80_prgram); |
1382 | 1384 | |
1383 | 1385 | |
1384 | 1386 | machine.device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(*ym, 0x4000, 0x4003, FUNC(ym2612_r), FUNC(ym2612_w)); |