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)); |