Skip to content

Commit

Permalink
barek2mb: Hook up PIC MCU
Browse files Browse the repository at this point in the history
Systems promoted to working
---------------------------
Bare Knuckle II (bootleg of Mega Drive version)
  • Loading branch information
startaq committed Sep 24, 2024
1 parent 678fefd commit a3f703b
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 47 deletions.
206 changes: 161 additions & 45 deletions src/mame/sega/megadriv_acbl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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();
Expand All @@ -869,7 +996,6 @@ void md_boot_6button_state::ssf2mdb(machine_config &config)
}



/*************************************
*
* Game-specific driver inits
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
37 changes: 35 additions & 2 deletions src/mame/sega/megadriv_acbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -19,7 +20,6 @@ class md_boot_state : public md_ctrl_state

void init_aladmdb();
void init_srmdb();
void init_barek2();
void init_barek2ch();
void init_barek3();
void init_barek3a();
Expand All @@ -35,7 +35,6 @@ class md_boot_state : public md_ctrl_state
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();
Expand All @@ -46,6 +45,40 @@ class md_boot_state : public md_ctrl_state
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:
Expand Down

1 comment on commit a3f703b

@Hammy1986
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Hopefully we can get some more dumped soon :)

Please sign in to comment.