diff --git a/src/mame/drivers/vsnes.cpp b/src/mame/drivers/vsnes.cpp index 1d4fe368070..22d4c56fbe4 100644 --- a/src/mame/drivers/vsnes.cpp +++ b/src/mame/drivers/vsnes.cpp @@ -198,24 +198,25 @@ void vsnes_state::vsnes_coin_counter_1_w(uint8_t data) void vsnes_state::vsnes_cpu1_map(address_map &map) { - map(0x0000, 0x07ff).mirror(0x1800).ram().share("work_ram"); + map(0x0000, 0x07ff).mirror(0x1800).ram(); map(0x2000, 0x3fff).rw(m_ppu1, FUNC(ppu2c0x_device::read), FUNC(ppu2c0x_device::write)); map(0x4014, 0x4014).w(FUNC(vsnes_state::sprite_dma_0_w)); map(0x4016, 0x4016).rw(FUNC(vsnes_state::vsnes_in0_r), FUNC(vsnes_state::vsnes_in0_w)); map(0x4017, 0x4017).r(FUNC(vsnes_state::vsnes_in1_r)); /* IN1 - input port 2 / PSG second control register */ - map(0x4020, 0x4020).rw(FUNC(vsnes_state::vsnes_coin_counter_r), FUNC(vsnes_state::vsnes_coin_counter_w)); - map(0x6000, 0x7fff).ram(); + map(0x4020, 0x4020).mirror(0x1fdf).rw(FUNC(vsnes_state::vsnes_coin_counter_r), FUNC(vsnes_state::vsnes_coin_counter_w)); + map(0x6000, 0x67ff).mirror(0x1800).ram().share("nvram"); map(0x8000, 0xffff).rom(); } void vsnes_state::vsnes_cpu2_map(address_map &map) { - map(0x0000, 0x07ff).mirror(0x1800).ram().share("work_ram_1"); + map(0x0000, 0x07ff).mirror(0x1800).ram(); map(0x2000, 0x3fff).rw(m_ppu2, FUNC(ppu2c0x_device::read), FUNC(ppu2c0x_device::write)); map(0x4014, 0x4014).w(FUNC(vsnes_state::sprite_dma_1_w)); map(0x4016, 0x4016).rw(FUNC(vsnes_state::vsnes_in0_1_r), FUNC(vsnes_state::vsnes_in0_1_w)); map(0x4017, 0x4017).r(FUNC(vsnes_state::vsnes_in1_1_r)); /* IN1 - input port 2 / PSG second control register */ - map(0x4020, 0x4020).w(FUNC(vsnes_state::vsnes_coin_counter_1_w)); + map(0x4020, 0x4020).mirror(0x1fdf).w(FUNC(vsnes_state::vsnes_coin_counter_1_w)); + map(0x6000, 0x67ff).mirror(0x1800).ram().share("nvram"); map(0x8000, 0xffff).rom(); } @@ -273,13 +274,13 @@ void vsnes_state::vssmbbl_sn_w(offs_t offset, uint8_t data) // the bootleg still makes writes to the PSG addresses, it seems the Z80 should interpret them to play the sounds void vsnes_state::vsnes_cpu1_bootleg_map(address_map &map) { - map(0x0000, 0x07ff).mirror(0x1800).ram().share("work_ram"); + map(0x0000, 0x07ff).mirror(0x0800).ram(); map(0x2000, 0x3fff).rw(m_ppu1, FUNC(ppu2c0x_device::read), FUNC(ppu2c0x_device::write)); map(0x4000, 0x400f).w(FUNC(vsnes_state::bootleg_sound_write)); map(0x4016, 0x4016).rw(FUNC(vsnes_state::vsnes_in0_r), FUNC(vsnes_state::vsnes_in0_w)); map(0x4017, 0x4017).r(FUNC(vsnes_state::vsnes_in1_r)); /* IN1 - input port 2 / PSG second control register */ map(0x4020, 0x4020).w(FUNC(vsnes_state::vsnes_coin_counter_w)); - map(0x6000, 0x7fff).ram(); + map(0x6000, 0x67ff).mirror(0x0800).ram(); map(0x8000, 0xffff).rom(); } @@ -299,7 +300,7 @@ void vsnes_state::vsnes_cpu1_bootleg_map(address_map &map) void vsnes_state::vsnes_bootleg_z80_map(address_map &map) { map(0x0000, 0x1fff).rom().region("sub", 0); - map(0x2000, 0x23ff).ram(); + map(0x2000, 0x27ff).ram(); map(0x4000, 0x5fff).r(FUNC(vsnes_state::vsnes_bootleg_z80_data_r)); // read in IRQ & NMI map(0x6000, 0x7fff).rw(FUNC(vsnes_state::vsnes_bootleg_z80_address_r), FUNC(vsnes_state::vssmbbl_sn_w)); @@ -470,7 +471,7 @@ static INPUT_PORTS_START( vsnes_zapper ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // low 6 bits always read 0b010000 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) /* sprite hit */ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) /* gun trigger */ @@ -1733,6 +1734,8 @@ void vsnes_state::vsnes(machine_config &config) MCFG_MACHINE_RESET_OVERRIDE(vsnes_state,vsnes) MCFG_MACHINE_START_OVERRIDE(vsnes_state,vsnes) + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + /* video hardware */ screen_device &screen1(SCREEN(config, "screen1", SCREEN_TYPE_RASTER)); screen1.set_raw(N2A03_NTSC_XTAL / 4, 341, 0, VISIBLE_SCREEN_WIDTH, ppu2c0x_device::NTSC_SCANLINES_PER_FRAME, 0, VISIBLE_SCREEN_HEIGHT); @@ -1797,11 +1800,13 @@ void vsnes_state::vsdual(machine_config &config) n2a03_device &subcpu(N2A03(config, m_subcpu, NTSC_APU_CLOCK)); subcpu.set_addrmap(AS_PROGRAM, &vsnes_state::vsnes_cpu2_map); - MCFG_MACHINE_RESET_OVERRIDE(vsnes_state,vsdual) + MCFG_MACHINE_RESET_OVERRIDE(vsnes_state,vsnes) MCFG_MACHINE_START_OVERRIDE(vsnes_state,vsdual) config.set_default_layout(layout_dualhsxs); + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + screen_device &screen1(SCREEN(config, "screen1", SCREEN_TYPE_RASTER)); screen1.set_raw(N2A03_NTSC_XTAL / 4, 341, 0, VISIBLE_SCREEN_WIDTH, ppu2c0x_device::NTSC_SCANLINES_PER_FRAME, 0, VISIBLE_SCREEN_HEIGHT); screen1.set_screen_update("ppu1", FUNC(ppu2c0x_device::screen_update)); diff --git a/src/mame/includes/vsnes.h b/src/mame/includes/vsnes.h index 749914e8694..44165d1a5b5 100644 --- a/src/mame/includes/vsnes.h +++ b/src/mame/includes/vsnes.h @@ -1,6 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli +#include "machine/nvram.h" #include "sound/sn76496.h" #include "video/ppu2c0x.h" @@ -15,8 +16,7 @@ public: , m_ppu2(*this, "ppu2") , m_sn1(*this, "sn1") , m_sn2(*this, "sn2") - , m_work_ram(*this, "work_ram") - , m_work_ram_1(*this, "work_ram_1") + , m_nvram(*this, "nvram") , m_gfx1_rom(*this, "gfx1") , m_chr_banks(*this, "chr%u", 0U) , m_bank_vrom(*this, "vrom%u", 0U) @@ -56,8 +56,7 @@ private: optional_device m_sn1; optional_device m_sn2; - required_shared_ptr m_work_ram; - optional_shared_ptr m_work_ram_1; + optional_device m_nvram; optional_memory_region m_gfx1_rom; memory_bank_array_creator<8> m_chr_banks; @@ -73,7 +72,6 @@ private: void vsnes_in0_1_w(uint8_t data); uint8_t vsnes_in0_1_r(); uint8_t vsnes_in1_1_r(); - uint8_t gun_in0_r(); void vsnormal_vrom_banking(uint8_t data); void gun_in0_w(uint8_t data); void vskonami_rom_banking(offs_t offset, uint8_t data); @@ -87,7 +85,7 @@ private: uint8_t supxevs_read_prot_3_r(); uint8_t supxevs_read_prot_4_r(); uint8_t tko_security_r(offs_t offset); - void mapper68_rom_banking(offs_t offset, uint8_t data); + void sunsoft3_rom_banking(offs_t offset, uint8_t data); void set_bnglngby_irq_w(uint8_t data); uint8_t set_bnglngby_irq_r(); void vsdual_vrom_banking_main(uint8_t data); @@ -97,7 +95,6 @@ private: DECLARE_MACHINE_START(vsnes); DECLARE_MACHINE_RESET(vsnes); DECLARE_MACHINE_START(vsdual); - DECLARE_MACHINE_RESET(vsdual); DECLARE_MACHINE_START(bootleg); void v_set_videorom_bank( int start, int count, int vrom_start_bank ); @@ -115,16 +112,13 @@ private: int m_coin; int m_do_vrom_bank; int m_input_latch[4]; - int m_sound_fix; - uint8_t m_last_bank; + int m_input_strobe[2]; std::unique_ptr m_vram; - std::unique_ptr m_extraram; uint8_t* m_vrom[2]; std::unique_ptr m_nt_ram[2]; memory_bank_array_creator<8> m_bank_vrom; uint32_t m_vrom_size[2]; int m_vrom_banks; - int m_zapstore; int m_old_bank; int m_drmario_shiftreg; int m_drmario_shiftcount; diff --git a/src/mame/machine/vsnes.cpp b/src/mame/machine/vsnes.cpp index ab5d478a59b..3a22c4795c3 100644 --- a/src/mame/machine/vsnes.cpp +++ b/src/mame/machine/vsnes.cpp @@ -33,98 +33,81 @@ Nintendo VS UniSystem and DualSystem - (c) 1984 Nintendo of America void vsnes_state::vsnes_in0_w(uint8_t data) { /* Toggling bit 0 high then low resets both controllers */ - if (data & 1) + if (m_input_strobe[0] & ~data & 1) { /* load up the latches */ m_input_latch[0] = ioport("IN0")->read(); m_input_latch[1] = ioport("IN1")->read(); } -} - -uint8_t vsnes_state::gun_in0_r() -{ - int ret = (m_input_latch[0]) & 1; - - /* shift */ - m_input_latch[0] >>= 1; - - ret |= ioport("COINS")->read(); /* merge coins, etc */ - ret |= (ioport("DSW0")->read() & 3) << 3; /* merge 2 dipswitches */ - -/* The gun games expect a 1 returned on every 5th read after sound_fix is reset*/ -/* Info Supplied by Ben Parnell of FCE Ultra fame */ - - if (m_sound_fix == 4) - { - ret = 1; - } - - m_sound_fix++; - - return ret; + m_input_strobe[0] = data; } uint8_t vsnes_state::vsnes_in0_r() { - int ret = (m_input_latch[0]) & 1; + if (m_input_strobe[0] & 1) + m_input_latch[0] = ioport("IN0")->read(); - /* shift */ + int ret = m_input_latch[0] & 1; m_input_latch[0] >>= 1; ret |= ioport("COINS")->read(); /* merge coins, etc */ ret |= (ioport("DSW0")->read() & 3) << 3; /* merge 2 dipswitches */ return ret; - } uint8_t vsnes_state::vsnes_in1_r() { - int ret = (m_input_latch[1]) & 1; + if (m_input_strobe[0] & 1) + m_input_latch[1] = ioport("IN1")->read(); + + int ret = m_input_latch[1] & 1; + m_input_latch[1] >>= 1; ret |= ioport("DSW0")->read() & ~3; /* merge the rest of the dipswitches */ - /* shift */ - m_input_latch[1] >>= 1; - return ret; } void vsnes_state::vsnes_in0_1_w(uint8_t data) { /* Toggling bit 0 high then low resets both controllers */ - if (data & 1) + if (m_input_strobe[1] & ~data & 1) { /* load up the latches */ m_input_latch[2] = ioport("IN2")->read(); m_input_latch[3] = ioport("IN3")->read(); } + + m_input_strobe[1] = data; } uint8_t vsnes_state::vsnes_in0_1_r() { - int ret = (m_input_latch[2]) & 1; + if (m_input_strobe[1] & 1) + m_input_latch[2] = ioport("IN2")->read(); - /* shift */ + int ret = m_input_latch[2] & 1; m_input_latch[2] >>= 1; ret |= ioport("COINS2")->read(); /* merge coins, etc */ ret |= (ioport("DSW1")->read() & 3) << 3; /* merge 2 dipswitches */ + return ret; } uint8_t vsnes_state::vsnes_in1_1_r() { - int ret = (m_input_latch[3]) & 1; + if (m_input_strobe[1] & 1) + m_input_latch[3] = ioport("IN3")->read(); + + int ret = m_input_latch[3] & 1; + m_input_latch[3] >>= 1; ret |= ioport("DSW1")->read() & ~3; /* merge the rest of the dipswitches */ - /* shift */ - m_input_latch[3] >>= 1; - return ret; - } /************************************* @@ -135,24 +118,9 @@ uint8_t vsnes_state::vsnes_in1_1_r() MACHINE_RESET_MEMBER(vsnes_state,vsnes) { - m_last_bank = 0xff; - m_sound_fix = 0; m_input_latch[0] = m_input_latch[1] = 0; m_input_latch[2] = m_input_latch[3] = 0; - -} - -/************************************* - * - * Init machine - * - *************************************/ - -MACHINE_RESET_MEMBER(vsnes_state,vsdual) -{ - m_input_latch[0] = m_input_latch[1] = 0; - m_input_latch[2] = m_input_latch[3] = 0; - + m_input_strobe[0] = m_input_strobe[1] = 0; } /************************************* @@ -163,8 +131,6 @@ MACHINE_RESET_MEMBER(vsnes_state,vsdual) void vsnes_state::v_set_videorom_bank(int start, int count, int vrom_start_bank) { - int i; - assert(start + count <= 8); vrom_start_bank &= (m_vrom_banks - 1); @@ -172,7 +138,7 @@ void vsnes_state::v_set_videorom_bank(int start, int count, int vrom_start_bank) /* bank_size_in_kb is used to determine how large the "bank" parameter is */ /* count determines the size of the area mapped */ - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { m_chr_banks[i + start]->set_entry(vrom_start_bank + i); } @@ -181,7 +147,6 @@ void vsnes_state::v_set_videorom_bank(int start, int count, int vrom_start_bank) MACHINE_START_MEMBER(vsnes_state,vsnes) { address_space &ppu1_space = m_ppu1->space(AS_PROGRAM); - int i; /* establish nametable ram */ m_nt_ram[0] = std::make_unique(0x1000); @@ -207,7 +172,7 @@ MACHINE_START_MEMBER(vsnes_state,vsnes) /* DRIVER_INIT is called first - means we can handle this different for VRAM games! */ if (m_vrom[0] != nullptr) { - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { ppu1_space.install_read_bank(0x0400 * i, 0x0400 * i + 0x03ff, m_chr_banks[i]); m_chr_banks[i]->configure_entries(0, m_vrom_banks, m_vrom[0], 0x400); @@ -305,7 +270,7 @@ void vsnes_state::gun_in0_w(uint8_t data) } /* here we do things a little different */ - if (data & 1) + if (m_input_strobe[0] & ~data & 1) { /* load up the latches */ m_input_latch[0] = ioport("IN0")->read(); @@ -361,19 +326,13 @@ void vsnes_state::gun_in0_w(uint8_t data) m_input_latch[1] = ioport("IN1")->read(); } - if ((m_zapstore & 1) && (!(data & 1))) - /* reset sound_fix to keep sound from hanging */ - { - m_sound_fix = 0; - } - - m_zapstore = data; + m_input_strobe[0] = data; } void vsnes_state::init_vsgun() { /* VROM switching is enabled with bit 2 of $4016 */ - m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x4016, 0x4016, read8smo_delegate(*this, FUNC(vsnes_state::gun_in0_r)), write8smo_delegate(*this, FUNC(vsnes_state::gun_in0_w))); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x4016, 0x4016, write8smo_delegate(*this, FUNC(vsnes_state::gun_in0_w))); m_do_vrom_bank = 1; } @@ -441,7 +400,7 @@ void vsnes_state::init_vsgshoe() memcpy (&prg[0x08000], &prg[0x12000], 0x2000); /* vrom switching is enabled with bit 2 of $4016 */ - m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x4016, 0x4016, read8smo_delegate(*this, FUNC(vsnes_state::gun_in0_r)), write8smo_delegate(*this, FUNC(vsnes_state::vsgshoe_gun_in0_w))); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x4016, 0x4016, write8smo_delegate(*this, FUNC(vsnes_state::vsgshoe_gun_in0_w))); m_do_vrom_bank = 1; } @@ -629,11 +588,6 @@ void vsnes_state::init_vs108() // 108 chip at $8000-$9fff m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8sm_delegate(*this, FUNC(vsnes_state::vs108_rom_banking))); - - // extra ram at $6000-$7fff - m_extraram = std::make_unique(0x2000); - save_pointer(NAME(m_extraram.get()), 0x2000); - m_maincpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff, m_extraram.get()); } /* Vs. RBI Baseball */ @@ -760,7 +714,7 @@ void vsnes_state::init_vsfdf() { init_vs108(); - m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x4016, 0x4016, read8smo_delegate(*this, FUNC(vsnes_state::gun_in0_r)), write8smo_delegate(*this, FUNC(vsnes_state::gun_in0_w))); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x4016, 0x4016, write8smo_delegate(*this, FUNC(vsnes_state::gun_in0_w))); m_do_vrom_bank = 0; } @@ -768,28 +722,18 @@ void vsnes_state::init_vsfdf() /**********************************************************************************/ /* Platoon rom banking */ -void vsnes_state::mapper68_rom_banking(offs_t offset, uint8_t data) +void vsnes_state::sunsoft3_rom_banking(offs_t offset, uint8_t data) { - switch (offset & 0x7000) + switch (offset & 0x7800) { - case 0x0000: - v_set_videorom_bank(0, 2, data * 2); - - break; - case 0x1000: - v_set_videorom_bank(2, 2, data * 2); - - break; - case 0x2000: - v_set_videorom_bank(4, 2, data * 2); - - break; - case 0x3000: /* ok? */ - v_set_videorom_bank(6, 2, data * 2); - + case 0x0800: + case 0x1800: + case 0x2800: + case 0x3800: + v_set_videorom_bank((offset >> 11) & 0x06, 2, data * 2); break; - case 0x7000: + case 0x7800: { uint8_t *prg = memregion("maincpu")->base(); memcpy(&prg[0x08000], &prg[0x10000 + data * 0x4000], 0x4000); @@ -802,14 +746,14 @@ void vsnes_state::mapper68_rom_banking(offs_t offset, uint8_t data) void vsnes_state::init_platoon() { - /* when starting a mapper 68 game the first 16K ROM bank in the cart is loaded into $8000 + /* when starting a mapper 67 game the first 16K ROM bank in the cart is loaded into $8000 the LAST 16K ROM bank is loaded into $C000. The last 16K of ROM cannot be swapped. */ uint8_t *prg = memregion("maincpu")->base(); memcpy(&prg[0x08000], &prg[0x10000], 0x4000); memcpy(&prg[0x0c000], &prg[0x2c000], 0x4000); - m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8sm_delegate(*this, FUNC(vsnes_state::mapper68_rom_banking))); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xffff, write8sm_delegate(*this, FUNC(vsnes_state::sunsoft3_rom_banking))); } /**********************************************************************************/ @@ -832,11 +776,6 @@ void vsnes_state::init_bnglngby() { m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0231, 0x0231, read8smo_delegate(*this, FUNC(vsnes_state::set_bnglngby_irq_r)), write8smo_delegate(*this, FUNC(vsnes_state::set_bnglngby_irq_w))); - /* extra ram */ - m_extraram = std::make_unique(0x2000); - save_pointer(NAME(m_extraram.get()), 0x2000); - m_maincpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff, m_extraram.get()); - m_ret = 0; /* normal banking */ @@ -872,15 +811,9 @@ void vsnes_state::vsdual_vrom_banking_sub(uint8_t data) void vsnes_state::init_vsdual() { - uint8_t *prg = memregion("maincpu")->base(); - /* vrom switching is enabled with bit 2 of $4016 */ m_maincpu->space(AS_PROGRAM).install_write_handler(0x4016, 0x4016, write8smo_delegate(*this, FUNC(vsnes_state::vsdual_vrom_banking_main))); m_subcpu->space(AS_PROGRAM).install_write_handler(0x4016, 0x4016, write8smo_delegate(*this, FUNC(vsnes_state::vsdual_vrom_banking_sub))); - - /* shared ram at $6000 */ - m_maincpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff, &prg[0x6000]); - m_subcpu->space(AS_PROGRAM).install_ram(0x6000, 0x7fff, &prg[0x6000]); } /**********************************************************************************/