trunk/src/mame/drivers/cps2.c
| r20724 | r20725 | |
| 688 | 688 | "0111" /* erase command */ |
| 689 | 689 | }; |
| 690 | 690 | |
| 691 | | static WRITE16_HANDLER( cps2_eeprom_port_w ) |
| 691 | WRITE16_MEMBER( cps_state::cps2_eeprom_port_w ) |
| 692 | 692 | { |
| 693 | | cps_state *state = space.machine().driver_data<cps_state>(); |
| 694 | | |
| 695 | 693 | if (ACCESSING_BITS_8_15) |
| 696 | 694 | { |
| 697 | 695 | /* bit 0 - Unused */ |
| r20724 | r20725 | |
| 704 | 702 | /* bit 7 - */ |
| 705 | 703 | |
| 706 | 704 | /* EEPROM */ |
| 707 | | state->ioport("EEPROMOUT")->write(data, 0xffff); |
| 705 | ioport("EEPROMOUT")->write(data, 0xffff); |
| 708 | 706 | } |
| 709 | 707 | |
| 710 | 708 | if (ACCESSING_BITS_0_7) |
| r20724 | r20725 | |
| 719 | 717 | /* bit 7 - */ |
| 720 | 718 | |
| 721 | 719 | /* Z80 Reset */ |
| 722 | | if (state->m_audiocpu != NULL) |
| 723 | | state->m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x0008) ? CLEAR_LINE : ASSERT_LINE); |
| 720 | if (m_audiocpu != NULL) |
| 721 | m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x0008) ? CLEAR_LINE : ASSERT_LINE); |
| 724 | 722 | |
| 725 | | coin_counter_w(space.machine(), 0, data & 0x0001); |
| 726 | | if ((strncmp(space.machine().system().name, "pzloop2", 8) == 0) || |
| 727 | | (strncmp(space.machine().system().name, "pzloop2j", 8) == 0) || |
| 728 | | (strncmp(space.machine().system().name, "pzloop2jr1", 8) == 0)) |
| 723 | coin_counter_w(machine(), 0, data & 0x0001); |
| 724 | if ((strncmp(machine().system().name, "pzloop2", 8) == 0) || |
| 725 | (strncmp(machine().system().name, "pzloop2j", 8) == 0) || |
| 726 | (strncmp(machine().system().name, "pzloop2jr1", 8) == 0)) |
| 729 | 727 | { |
| 730 | 728 | // Puzz Loop 2 uses coin counter 2 input to switch between stick and paddle controls |
| 731 | | state->m_readpaddle = data & 0x0002; |
| 729 | m_readpaddle = data & 0x0002; |
| 732 | 730 | } |
| 733 | 731 | else |
| 734 | 732 | { |
| 735 | | coin_counter_w(space.machine(), 1, data & 0x0002); |
| 733 | coin_counter_w(machine(), 1, data & 0x0002); |
| 736 | 734 | } |
| 737 | 735 | |
| 738 | | if (strncmp(space.machine().system().name, "mmatrix", 7) == 0) // Mars Matrix seems to require the coin lockout bit to be reversed |
| 736 | if (strncmp(machine().system().name, "mmatrix", 7) == 0) // Mars Matrix seems to require the coin lockout bit to be reversed |
| 739 | 737 | { |
| 740 | | coin_lockout_w(space.machine(), 0, data & 0x0010); |
| 741 | | coin_lockout_w(space.machine(), 1, data & 0x0020); |
| 742 | | coin_lockout_w(space.machine(), 2, data & 0x0040); |
| 743 | | coin_lockout_w(space.machine(), 3, data & 0x0080); |
| 738 | coin_lockout_w(machine(), 0, data & 0x0010); |
| 739 | coin_lockout_w(machine(), 1, data & 0x0020); |
| 740 | coin_lockout_w(machine(), 2, data & 0x0040); |
| 741 | coin_lockout_w(machine(), 3, data & 0x0080); |
| 744 | 742 | } |
| 745 | 743 | else |
| 746 | 744 | { |
| 747 | | coin_lockout_w(space.machine(), 0, ~data & 0x0010); |
| 748 | | coin_lockout_w(space.machine(), 1, ~data & 0x0020); |
| 749 | | coin_lockout_w(space.machine(), 2, ~data & 0x0040); |
| 750 | | coin_lockout_w(space.machine(), 3, ~data & 0x0080); |
| 745 | coin_lockout_w(machine(), 0, ~data & 0x0010); |
| 746 | coin_lockout_w(machine(), 1, ~data & 0x0020); |
| 747 | coin_lockout_w(machine(), 2, ~data & 0x0040); |
| 748 | coin_lockout_w(machine(), 3, ~data & 0x0080); |
| 751 | 749 | } |
| 752 | 750 | |
| 753 | 751 | /* |
| 754 | | set_led_status(space.machine(), 0, data & 0x01); |
| 755 | | set_led_status(space.machine(), 1, data & 0x10); |
| 756 | | set_led_status(space.machine(), 2, data & 0x20); |
| 752 | set_led_status(machine(), 0, data & 0x01); |
| 753 | set_led_status(machine(), 1, data & 0x10); |
| 754 | set_led_status(machine(), 2, data & 0x20); |
| 757 | 755 | */ |
| 758 | 756 | } |
| 759 | 757 | } |
| r20724 | r20725 | |
| 765 | 763 | * |
| 766 | 764 | *************************************/ |
| 767 | 765 | |
| 768 | | TIMER_CALLBACK_MEMBER(cps_state::cps2_update_digital_volume) |
| 769 | | { |
| 766 | TIMER_CALLBACK_MEMBER(cps_state::cps2_update_digital_volume) |
| 767 | { |
| 770 | 768 | int vol_button_state; |
| 771 | 769 | |
| 772 | 770 | vol_button_state = ioport("DIGITALVOL")->read(); |
| r20724 | r20725 | |
| 779 | 777 | |
| 780 | 778 | machine().device<qsound_device>("qsound")->set_output_gain(0, m_cps2digitalvolumelevel / 39.0); |
| 781 | 779 | machine().device<qsound_device>("qsound")->set_output_gain(1, m_cps2digitalvolumelevel / 39.0); |
| 782 | | } |
| 780 | } |
| 783 | 781 | |
| 784 | | static READ16_HANDLER( cps2_qsound_volume_r ) |
| 782 | READ16_MEMBER( cps_state::cps2_qsound_volume_r ) |
| 785 | 783 | { |
| 786 | | cps_state *state = space.machine().driver_data<cps_state>(); |
| 787 | | |
| 788 | | UINT16 cps2_vol_states[40] = |
| 784 | static const UINT16 cps2_vol_states[40] = |
| 789 | 785 | { |
| 790 | 786 | 0xf010, 0xf008, 0xf004, 0xf002, 0xf001, 0xe810, 0xe808, 0xe804, 0xe802, 0xe801, |
| 791 | 787 | 0xe410, 0xe408, 0xe404, 0xe402, 0xe401, 0xe210, 0xe208, 0xe204, 0xe202, 0xe201, |
| r20724 | r20725 | |
| 795 | 791 | |
| 796 | 792 | UINT16 result; |
| 797 | 793 | |
| 798 | | result = cps2_vol_states[state->m_cps2digitalvolumelevel]; |
| 794 | result = cps2_vol_states[m_cps2digitalvolumelevel]; |
| 799 | 795 | |
| 800 | 796 | /* Extra adapter memory (0x660000-0x663fff) available when bit 14 = 0 */ |
| 801 | 797 | /* Network adapter (ssf2tb) present when bit 15 = 0 */ |
| 802 | 798 | /* Only game known to use both these so far is SSF2TB */ |
| 803 | 799 | |
| 804 | | if (state->m_cps2networkpresent) |
| 800 | if (m_cps2networkpresent) |
| 805 | 801 | return 0x2021; /* SSF2TB doesn't have a digital slider in the test screen */ |
| 806 | 802 | else |
| 807 | | if (state->m_cps2disabledigitalvolume) |
| 803 | if (m_cps2disabledigitalvolume) |
| 808 | 804 | return 0xd000; /* digital display isn't shown in test mode */ |
| 809 | 805 | else |
| 810 | 806 | return result; |
| r20724 | r20725 | |
| 817 | 813 | * |
| 818 | 814 | *************************************/ |
| 819 | 815 | |
| 820 | | static READ16_HANDLER( kludge_r ) |
| 816 | READ16_MEMBER( cps_state::kludge_r ) |
| 821 | 817 | { |
| 822 | 818 | return 0xffff; |
| 823 | 819 | } |
| 824 | 820 | |
| 825 | | static READ16_HANDLER( joy_or_paddle_r ) |
| 821 | READ16_MEMBER( cps_state::joy_or_paddle_r ) |
| 826 | 822 | { |
| 827 | | cps_state *state = space.machine().driver_data<cps_state>(); |
| 828 | | |
| 829 | | if (state->m_readpaddle != 0) |
| 830 | | return (state->ioport("IN0")->read()); |
| 823 | if (m_readpaddle != 0) |
| 824 | return (ioport("IN0")->read()); |
| 831 | 825 | else |
| 832 | | return (state->ioport("PADDLE1")->read() & 0xff) | (state->ioport("PADDLE2")->read() << 8); |
| 826 | return (ioport("PADDLE1")->read() & 0xff) | (ioport("PADDLE2")->read() << 8); |
| 833 | 827 | } |
| 834 | 828 | |
| 835 | 829 | |
| r20724 | r20725 | |
| 855 | 849 | AM_RANGE(0x804000, 0x804001) AM_READ_PORT("IN0") /* IN0 */ |
| 856 | 850 | AM_RANGE(0x804010, 0x804011) AM_READ_PORT("IN1") /* IN1 */ |
| 857 | 851 | AM_RANGE(0x804020, 0x804021) AM_READ_PORT("IN2") /* IN2 + EEPROM */ |
| 858 | | AM_RANGE(0x804030, 0x804031) AM_READ_LEGACY(cps2_qsound_volume_r) /* Master volume. Also when bit 14=0 addon memory is present, when bit 15=0 network adapter present. */ |
| 859 | | AM_RANGE(0x804040, 0x804041) AM_WRITE_LEGACY(cps2_eeprom_port_w) /* EEPROM */ |
| 852 | AM_RANGE(0x804030, 0x804031) AM_READ(cps2_qsound_volume_r) /* Master volume. Also when bit 14=0 addon memory is present, when bit 15=0 network adapter present. */ |
| 853 | AM_RANGE(0x804040, 0x804041) AM_WRITE(cps2_eeprom_port_w) /* EEPROM */ |
| 860 | 854 | AM_RANGE(0x8040a0, 0x8040a1) AM_WRITENOP /* Unknown (reset once on startup) */ |
| 861 | | AM_RANGE(0x8040b0, 0x8040b3) AM_READ_LEGACY(kludge_r) /* unknown (xmcotaj hangs if this is 0) */ |
| 855 | AM_RANGE(0x8040b0, 0x8040b3) AM_READ(kludge_r) /* unknown (xmcotaj hangs if this is 0) */ |
| 862 | 856 | AM_RANGE(0x8040e0, 0x8040e1) AM_WRITE(cps2_objram_bank_w) /* bit 0 = Object ram bank swap */ |
| 863 | 857 | AM_RANGE(0x804100, 0x80413f) AM_WRITE(cps1_cps_a_w) AM_SHARE("cps_a_regs") /* CPS-A custom */ |
| 864 | 858 | AM_RANGE(0x804140, 0x80417f) AM_READWRITE(cps1_cps_b_r, cps1_cps_b_w) /* CPS-B custom */ |
| r20724 | r20725 | |
| 883 | 877 | AM_RANGE(0x804000, 0x804001) AM_READ_PORT("IN0") /* IN0 */ |
| 884 | 878 | AM_RANGE(0x804010, 0x804011) AM_READ_PORT("IN1") /* IN1 */ |
| 885 | 879 | AM_RANGE(0x804020, 0x804021) AM_READ_PORT("IN2") /* IN2 + EEPROM */ |
| 886 | | AM_RANGE(0x804030, 0x804031) AM_READ_LEGACY(cps2_qsound_volume_r) /* Master volume. Also when bit 14=0 addon memory is present, when bit 15=0 network adapter present. */ |
| 887 | | AM_RANGE(0x804040, 0x804041) AM_WRITE_LEGACY(cps2_eeprom_port_w) /* EEPROM */ |
| 880 | AM_RANGE(0x804030, 0x804031) AM_READ(cps2_qsound_volume_r) /* Master volume. Also when bit 14=0 addon memory is present, when bit 15=0 network adapter present. */ |
| 881 | AM_RANGE(0x804040, 0x804041) AM_WRITE(cps2_eeprom_port_w) /* EEPROM */ |
| 888 | 882 | AM_RANGE(0x8040a0, 0x8040a1) AM_WRITENOP /* Unknown (reset once on startup) */ |
| 889 | | AM_RANGE(0x8040b0, 0x8040b3) AM_READ_LEGACY(kludge_r) /* unknown (xmcotaj hangs if this is 0) */ |
| 883 | AM_RANGE(0x8040b0, 0x8040b3) AM_READ(kludge_r) /* unknown (xmcotaj hangs if this is 0) */ |
| 890 | 884 | AM_RANGE(0x8040e0, 0x8040e1) AM_WRITE(cps2_objram_bank_w) /* bit 0 = Object ram bank swap */ |
| 891 | 885 | AM_RANGE(0x804100, 0x80413f) AM_WRITE(cps1_cps_a_w) AM_SHARE("cps_a_regs") /* CPS-A custom */ |
| 892 | 886 | AM_RANGE(0x804140, 0x80417f) AM_READWRITE(cps1_cps_b_r, cps1_cps_b_w) /* CPS-B custom */ |
| r20724 | r20725 | |
| 8271 | 8265 | * |
| 8272 | 8266 | *************************************/ |
| 8273 | 8267 | |
| 8274 | | static void init_digital_volume(running_machine &machine) |
| 8275 | | { |
| 8276 | | cps_state *state = machine.driver_data<cps_state>(); |
| 8268 | void cps_state::init_digital_volume() |
| 8269 | { |
| 8270 | m_cps2digitalvolumelevel = 39; /* maximum */ |
| 8271 | m_cps2disabledigitalvolume = 0; |
| 8277 | 8272 | |
| 8278 | | state->m_cps2digitalvolumelevel = 39; /* maximum */ |
| 8279 | | state->m_cps2disabledigitalvolume = 0; |
| 8280 | | |
| 8281 | 8273 | /* create a timer to update our volume state from the fake switches - read it every 6 frames or so to enable some granularity */ |
| 8282 | | state->m_digital_volume_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(cps_state::cps2_update_digital_volume),state)); |
| 8283 | | state->m_digital_volume_timer->adjust(attotime::from_msec(100), 0, attotime::from_msec(100)); |
| 8284 | | } |
| 8274 | m_digital_volume_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cps_state::cps2_update_digital_volume),this)); |
| 8275 | m_digital_volume_timer->adjust(attotime::from_msec(100), 0, attotime::from_msec(100)); |
| 8276 | } |
| 8285 | 8277 | |
| 8286 | 8278 | DRIVER_INIT_MEMBER(cps_state,cps2) |
| 8287 | 8279 | { |
| r20724 | r20725 | |
| 8293 | 8285 | |
| 8294 | 8286 | m_cps2networkpresent = 0; |
| 8295 | 8287 | |
| 8296 | | init_digital_volume(machine()); |
| 8288 | init_digital_volume(); |
| 8297 | 8289 | |
| 8298 | 8290 | machine().device("maincpu")->set_clock_scale(0.7375f); /* RAM access waitstates etc. aren't emulated - slow the CPU to compensate */ |
| 8299 | 8291 | } |
| r20724 | r20725 | |
| 8318 | 8310 | |
| 8319 | 8311 | save_item(NAME(m_readpaddle)); |
| 8320 | 8312 | |
| 8321 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0x804000, 0x804001, FUNC(joy_or_paddle_r)); |
| 8313 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x804000, 0x804001, read16_delegate(FUNC(cps_state::joy_or_paddle_r), this)); |
| 8322 | 8314 | } |
| 8323 | 8315 | |
| 8324 | 8316 | DRIVER_INIT_MEMBER(cps_state,singbrd) |
| r20724 | r20725 | |
| 8330 | 8322 | m_digital_volume_timer->adjust(attotime::never, 0, attotime::never); |
| 8331 | 8323 | } |
| 8332 | 8324 | |
| 8333 | | static READ16_HANDLER( gigaman2_dummyqsound_r ) |
| 8325 | READ16_MEMBER( cps_state::gigaman2_dummyqsound_r ) |
| 8334 | 8326 | { |
| 8335 | | cps_state *state = space.machine().driver_data<cps_state>(); |
| 8336 | | return state->m_gigaman2_dummyqsound_ram[offset]; |
| 8327 | return m_gigaman2_dummyqsound_ram[offset]; |
| 8337 | 8328 | }; |
| 8338 | 8329 | |
| 8339 | | static WRITE16_HANDLER( gigaman2_dummyqsound_w ) |
| 8330 | WRITE16_MEMBER( cps_state::gigaman2_dummyqsound_w ) |
| 8340 | 8331 | { |
| 8341 | | cps_state *state = space.machine().driver_data<cps_state>(); |
| 8342 | | state->m_gigaman2_dummyqsound_ram[offset] = data; |
| 8332 | m_gigaman2_dummyqsound_ram[offset] = data; |
| 8343 | 8333 | }; |
| 8344 | 8334 | |
| 8345 | 8335 | /* rearrange the graphics data into the normal order */ |
| 8346 | | static void gigaman2_gfx_reorder(running_machine &machine) |
| 8336 | void cps_state::gigaman2_gfx_reorder() |
| 8347 | 8337 | { |
| 8348 | 8338 | int i; |
| 8349 | | int length = machine.root_device().memregion( "gfx" )->bytes(); |
| 8350 | | UINT16 *rom = (UINT16 *)machine.root_device().memregion("gfx")->base(); |
| 8351 | | UINT16 *buf = auto_alloc_array(machine, UINT16, length ); |
| 8339 | int length = memregion( "gfx" )->bytes(); |
| 8340 | UINT16 *rom = (UINT16 *)memregion("gfx")->base(); |
| 8341 | UINT16 *buf = auto_alloc_array(machine(), UINT16, length ); |
| 8352 | 8342 | |
| 8353 | 8343 | memcpy (buf, rom, length); |
| 8354 | 8344 | |
| r20724 | r20725 | |
| 8356 | 8346 | rom[i] = buf[((i & ~7) >> 2) | ((i & 4) << 18) | ((i & 2) >> 1) | ((i & 1) << 21)]; |
| 8357 | 8347 | } |
| 8358 | 8348 | |
| 8359 | | auto_free( machine, buf ); |
| 8349 | auto_free( machine(), buf ); |
| 8360 | 8350 | } |
| 8361 | 8351 | |
| 8362 | 8352 | DRIVER_INIT_MEMBER(cps_state,gigaman2) |
| r20724 | r20725 | |
| 8365 | 8355 | UINT16 *rom = (UINT16 *)memregion("maincpu")->base(); |
| 8366 | 8356 | int length = memregion("maincpu")->bytes(); |
| 8367 | 8357 | |
| 8368 | | gigaman2_gfx_reorder(machine()); |
| 8358 | gigaman2_gfx_reorder(); |
| 8369 | 8359 | |
| 8370 | 8360 | DRIVER_INIT_CALL(cps2); |
| 8371 | 8361 | |
| 8372 | 8362 | m_gigaman2_dummyqsound_ram = auto_alloc_array(machine(), UINT16, 0x20000 / 2); |
| 8373 | 8363 | save_pointer(NAME(m_gigaman2_dummyqsound_ram), 0x20000 / 2); |
| 8374 | 8364 | |
| 8375 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(0x618000, 0x619fff, FUNC(gigaman2_dummyqsound_r), FUNC(gigaman2_dummyqsound_w)); // no qsound.. |
| 8365 | space.install_readwrite_handler(0x618000, 0x619fff, read16_delegate(FUNC(cps_state::gigaman2_dummyqsound_r),this), write16_delegate(FUNC(cps_state::gigaman2_dummyqsound_w), this)); // no qsound.. |
| 8376 | 8366 | space.set_decrypted_region(0x000000, (length) - 1, &rom[length/4]); |
| 8377 | 8367 | m68k_set_encrypted_opcode_range(machine().device("maincpu"), 0, length); |
| 8378 | 8368 | |