barek2mb: Hook up PIC MCU

Systems promoted to working
---------------------------
Bare Knuckle II (bootleg of Mega Drive version)
This commit is contained in:
Dirk Best 2024-09-24 18:18:22 +02:00
parent 678fefdfbc
commit a3f703b304
2 changed files with 196 additions and 47 deletions

View file

@ -144,6 +144,12 @@ Sunset Riders info
- title raster effect is broken (bug in Mega Drive code, happens with normal set too)
TODO (barek2mb):
- Unknown inputs to Port B of the emulated PIC
- MCU clock frequency
- There is only a 50 MHz XTAL on the PCB, are the other clocks correct?
****************************************************************************/
#include "emu.h"
@ -161,6 +167,14 @@ void md_boot_state::md_bootleg_map(address_map &map)
map(0x200000, 0x2023ff).ram(); // Tested
}
void md_boot_mcu_state::md_boot_mcu_map(address_map &map)
{
md_bootleg_map(map);
map(0x220000, 0x220001).w(FUNC(md_boot_mcu_state::mcu_w));
map(0x330000, 0x330001).r(FUNC(md_boot_mcu_state::mcu_r));
}
void md_boot_6button_state::ssf2mdb_68k_map(address_map &map)
{
megadriv_68k_map(map);
@ -171,24 +185,6 @@ void md_boot_6button_state::ssf2mdb_68k_map(address_map &map)
}
void md_boot_state::megadrvb(machine_config &config)
{
md_ntsc(config);
ctrl1_3button(config);
ctrl2_3button(config);
m_ioports[2]->set_in_handler(NAME([this] () { return m_io_exp.read_safe(0x3f); }));
}
void md_boot_state::md_bootleg(machine_config &config)
{
megadrvb(config);
m_maincpu->set_addrmap(AS_PROGRAM, &md_boot_state::md_bootleg_map);
}
/*************************************
*
* Games memory handlers
@ -250,18 +246,6 @@ uint16_t md_boot_state::jparkmb_r()
return 0x0000;
}
uint16_t md_boot_state::barek2mb_r()
{
if (m_maincpu->pc() == 0xfa40)
return 0x0400; // TODO: what's this? Needed or the game doesn't boot
if (m_maincpu->pc() == 0xfa88)
return 0x0ff0; // TODO: fix this, should probably read coin inputs, as is gives 9 credits at start up
logerror("barek2mb_r : %06x\n", m_maincpu->pc());
return 0x0000;
}
uint16_t md_boot_state::barek3mba_r() // missing PIC dump, simulated for now
{
if (m_maincpu->pc() == 0x4dbc6)
@ -315,6 +299,83 @@ uint16_t md_boot_state::dsw_r(offs_t offset)
}
/*************************************
*
* PIC MCU Emulation
*
*************************************/
uint16_t md_boot_mcu_state::mcu_r()
{
return (m_mcu_out_latch_msb << 8) | m_mcu_out_latch_lsb;
}
void md_boot_mcu_state::mcu_w(uint16_t data)
{
m_mcu_in_latch_lsb = data >> 0;
m_mcu_in_latch_msb = data >> 8;
}
void md_boot_mcu_state::mcu_porta_w(uint8_t data)
{
// 3--- select dsw (0) or latches (1)
// -2-- latch enable
// --1- select input (0) or output (1) latches
// ---0 select lsb or msb latches
if (BIT(data, 2) == 0)
{
if (BIT(data, 1) == 1)
{
if (BIT(data, 0) == 0)
m_mcu_out_latch_lsb = m_mcu_portc;
else
m_mcu_out_latch_msb = m_mcu_portc;
}
}
m_mcu_porta = data;
}
void md_boot_mcu_state::mcu_portb_w(uint8_t data)
{
// 7------- unused
// -6------ cleared on reset
// --5----- toggled on input to b3
// ---4---- toggled on input to b2
// ----3--- unknown (input)
// -----2-- unknown (input)
// ------1- unused (input)
// -------0 coin (input)
}
uint8_t md_boot_mcu_state::mcu_portc_r()
{
// read dip switches
if (BIT(m_mcu_porta, 3) == 0)
return m_dsw->read();
// read from latch
if (BIT(m_mcu_porta, 1) == 0)
{
if (BIT(m_mcu_porta, 0) == 0)
return m_mcu_in_latch_lsb;
else
return m_mcu_in_latch_msb;
}
// should never go here
logerror("mcu: read from output latch!\n");
return 0xff;
}
void md_boot_mcu_state::mcu_portc_w(uint8_t data)
{
m_mcu_portc = data;
}
/*************************************
*
* Game-specific port definitions
@ -743,8 +804,43 @@ INPUT_PORTS_START( barek2ch )
INPUT_PORTS_END
INPUT_PORTS_START( barek2 )
PORT_INCLUDE( aladmdb )
// TODO!
PORT_INCLUDE( md_common )
PORT_START("dsw")
PORT_DIPNAME(0x0f, 0x0f, DEF_STR( Coinage ))
PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ))
PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ))
PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ))
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ))
PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ))
PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ))
PORT_DIPSETTING( 0x09, DEF_STR( 2C_1C ))
PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ))
PORT_DIPSETTING( 0x07, DEF_STR( 4C_1C ))
PORT_DIPSETTING( 0x06, DEF_STR( 5C_1C ))
PORT_DIPSETTING( 0x05, DEF_STR( 6C_1C ))
PORT_DIPSETTING( 0x04, DEF_STR( 2C_3C ))
PORT_DIPSETTING( 0x03, DEF_STR( 3C_2C ))
PORT_DIPSETTING( 0x02, DEF_STR( 5C_3C ))
PORT_DIPSETTING( 0x01, DEF_STR( 8C_3C ))
PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C )) // duplicate
PORT_DIPNAME(0x30, 0x30, DEF_STR( Lives ))
PORT_DIPSETTING( 0x30, "1" )
PORT_DIPSETTING( 0x20, "2" )
PORT_DIPSETTING( 0x10, "3" )
PORT_DIPSETTING( 0x00, "4" )
PORT_DIPNAME(0xc0, 0xc0, DEF_STR( Difficulty ))
PORT_DIPSETTING( 0xc0, DEF_STR( Easy ))
PORT_DIPSETTING( 0x80, DEF_STR( Medium ))
PORT_DIPSETTING( 0x40, DEF_STR( Hard ))
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ))
PORT_START("in0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNKNOWN)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNKNOWN)
PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED)
INPUT_PORTS_END
INPUT_PORTS_START( barek3 )
@ -847,6 +943,37 @@ INPUT_PORTS_END
*
*************************************/
void md_boot_state::megadrvb(machine_config &config)
{
md_ntsc(config);
ctrl1_3button(config);
ctrl2_3button(config);
m_ioports[2]->set_in_handler(NAME([this] () { return m_io_exp.read_safe(0x3f); }));
}
void md_boot_state::md_bootleg(machine_config &config)
{
megadrvb(config);
m_maincpu->set_addrmap(AS_PROGRAM, &md_boot_state::md_bootleg_map);
}
void md_boot_mcu_state::md_boot_mcu(machine_config &config)
{
megadrvb(config);
m_maincpu->set_addrmap(AS_PROGRAM, &md_boot_mcu_state::md_boot_mcu_map);
PIC16C57(config, m_mcu, 4000000); // unknown clock
m_mcu->write_a().set(FUNC(md_boot_mcu_state::mcu_porta_w));
m_mcu->read_b().set_ioport("in0");
m_mcu->write_b().set(FUNC(md_boot_mcu_state::mcu_portb_w));
m_mcu->read_c().set(FUNC(md_boot_mcu_state::mcu_portc_r));
m_mcu->write_c().set(FUNC(md_boot_mcu_state::mcu_portc_w));
}
void md_boot_6button_state::machine_start()
{
md_boot_state::machine_start();
@ -869,7 +996,6 @@ void md_boot_6button_state::ssf2mdb(machine_config &config)
}
/*************************************
*
* Game-specific driver inits
@ -969,15 +1095,6 @@ void md_boot_state::init_srmdb()
init_megadriv();
}
void md_boot_state::init_barek2()
{
m_maincpu->space(AS_PROGRAM).install_write_handler(0x220000, 0x220001, write16smo_delegate(*this, FUNC(md_boot_state::aladmdb_w)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x330000, 0x330001, read16smo_delegate(*this, FUNC(md_boot_state::barek2mb_r)));
init_megadrij();
}
void md_boot_6button_state::init_barekch()
{
uint16_t *src = (uint16_t *)memregion("maincpu")->base();
@ -1181,8 +1298,7 @@ ROM_START( barek2mb )
ROM_LOAD16_BYTE( "m3.bin", 0x100001, 0x080000, CRC(6ec5af5d) SHA1(9088a2d4cff5e7eb439ebaa91ad3bfff11366127) )
ROM_LOAD16_BYTE( "m4.bin", 0x100000, 0x080000, CRC(d8c61e0d) SHA1(3d06e656f6621bb0741211f80c1ecff1669475ee) )
// Not hooked up yet
ROM_REGION( 0x1000, "pic", ROMREGION_ERASE00 )
ROM_REGION( 0x1000, "mcu", 0 )
ROM_LOAD( "bk_pic16c57rcp.bin", 0x0000, 0x1000, CRC(434ad1b7) SHA1(9241554793c7375cf58239e762481a4b80a51df6) ) // Unprotected
ROM_END
@ -1270,7 +1386,7 @@ GAME( 1994, ssf2mdb, 0, ssf2mdb, ssf2mdb, md_boot_6button_state,
GAME( 1993, srmdb, 0, megadrvb, srmdb, md_boot_state, init_srmdb, ROT0, "bootleg / Konami", "Sunset Riders (bootleg of Mega Drive version)", 0 )
GAME( 1993, sonic2mb, 0, md_bootleg, sonic2mb, md_boot_state, init_sonic2mb, ROT0, "bootleg / Sega", "Sonic The Hedgehog 2 (bootleg of Mega Drive version)", 0 ) // Flying wires going through the empty PIC space aren't completely understood
GAME( 1993, sonic3mb, 0, md_bootleg, sonic3mb, md_sonic3bl_state, init_sonic3mb, ROT0, "bootleg / Sega", "Sonic The Hedgehog 3 (bootleg of Mega Drive version)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING ) // undumped PIC
GAME( 1994, barek2mb, 0, md_bootleg, barek2, md_boot_state, init_barek2, ROT0, "bootleg / Sega", "Bare Knuckle II (bootleg of Mega Drive version)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING ) // Needs PIC hook up
GAME( 1994, barek2mb, 0, md_boot_mcu, barek2, md_boot_mcu_state, init_megadrij, ROT0, "bootleg / Sega", "Bare Knuckle II (bootleg of Mega Drive version)", 0 ) // PCB labeled "BK-059"
GAME( 1994, barek3mb, 0, megadrvb, barek3, md_boot_state, init_barek3, ROT0, "bootleg / Sega", "Bare Knuckle III (bootleg of Mega Drive version)", 0 )
GAME( 1994, barek3mba, barek3mb, megadrvb, barek3, md_boot_state, init_barek3a, ROT0, "bootleg / Sega", "Bare Knuckle III (bootleg of Mega Drive version, protected)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING ) // undumped PIC
GAME( 1994, bk3ssrmb, 0, megadrvb_6b, bk3ssrmb, md_boot_6button_state, init_bk3ssrmb, ROT0, "bootleg / Sega", "Bare Knuckle III / Sunset Riders (bootleg of Mega Drive versions)", MACHINE_NOT_WORKING ) // Currently boots as Bare Knuckle III, mechanism to switch game not found yet

View file

@ -4,6 +4,7 @@
#define MAME_SEGA_MEGADRIV_ACBL_H
#include "megadriv.h"
#include "cpu/pic16c5x/pic16c5x.h"
class md_boot_state : public md_ctrl_state
@ -19,7 +20,6 @@ public:
void init_aladmdb();
void init_srmdb();
void init_barek2();
void init_barek2ch();
void init_barek3();
void init_barek3a();
@ -35,7 +35,6 @@ protected:
private:
void aladmdb_w(uint16_t data);
uint16_t aladmdb_r();
uint16_t barek2mb_r();
uint16_t barek3mba_r();
uint16_t jparkmb_r();
uint16_t twinktmb_r();
@ -46,6 +45,40 @@ private:
int m_aladmdb_mcu_port = 0;
};
// for games with emulated pic mcu
class md_boot_mcu_state : public md_boot_state
{
public:
md_boot_mcu_state(const machine_config &mconfig, device_type type, const char *tag) :
md_boot_state(mconfig, type, tag),
m_mcu(*this, "mcu"),
m_dsw(*this, "dsw")
{ }
void md_boot_mcu(machine_config &config);
private:
void md_boot_mcu_map(address_map &map);
uint16_t mcu_r();
void mcu_w(uint16_t data);
void mcu_porta_w(uint8_t data);
uint8_t mcu_portc_r();
void mcu_portb_w(uint8_t data);
void mcu_portc_w(uint8_t data);
required_device<pic16c57_device> m_mcu;
required_ioport m_dsw;
uint8_t m_mcu_porta;
uint8_t m_mcu_portc;
uint8_t m_mcu_in_latch_msb;
uint8_t m_mcu_in_latch_lsb;
uint8_t m_mcu_out_latch_msb;
uint8_t m_mcu_out_latch_lsb;
};
class md_sonic3bl_state : public md_boot_state
{
public: