summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/snesb51.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/snesb51.cpp')
-rw-r--r--src/mame/drivers/snesb51.cpp146
1 files changed, 139 insertions, 7 deletions
diff --git a/src/mame/drivers/snesb51.cpp b/src/mame/drivers/snesb51.cpp
index bbaf3278d97..1dcc6277883 100644
--- a/src/mame/drivers/snesb51.cpp
+++ b/src/mame/drivers/snesb51.cpp
@@ -7,6 +7,7 @@
Skeleton driver
The following systems are dumped:
+ - Fatal Fury Special
- Mortal Kombat 3
- 4 Slot board (two different BIOS versions)
- 4 Slot board with built-in NBA Jam
@@ -52,24 +53,37 @@
6 -
* Note - P5 ribbon to SNES controls 7 - GND
+ Dumper's notes for MK3:
+ "Ok can confirm with this style the MCU provides an overlay similar to the "NBA jam 4 slot" snes bootlegs.
+ I have an onscreen insert coin display from the MCU but the underlying snes hardware is dead so actual game is not running."
+
+ TODO: complete MCU hookup
***************************************************************************/
#include "emu.h"
+#include "includes/snes.h"
#include "cpu/mcs51/mcs51.h"
#include "emupal.h"
+#include "speaker.h"
+
-class snesb51_state : public driver_device
+namespace {
+
+class snesb51_state : public snes_state
{
public:
snesb51_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
+ snes_state(mconfig, type, tag),
m_mcu(*this, "mcu")
{ }
+ void base(machine_config &config);
void mk3snes(machine_config &config);
void snes4sl(machine_config &config);
void snes4sln(machine_config &config);
+ void init_fatfurspb();
+
protected:
void machine_start() override;
@@ -78,6 +92,8 @@ private:
void mem_map(address_map &map);
void io_map(address_map &map);
+ void snes_map(address_map &map);
+ void spc_map(address_map &map);
void mcu_p1_w(uint8_t data);
uint8_t mcu_p3_r();
@@ -91,6 +107,18 @@ private:
uint16_t m_ram_address;
};
+void snesb51_state::snes_map(address_map &map)
+{
+ map(0x000000, 0x7dffff).rw(FUNC(snesb51_state::snes_r_bank1), FUNC(snesb51_state::snes_w_bank1));
+ map(0x7e0000, 0x7fffff).ram().share(m_wram); // 8KB Low RAM, 24KB High RAM, 96KB Expanded RAM
+ map(0x800000, 0xffffff).rw(FUNC(snesb51_state::snes_r_bank2), FUNC(snesb51_state::snes_w_bank2)); // Mirror and ROM
+}
+
+void snesb51_state::spc_map(address_map &map)
+{
+ map(0x0000, 0xffff).ram().share("aram");
+}
+
void snesb51_state::mem_map(address_map &map)
{
map(0x0000, 0x7fff).rom().region("mcu", 0);
@@ -112,6 +140,41 @@ void snesb51_state::io_map(address_map &map)
}
static INPUT_PORTS_START( mk3snes )
+ PORT_START("SERIAL1_DATA1")
+ PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Button B") PORT_PLAYER(1)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P1 Button Y") PORT_PLAYER(1)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("P1 Start")
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Button A") PORT_PLAYER(1)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P1 Button X") PORT_PLAYER(1)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P1 Button L") PORT_PLAYER(1)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Button R") PORT_PLAYER(1)
+ PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("SERIAL2_DATA1")
+ PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Button B") PORT_PLAYER(2)
+ PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P2 Button Y") PORT_PLAYER(2)
+ PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P2 Start")
+ PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
+ PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
+ PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
+ PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Button A") PORT_PLAYER(2)
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("P2 Button X") PORT_PLAYER(2)
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("P2 Button L") PORT_PLAYER(2)
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Button R") PORT_PLAYER(2)
+ PORT_BIT( 0x000f, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("SERIAL1_DATA2")
+ PORT_BIT( 0xffff, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("SERIAL2_DATA2")
+ PORT_BIT( 0xffff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( snes4sl )
@@ -178,10 +241,47 @@ void snesb51_state::machine_start()
{
m_ram = std::make_unique<uint8_t[]>(0x2000);
save_pointer(NAME(m_ram), 0x2000);
+
+ snes_state::machine_start();
+}
+
+void snesb51_state::base(machine_config &config)
+{
+ // basic machine hardware
+ _5A22(config, m_maincpu, 3580000 * 6);
+ m_maincpu->set_addrmap(AS_PROGRAM, &snesb51_state::snes_map);
+
+ S_SMP(config, m_soundcpu, XTAL(24'576'000) / 12);
+ m_soundcpu->set_addrmap(AS_DATA, &snesb51_state::spc_map);
+ m_soundcpu->dsp_io_read_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_r));
+ m_soundcpu->dsp_io_write_callback().set(m_s_dsp, FUNC(s_dsp_device::dsp_io_w));
+
+ config.set_perfect_quantum(m_maincpu);
+
+ // video hardware
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_raw(DOTCLK_NTSC * 2, SNES_HTOTAL * 2, 0, SNES_SCR_WIDTH * 2, SNES_VTOTAL_NTSC, 0, SNES_SCR_HEIGHT_NTSC);
+ m_screen->set_video_attributes(VIDEO_VARIABLE_WIDTH);
+ m_screen->set_screen_update(FUNC(snes_state::screen_update));
+
+ SNES_PPU(config, m_ppu, MCLK_NTSC);
+ m_ppu->open_bus_callback().set([this] { return snes_open_bus_r(); });
+ m_ppu->set_screen("screen");
+
+ // sound hardware
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ S_DSP(config, m_s_dsp, XTAL(24'576'000) / 12);
+ m_s_dsp->set_addrmap(0, &snesb51_state::spc_map);
+ m_s_dsp->add_route(0, "lspeaker", 1.00);
+ m_s_dsp->add_route(1, "rspeaker", 1.00);
}
void snesb51_state::mk3snes(machine_config &config)
{
+ base(config);
+
I8751(config, m_mcu, 12_MHz_XTAL);
m_mcu->set_addrmap(AS_IO, &snesb51_state::io_map);
m_mcu->port_out_cb<1>().set(FUNC(snesb51_state::mcu_p1_w));
@@ -191,6 +291,8 @@ void snesb51_state::mk3snes(machine_config &config)
void snesb51_state::snes4sl(machine_config &config)
{
+ base(config);
+
// exact type unknown
I8031(config, m_mcu, 12_MHz_XTAL);
m_mcu->set_addrmap(AS_PROGRAM, &snesb51_state::mem_map);
@@ -206,6 +308,8 @@ void snesb51_state::snes4sl(machine_config &config)
void snesb51_state::snes4sln(machine_config &config)
{
+ base(config);
+
I8051(config, m_mcu, 12_MHz_XTAL); // SAB 8051A-P
m_mcu->set_addrmap(AS_PROGRAM, &snesb51_state::mem_map);
m_mcu->set_addrmap(AS_IO, &snesb51_state::io_map);
@@ -216,7 +320,7 @@ void snesb51_state::snes4sln(machine_config &config)
// This is identical to the SNES release apart from a single byte
ROM_START( mk3snes )
- ROM_REGION(0x400000, "game", 0)
+ ROM_REGION(0x400000, "user3", 0)
ROM_LOAD("5.u5", 0x000000, 0x080000, CRC(c21ee1ac) SHA1(12fc526e39b0b998b39d558fbe5660e72c7fad14))
ROM_LOAD("6.u6", 0x080000, 0x080000, CRC(0e064323) SHA1(a11175516892beb862c7cc1e186034ef1b55ee8f))
ROM_LOAD("7.u7", 0x100000, 0x080000, CRC(7db6b7be) SHA1(a7653c04f5321fd83062425a492c7ed0a4f1fdb0))
@@ -256,7 +360,35 @@ ROM_START( snes4sln )
ROM_LOAD("5.bin", 0x0000, 0x8000, CRC(af8a64e3) SHA1(f13187d213fe7c2a0edcb88d4e828bd24112e812))
ROM_END
-// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS
-GAME( 199?, mk3snes, 0, mk3snes, mk3snes, snesb51_state, empty_init, ROT0, "bootleg", "Mortal Kombat 3 (SNES bootleg)", MACHINE_IS_SKELETON )
-GAME( 1993, snes4sl, 0, snes4sl, snes4sl, snesb51_state, empty_init, ROT0, "bootleg", "SNES 4 Slot arcade switcher", MACHINE_IS_SKELETON )
-GAME( 1994, snes4sln, 0, snes4sln, snes4sl, snesb51_state, empty_init, ROT0, "bootleg", "SNES 4 Slot arcade switcher (NBA Jam)", MACHINE_IS_SKELETON )
+ROM_START( fatfurspb )
+ ROM_REGION( 0x400000, "user3", 0 )
+ ROM_LOAD("1.u14", 0x000000, 0x100000, CRC(7cb9192c) SHA1(0247e303902e86eaa9443f2a39d352430df5f46f))
+ ROM_LOAD("2.u15", 0x100000, 0x100000, CRC(440e3017) SHA1(7d1a2077032c761676bff7f841ab1fc669d322fa))
+ ROM_LOAD("3.u16", 0x200000, 0x100000, CRC(dbbe10de) SHA1(27c590bff5a762a2528d0819b7544914ab6cae7c))
+ ROM_LOAD("4.u17", 0x300000, 0x100000, CRC(a356e60c) SHA1(c403eff4e7c7deefed68a34a0dbeefadac8c7a0e))
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD("d87c51.u9", 0x0000, 0x1000, NO_DUMP)
+ROM_END
+
+
+void snesb51_state::init_fatfurspb()
+{
+ uint8_t *rom = memregion("user3")->base();
+
+ for (uint32_t i = 0; i < 0x400000; i++)
+ {
+ rom[i] = bitswap<8>(rom[i], 5, 0, 6, 1, 7, 4, 3, 2);
+ }
+
+ init_snes_hirom();
+}
+
+} // anonymous namespace
+
+
+// YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS
+GAME( 199?, mk3snes, 0, mk3snes, mk3snes, snesb51_state, init_snes_hirom, ROT0, "bootleg", "Mortal Kombat 3 (SNES bootleg)", MACHINE_IS_SKELETON )
+GAME( 1993, snes4sl, 0, snes4sl, snes4sl, snesb51_state, empty_init, ROT0, "bootleg", "SNES 4 Slot arcade switcher", MACHINE_IS_SKELETON )
+GAME( 1994, snes4sln, 0, snes4sln, snes4sl, snesb51_state, empty_init, ROT0, "bootleg", "SNES 4 Slot arcade switcher (NBA Jam)", MACHINE_IS_SKELETON )
+GAME( 199?, fatfurspb, 0, mk3snes, mk3snes, snesb51_state, init_fatfurspb, ROT0, "bootleg", "Fatal Fury Special (SNES bootleg)", MACHINE_IS_SKELETON )