diff options
author | Fabio Priuli <etabeta78@users.noreply.github.com> | 2013-04-07 09:32:02 +0000 |
---|---|---|
committer | Fabio Priuli <etabeta78@users.noreply.github.com> | 2013-04-07 09:32:02 +0000 |
commit | 0595f70aa312e91e311a18ff35c534227876869a (patch) | |
tree | 3ed7782807814f1f8cf087bfa05bf92fcbe9a9f7 | |
parent | 38716f6a64cafd134ac61170cf6c4f6b19d38a48 (diff) |
(MESS) snes.c: added support for the PowerFest '94 competition cart. [Fabio Priuli]
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | hash/snes.xml | 12 | ||||
-rw-r--r-- | src/mess/drivers/snes.c | 100 | ||||
-rw-r--r-- | src/mess/machine/sns_event.c | 288 | ||||
-rw-r--r-- | src/mess/machine/sns_event.h | 55 | ||||
-rw-r--r-- | src/mess/machine/sns_slot.c | 2 | ||||
-rw-r--r-- | src/mess/machine/sns_slot.h | 1 | ||||
-rw-r--r-- | src/mess/mess.mak | 1 |
8 files changed, 453 insertions, 8 deletions
diff --git a/.gitattributes b/.gitattributes index 24994604f35..9fec2ec6402 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7509,6 +7509,8 @@ src/mess/machine/snescx4.c svneol=native#text/plain src/mess/machine/snescx4.h svneol=native#text/plain src/mess/machine/sns_bsx.c svneol=native#text/plain src/mess/machine/sns_bsx.h svneol=native#text/plain +src/mess/machine/sns_event.c svneol=native#text/plain +src/mess/machine/sns_event.h svneol=native#text/plain src/mess/machine/sns_rom.c svneol=native#text/plain src/mess/machine/sns_rom.h svneol=native#text/plain src/mess/machine/sns_rom21.c svneol=native#text/plain diff --git a/hash/snes.xml b/hash/snes.xml index dba40ba6d98..69e8f808526 100644 --- a/hash/snes.xml +++ b/hash/snes.xml @@ -4511,7 +4511,7 @@ Known bad dumps, redump needed </part> </software> - <software name="powerf94" supported="no"> <!-- unemulated additional hardware (EVENT) --> + <software name="pfest94"> <!-- Notes: contains corrupt data --> <description>Nintendo PowerFest 94 (USA, Not for sale)</description> <year>1994</year> @@ -4538,13 +4538,13 @@ Known bad dumps, redump needed <feature name="u16" value="" /> <!-- DSP --> <feature name="lockout" value="D411A" /> <feature name="dipswitch" value="S1" /> <!-- (....'...) --> - <feature name="slot" value="lorom" /> + <feature name="slot" value="pfest94" /> <dataarea name="rom" size="2359296"> - <rom name="m-cart pwr-fst 94.u7" size="524288" crc="9974b593" sha1="1c53c806d0dd5bad4b8b9337c0051ddaa0d3355f" offset="0x000000" status="baddump" /> - <rom name="griff jr power fest 94.u8" size="1048576" crc="c7b5e8c6" sha1="092a7146c8204019e1b760fd70e422d32cd11b70" offset="0x080000" status="baddump" /> - <rom name="mario-lost pwr-fst 94.u9" size="524288" crc="38be3e18" sha1="072bb7de400b16a811b9066b5d5813600be3d9c0" offset="0x180000" status="baddump" /> <!-- the following label is handwritten, could got it wrong --> - <rom name="i m pts - hr 11-2-94.u10" size="262144" crc="143a1c2f" sha1="523ffc9f3e78f5f26fa003a906b26609dec33dd6" offset="0x200000" status="baddump" /> + <rom name="i m pts - hr 11-2-94.u10" size="262144" crc="143a1c2f" sha1="523ffc9f3e78f5f26fa003a906b26609dec33dd6" offset="0x000000" status="baddump" /> + <rom name="mario-lost pwr-fst 94.u9" size="524288" crc="38be3e18" sha1="072bb7de400b16a811b9066b5d5813600be3d9c0" offset="0x040000" status="baddump" /> + <rom name="m-cart pwr-fst 94.u7" size="524288" crc="9974b593" sha1="1c53c806d0dd5bad4b8b9337c0051ddaa0d3355f" offset="0x0c0000" status="baddump" /> + <rom name="griff jr power fest 94.u8" size="1048576" crc="c7b5e8c6" sha1="092a7146c8204019e1b760fd70e422d32cd11b70" offset="0x140000" status="baddump" /> </dataarea> <dataarea name="addon" size="10240"> <rom name="dsp1.bin" size="10240" crc="2838f9f5" sha1="0a03ccb1fd2bea91151c745a4d1f217ae784f889" offset="0x000000" /> diff --git a/src/mess/drivers/snes.c b/src/mess/drivers/snes.c index 4d5d4b78422..d7e0c4a0e26 100644 --- a/src/mess/drivers/snes.c +++ b/src/mess/drivers/snes.c @@ -42,6 +42,7 @@ #include "machine/sns_spc7110.h" #include "machine/sns_sufami.h" #include "machine/sns_upd.h" +#include "machine/sns_event.h" class snes_console_state : public snes_state @@ -76,7 +77,11 @@ public: DECLARE_WRITE8_MEMBER( snesbsx_hi_w ); DECLARE_READ8_MEMBER( snesbsx_lo_r ); DECLARE_WRITE8_MEMBER( snesbsx_lo_w ); - + DECLARE_READ8_MEMBER( pfest94_hi_r ); + DECLARE_WRITE8_MEMBER( pfest94_hi_w ); + DECLARE_READ8_MEMBER( pfest94_lo_r ); + DECLARE_WRITE8_MEMBER( pfest94_lo_w ); + DECLARE_READ8_MEMBER( spc_ram_100_r ); DECLARE_WRITE8_MEMBER( spc_ram_100_w ); CUSTOM_INPUT_MEMBER( snes_mouse_speed_input ); @@ -767,6 +772,91 @@ WRITE8_MEMBER( snes_console_state::snesbsx_lo_w ) } +//--------------------------------------------------------------------------------- +// Powerfest '94 event cart +//--------------------------------------------------------------------------------- + +READ8_MEMBER( snes_console_state::pfest94_hi_r ) +{ + UINT16 address = offset & 0xffff; + + if (offset < 0x400000) + { + if (address < 0x2000) + return space.read_byte(0x7e0000 + address); + else if (address < 0x6000) + return snes_r_io(space, address); + else if (address < 0x8000) + { + if (offset < 0x100000) // DSP access + return m_cartslot->chip_read(space, offset); + else if (offset == 0x106000) // menu access + return m_cartslot->chip_read(space, offset + 0x8000); + else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access + return m_cartslot->read_ram(space, offset); + else + return snes_open_bus_r(space, 0); + } + else + return m_cartslot->read_h(space, offset); + } + return m_cartslot->read_h(space, offset); +} + +WRITE8_MEMBER( snes_console_state::pfest94_hi_w ) +{ + UINT16 address = offset & 0xffff; + if (offset < 0x400000) + { + if (address < 0x2000) + space.write_byte(0x7e0000 + address, data); + else if (address < 0x6000) + snes_w_io(space, address, data); + else if (address < 0x8000) + { + if (offset < 0x100000) // DSP access + m_cartslot->chip_write(space, offset, data); + else if (offset == 0x206000) // menu access + m_cartslot->chip_write(space, offset + 0x8000, data); + else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access + m_cartslot->write_ram(space, offset, data); + } + } +} + +READ8_MEMBER( snes_console_state::pfest94_lo_r ) +{ + UINT16 address = offset & 0xffff; + + if (offset < 0x400000) + { + if (address < 0x2000) + return space.read_byte(0x7e0000 + address); + else if (address < 0x6000) + return snes_r_io(space, address); + else if (address < 0x8000) + { + if (offset < 0x100000) // DSP access + return m_cartslot->chip_read(space, offset); + else if (offset == 0x106000) // menu access + return m_cartslot->chip_read(space, offset + 0x8000); + else if (offset >= 0x300000 && m_cartslot->m_cart->get_nvram_size()) // NVRAM access + return m_cartslot->read_ram(space, offset); + else + return snes_open_bus_r(space, 0); + } + else + return m_cartslot->read_l(space, offset); + } + return 0xff; // or open_bus? +} + +WRITE8_MEMBER( snes_console_state::pfest94_lo_w ) +{ + pfest94_hi_w(space, offset, data, 0xff); +} + + /************************************* * * Address maps @@ -1386,6 +1476,7 @@ static SLOT_INTERFACE_START(snes_cart) SLOT_INTERFACE_INTERNAL("hirom_spcrtc", SNS_HIROM_SPC7110_RTC) SLOT_INTERFACE_INTERNAL("hirom_srtc", SNS_HIROM_SRTC) SLOT_INTERFACE_INTERNAL("bsxrom", SNS_ROM_BSX) // BS-X base cart - partial support only + SLOT_INTERFACE_INTERNAL("pfest94", SNS_PFEST94) // pirate carts SLOT_INTERFACE_INTERNAL("lorom_poke", SNS_LOROM_POKEMON) SLOT_INTERFACE_INTERNAL("lorom_tekken2", SNS_LOROM_TEKKEN2) @@ -1485,7 +1576,12 @@ static MACHINE_START( snes_console ) machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snes_console_state::snes7110_hi_r),state), write8_delegate(FUNC(snes_console_state::snes7110_hi_w),state)); set_5a22_map(*state->m_maincpu); break; - // pirate 'mappers' + case SNES_PFEST94: + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snes_console_state::pfest94_lo_r),state), write8_delegate(FUNC(snes_console_state::pfest94_lo_w),state)); + machine.device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snes_console_state::pfest94_hi_r),state), write8_delegate(FUNC(snes_console_state::pfest94_hi_w),state)); + set_5a22_map(*state->m_maincpu); + break; + // pirate 'mappers' case SNES_POKEMON: machine.device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x800000, 0x80ffff, 0, 0x780000, read8_delegate(FUNC(base_sns_cart_slot_device::chip_read),(base_sns_cart_slot_device*)state->m_cartslot)); machine.device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x800000, 0x80ffff, 0, 0x780000, write8_delegate(FUNC(base_sns_cart_slot_device::chip_write),(base_sns_cart_slot_device*)state->m_cartslot)); diff --git a/src/mess/machine/sns_event.c b/src/mess/machine/sns_event.c new file mode 100644 index 00000000000..862fe6d1a4d --- /dev/null +++ b/src/mess/machine/sns_event.c @@ -0,0 +1,288 @@ +/*********************************************************************************************************** + + Super NES/Famicom Event cartridges emulation (for SNES/SFC) + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + + TODO: figure out how the Test Mode switch works... + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "machine/sns_event.h" + + +//------------------------------------------------- +// sns_rom_device - constructor +//------------------------------------------------- + +const device_type SNS_PFEST94 = &device_creator<sns_pfest94_device>; + + +sns_pfest94_device::sns_pfest94_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, SNS_PFEST94, "SNES Powerfest '94", tag, owner, clock, "sns_pfest94", __FILE__), + device_sns_cart_interface( mconfig, *this ), + m_upd7725(*this, "dsp"), + m_dsw(*this, "DIPSW") +{ +} + + +void sns_pfest94_device::device_start() +{ + m_dsp_prg = auto_alloc_array(machine(), UINT32, 0x2000/4); + m_dsp_data = auto_alloc_array(machine(), UINT16, 0x800/2); + pfest94_timer = timer_alloc(TIMER_EVENT); + pfest94_timer->reset(); + + save_item(NAME(m_base_bank)); + save_item(NAME(m_mask)); + save_item(NAME(m_status)); + save_item(NAME(m_count)); +} + +void sns_pfest94_device::device_reset() +{ + m_base_bank = 0; + m_mask = 0x07; + m_status = 0; + m_count = 0; +} + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +READ8_MEMBER(sns_pfest94_device::read_l) +{ + // menu + if ((offset & 0x208000) == 0x208000) + { + int bank = ((offset - 0x200000) / 0x10000) & 7; + return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)]; + } + else + { + // never called beyond 0x400000! + offset &= 0x1fffff; + int bank = (m_base_bank == 0x18) ? offset / 0x8000 : offset / 0x10000; + return m_rom[rom_bank_map[m_base_bank + (bank & m_mask)] * 0x8000 + (offset & 0x7fff)]; + } +} + +READ8_MEMBER(sns_pfest94_device::read_h) +{ + // menu + if ((offset & 0x208000) == 0x208000) + { + int bank = ((offset - 0x200000) / 0x8000) & 7; + return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)]; + } + + // called beyond 0x400000! + if (offset < 0x400000) + { + offset &= 0x1fffff; + int bank = (m_base_bank == 0x18) ? offset / 0x8000 : offset / 0x10000; + return m_rom[rom_bank_map[m_base_bank + (bank & m_mask)] * 0x8000 + (offset & 0x7fff)]; + } + else + { + offset &= 0x3fffff; + int bank = offset / 0x8000; + return m_rom[rom_bank_map[m_base_bank + (bank & m_mask)] * 0x8000 + (offset & 0x7fff)]; + } +} + + +// these are used for two diff effects: both to select game from menu and to access the DSP when running SMK! +READ8_MEMBER( sns_pfest94_device::chip_read ) +{ + if (offset & 0x8000) + { + // menu access + return m_status; + } + else + { + // DSP access + offset &= 0x1fff; + return m_upd7725->snesdsp_read(offset < 0x1000); + } +} + + +WRITE8_MEMBER( sns_pfest94_device::chip_write ) +{ + if (offset & 0x8000) + { + // menu access + if (data == 0x00) + { + m_base_bank = 0; + m_mask = 0x07; + } + if (data == 0x09) + { + m_base_bank = 0x08; + m_mask = 0x0f; + // start timer + m_count = (3 + ((m_dsw->read() & 0xf0) >> 4)) * 60; + pfest94_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); + } + if (data == 0x0c) + { + m_base_bank = 0x18; + m_mask = 0x0f; + } + if (data == 0x0a) + { + m_base_bank = 0x28; + m_mask = 0x1f; + } + } + else + { + // DSP access + offset &= 0x1fff; + m_upd7725->snesdsp_write(offset < 0x1000, data); + } +} + + +//------------------------------------------------- +// NEC DSP +//------------------------------------------------- + +// helpers +inline UINT32 get_prg(UINT8 *CPU, UINT32 addr) +{ + return ((CPU[addr * 4] << 24) | (CPU[addr * 4 + 1] << 16) | (CPU[addr * 4 + 2] << 8) | 0x00); +} +inline UINT16 get_data(UINT8 *CPU, UINT32 addr) +{ + return ((CPU[addr * 2] << 8) | CPU[addr * 2 + 1]); +} + +void sns_pfest94_device::speedup_addon_bios_access() +{ + m_upd7725->space(AS_PROGRAM).install_read_bank(0x0000, 0x07ff, "dsp_prg"); + m_upd7725->space(AS_DATA).install_read_bank(0x0000, 0x03ff, "dsp_data"); + membank("dsp_prg")->set_base(m_dsp_prg); + membank("dsp_data")->set_base(m_dsp_data); + // copy data in the correct format + for (int x = 0; x < 0x800; x++) + m_dsp_prg[x] = (m_bios[x * 4] << 24) | (m_bios[x * 4 + 1] << 16) | (m_bios[x * 4 + 2] << 8) | 0x00; + for (int x = 0; x < 0x400; x++) + m_dsp_data[x] = (m_bios[0x2000 + x * 2] << 8) | m_bios[0x2000 + x * 2 + 1]; +} + + +// DSP dump contains prg at offset 0 and data at offset 0x2000 +READ32_MEMBER( sns_pfest94_device::necdsp_prg_r ) +{ + return get_prg(m_bios, offset); +} + +READ16_MEMBER( sns_pfest94_device::necdsp_data_r ) +{ + return get_data(m_bios, offset + 0x2000/2); +} + + +//------------------------------------------------- +// ADDRESS_MAP( dsp_prg_map ) +//------------------------------------------------- + +static ADDRESS_MAP_START( dsp_prg_map_lorom, AS_PROGRAM, 32, sns_pfest94_device ) + AM_RANGE(0x0000, 0x07ff) AM_READ(necdsp_prg_r) +ADDRESS_MAP_END + + +//------------------------------------------------- +// ADDRESS_MAP( dsp_data_map ) +//------------------------------------------------- + +static ADDRESS_MAP_START( dsp_data_map_lorom, AS_DATA, 16, sns_pfest94_device ) + AM_RANGE(0x0000, 0x03ff) AM_READ(necdsp_data_r) +ADDRESS_MAP_END + + +//------------------------------------------------- +// MACHINE_DRIVER( snes_dsp ) +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( snes_dsp_pfest94 ) + MCFG_CPU_ADD("dsp", UPD7725, 8000000) + MCFG_CPU_PROGRAM_MAP(dsp_prg_map_lorom) + MCFG_CPU_DATA_MAP(dsp_data_map_lorom) +MACHINE_CONFIG_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor sns_pfest94_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( snes_dsp_pfest94 ); +} + +//------------------------------------------------- +// Dipswicth +//------------------------------------------------- + +static INPUT_PORTS_START( pfest94_dsw ) + PORT_START("DIPSW") + PORT_DIPUNUSED(0x03, 0x00) + PORT_DIPNAME( 0x04, 0x00, "Test Mode" ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x04, DEF_STR( On ) ) + PORT_DIPUNUSED(0x08, 0x08) + PORT_DIPNAME( 0xf0, 0x30, "Timer" ) + PORT_DIPSETTING( 0x00, "3 Minutes" ) + PORT_DIPSETTING( 0x10, "4 Minutes" ) + PORT_DIPSETTING( 0x20, "5 Minutes" ) + PORT_DIPSETTING( 0x30, "6 Minutes" ) + PORT_DIPSETTING( 0x40, "7 Minutes" ) + PORT_DIPSETTING( 0x50, "8 Minutes" ) + PORT_DIPSETTING( 0x60, "9 Minutes" ) + PORT_DIPSETTING( 0x70, "10 Minutes" ) + PORT_DIPSETTING( 0x80, "11 Minutes" ) + PORT_DIPSETTING( 0x90, "12 Minutes" ) + PORT_DIPSETTING( 0xa0, "13 Minutes" ) + PORT_DIPSETTING( 0xb0, "14 Minutes" ) + PORT_DIPSETTING( 0xc0, "15 Minutes" ) + PORT_DIPSETTING( 0xd0, "16 Minutes" ) + PORT_DIPSETTING( 0xe0, "17 Minutes" ) + PORT_DIPSETTING( 0xf0, "18 Minutes" ) +INPUT_PORTS_END + + +ioport_constructor sns_pfest94_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( pfest94_dsw ); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void sns_pfest94_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (id == TIMER_EVENT) + { + if (!m_count) + { + m_status |= 2; + pfest94_timer->reset(); + } + m_count--; + } +} + + diff --git a/src/mess/machine/sns_event.h b/src/mess/machine/sns_event.h new file mode 100644 index 00000000000..12a1e050f4b --- /dev/null +++ b/src/mess/machine/sns_event.h @@ -0,0 +1,55 @@ +#ifndef __SNS_EVENT_H +#define __SNS_EVENT_H + +#include "machine/sns_slot.h" +#include "cpu/upd7725/upd7725.h" + + +// ======================> sns_pfest94_device + +class sns_pfest94_device : public device_t, + public device_sns_cart_interface +{ +public: + // construction/destruction + sns_pfest94_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + virtual machine_config_constructor device_mconfig_additions() const; + virtual ioport_constructor device_input_ports() const; + + required_device<upd7725_device> m_upd7725; + required_ioport m_dsw; + + virtual void speedup_addon_bios_access(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read_l); + virtual DECLARE_READ8_MEMBER(read_h); + virtual DECLARE_READ8_MEMBER(chip_read); + virtual DECLARE_WRITE8_MEMBER(chip_write); + + virtual DECLARE_READ32_MEMBER(necdsp_prg_r); + virtual DECLARE_READ16_MEMBER(necdsp_data_r); + +private: + UINT8 m_base_bank; + UINT8 m_mask; + UINT8 m_status; + UINT32 m_count; + + UINT32 *m_dsp_prg; + UINT16 *m_dsp_data; + + static const device_timer_id TIMER_EVENT = 0; + emu_timer *pfest94_timer; +}; + + +// device type definition +extern const device_type SNS_PFEST94; + +#endif diff --git a/src/mess/machine/sns_slot.c b/src/mess/machine/sns_slot.c index 433d5ac7d7a..572286e9ef9 100644 --- a/src/mess/machine/sns_slot.c +++ b/src/mess/machine/sns_slot.c @@ -281,6 +281,8 @@ static const sns_slot slot_list[] = { SNES_BSMEMPAK, "bsmempak"}, // Sufami Turbo carts { SNES_STROM, "strom"}, + // Event carts + { SNES_PFEST94, "pfest94" }, // pirate carts { SNES_POKEMON, "lorom_poke"}, { SNES_TEKKEN2, "lorom_tekken2"}, diff --git a/src/mess/machine/sns_slot.h b/src/mess/machine/sns_slot.h index ad76d1d4ced..0b3ade34b5a 100644 --- a/src/mess/machine/sns_slot.h +++ b/src/mess/machine/sns_slot.h @@ -41,6 +41,7 @@ enum SNES_ST011, SNES_ST018, SNES_Z80GB, + SNES_PFEST94, SNES_BSX, SNES_BSXLO, SNES_BSXHI, diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 9865032315e..aefe96d0fcd 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -1415,6 +1415,7 @@ $(MESSOBJ)/nintendo.a: \ $(MESS_MACHINE)/sns_spc7110.o \ $(MESS_MACHINE)/sns_sufami.o\ $(MESS_MACHINE)/sns_upd.o \ + $(MESS_MACHINE)/sns_event.o \ $(MESS_DRIVERS)/snes.o \ $(MESS_DRIVERS)/n64.o \ $(MESS_AUDIO)/gb.o \ |