chelnovjbl: Hook up MCU

This commit is contained in:
Dirk Best 2019-08-28 16:58:41 +02:00
parent 5c482945c6
commit a1b1b325b1
2 changed files with 130 additions and 29 deletions

View File

@ -86,7 +86,6 @@ Stephh's notes (based on the games M68000 code and some tests) :
#include "sound/2203intf.h"
#include "sound/3526intf.h"
#include "sound/3812intf.h"
#include "cpu/mcs51/mcs51.h"
#include "screen.h"
#include "speaker.h"
@ -97,6 +96,69 @@ Stephh's notes (based on the games M68000 code and some tests) :
*
*************************************/
// i8031 bootleg emulation
void karnov_state::chelnovjbl_mcu_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
}
void karnov_state::chelnovjbl_mcu_io_map(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x00).rw(FUNC(karnov_state::mcu_data_l_r), FUNC(karnov_state::mcu_data_l_w));
map(0x01, 0x01).rw(FUNC(karnov_state::mcu_data_h_r), FUNC(karnov_state::mcu_data_h_w));
}
void karnov_state::chelnovjbl_mcu_ack_w(uint16_t data)
{
m_maincpu->set_input_line(6, CLEAR_LINE);
}
uint16_t karnov_state::chelnovjbl_mcu_r()
{
return m_mcu_to_maincpu;
}
void karnov_state::chelnovjbl_mcu_w(uint16_t data)
{
m_maincpu_to_mcu = data;
m_mcu->set_input_line(MCS51_INT1_LINE, ASSERT_LINE);
}
uint8_t karnov_state::mcu_data_l_r()
{
return m_maincpu_to_mcu >> 0;
}
void karnov_state::mcu_data_l_w(uint8_t data)
{
m_mcu_to_maincpu = (m_mcu_to_maincpu & 0xff00) | (data << 0);
}
uint8_t karnov_state::mcu_data_h_r()
{
return m_maincpu_to_mcu >> 8;
}
void karnov_state::mcu_data_h_w(uint8_t data)
{
m_mcu_to_maincpu = (m_mcu_to_maincpu & 0x00ff) | (data << 8);
}
void karnov_state::mcu_p1_w(uint8_t data)
{
if (BIT(m_mcu_p1, 0) == 1 && BIT(data, 0) == 0)
m_mcu->set_input_line(MCS51_INT1_LINE, CLEAR_LINE);
if (BIT(m_mcu_p1, 1) == 1 && BIT(data, 1) == 0)
m_maincpu->set_input_line(6, ASSERT_LINE);
m_mcu_p1 = data;
}
// end of i8031 emulation
/* Emulation of the protected microcontroller - for coins & general protection */
void karnov_state::karnov_i8751_w( int data )
{
@ -416,6 +478,14 @@ void karnov_state::karnov_map(address_map &map)
map(0x0c000e, 0x0c000f).w(FUNC(karnov_state::vint_ack_w));
}
void karnov_state::chelnovjbl_map(address_map &map)
{
karnov_map(map);
map(0x0c0000, 0x0c0001).portr("P1_P2").w(FUNC(karnov_state::chelnovjbl_mcu_ack_w));
map(0x0c0006, 0x0c0007).rw(FUNC(karnov_state::chelnovjbl_mcu_r), FUNC(karnov_state::chelnovjbl_mcu_w));
map(0x0c000c, 0x0c000d).unmaprw();
map(0x0c000e, 0x0c000f).nopr();
}
void karnov_state::base_sound_map(address_map &map)
{
@ -480,7 +550,7 @@ INPUT_PORTS_END
static INPUT_PORTS_START( karnov )
PORT_INCLUDE( common )
PORT_START("FAKE") /* Dummy input for i8751 */
PORT_START("COIN") /* Dummy input for i8751 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -537,7 +607,7 @@ static INPUT_PORTS_START( wndrplnt )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) /* BUTTON3 */
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED ) /* BUTTON3 PORT_COCKTAIL */
PORT_START("FAKE") /* Dummy input for i8751 */
PORT_START("COIN") /* Dummy input for i8751 */
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 )
@ -587,7 +657,7 @@ INPUT_PORTS_END
static INPUT_PORTS_START( chelnov )
PORT_INCLUDE( common )
PORT_START("FAKE") /* Dummy input for i8751 */
PORT_START("COIN") /* Dummy input for i8751 */
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -707,7 +777,7 @@ WRITE_LINE_MEMBER(karnov_state::vbint_w)
if (!state)
return;
uint8_t port = ioport("FAKE")->read();
uint8_t port = ioport("COIN")->read();
/* Coin input to the i8751 generates an interrupt to the main cpu */
if (port == m_coin_mask)
@ -733,6 +803,12 @@ WRITE_LINE_MEMBER(karnov_state::vbint_w)
m_maincpu->set_input_line(7, ASSERT_LINE);
}
void karnov_state::chelnovjbl_vbint_w(int state)
{
m_maincpu->set_input_line(7, ASSERT_LINE);
}
/*************************************
*
* Machine driver
@ -747,7 +823,9 @@ void karnov_state::machine_start()
save_item(NAME(m_i8751_command_queue));
save_item(NAME(m_i8751_level));
save_item(NAME(m_latch));
save_item(NAME(m_mcu_p1));
save_item(NAME(m_mcu_to_maincpu));
save_item(NAME(m_maincpu_to_mcu));
}
void karnov_state::machine_reset()
@ -778,14 +856,14 @@ void karnov_state::karnov(machine_config &config)
/* video hardware */
BUFFERED_SPRITERAM16(config, m_spriteram);
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(32*8, 32*8);
screen.set_visarea(0*8, 32*8-1, 1*8, 31*8-1);
screen.set_screen_update(FUNC(karnov_state::screen_update));
screen.set_palette(m_palette);
screen.screen_vblank().set(FUNC(karnov_state::vbint_w));
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
m_screen->set_size(32*8, 32*8);
m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1);
m_screen->set_screen_update(FUNC(karnov_state::screen_update));
m_screen->set_palette(m_palette);
m_screen->screen_vblank().set(FUNC(karnov_state::vbint_w));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_karnov);
DECO_RMC3(config, m_palette, 0, 1024); // xxxxBBBBGGGGRRRR with custom weighting
@ -824,21 +902,18 @@ void karnov_state::karnovjbl(machine_config &config)
ym2.add_route(ALL_OUTPUTS, "mono", 1.0);
}
void karnov_state::chelnovjbl_mcu_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
}
void karnov_state::chelnovjbl(machine_config &config)
{
karnov(config);
i8031_device &mcu(I8031(config, "mcu", 2000000)); // ??mhz
mcu.set_addrmap(AS_PROGRAM, &karnov_state::chelnovjbl_mcu_map);
// mcu.port_in_cb<1>().set(FUNC(karnov_state::p1_r));
// mcu.port_out_cb<1>().set(FUNC(karnov_state::p1_w));
// mcu.port_in_cb<3>().set(FUNC(karnov_state::p3_r));
// mcu.port_out_cb<3>().set(FUNC(karnov_state::p3_w));
m_maincpu->set_addrmap(AS_PROGRAM, &karnov_state::chelnovjbl_map);
I8031(config, m_mcu, 8_MHz_XTAL); // unknown clock
m_mcu->set_addrmap(AS_PROGRAM, &karnov_state::chelnovjbl_mcu_map);
m_mcu->set_addrmap(AS_IO, &karnov_state::chelnovjbl_mcu_io_map);
m_mcu->port_out_cb<1>().set(FUNC(karnov_state::mcu_p1_w));
m_mcu->port_in_cb<3>().set_ioport("COIN");
m_screen->screen_vblank().set(FUNC(karnov_state::chelnovjbl_vbint_w));
}
void karnov_state::wndrplnt(machine_config &config)
@ -1214,7 +1289,7 @@ ROM_START( chelnovjbl ) // code is the same as the regular chelnovj set
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 6502 Sound CPU */
ROM_LOAD( "ee05-.f3", 0x8000, 0x8000, CRC(6a8936b4) SHA1(2b72cb749e6bddb67c2bd3d27b3a92511f9ef016) )
ROM_REGION( 0x2000, "mcu", 0 ) /* SCM8031HCCN40 */ // unique to the bootlegs (rewritten, or an exact copy of original Data East internal rom?)
ROM_REGION( 0x2000, "mcu", 0 ) /* SCM8031HCCN40 */ // unique to the bootlegs (rewritten or adjusted to be 8031 compatible)
ROM_LOAD( "17o.bin", 0x0000, 0x2000, CRC(9af64150) SHA1(0f478d9f79baebd2ad90615c98c6bc2d73c0056a) )
ROM_REGION( 0x08000, "gfx1", 0 )
@ -1359,5 +1434,5 @@ GAME( 1987, wndrplnt, 0, wndrplnt, wndrplnt, karnov_state, init_wndrp
GAME( 1988, chelnov, 0, karnov, chelnov, karnov_state, init_chelnov, ROT0, "Data East Corporation", "Chelnov - Atomic Runner (World)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, chelnovu, chelnov, karnov, chelnovu, karnov_state, init_chelnovu, ROT0, "Data East USA", "Chelnov - Atomic Runner (US)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, chelnovj, chelnov, karnov, chelnovj, karnov_state, init_chelnovj, ROT0, "Data East Corporation", "Chelnov - Atomic Runner (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, chelnovjbl, chelnov, chelnovjbl, chelnovj, karnov_state, init_chelnovj, ROT0, "bootleg", "Chelnov - Atomic Runner (Japan, bootleg with I8031, set 1)", MACHINE_SUPPORTS_SAVE ) // todo: hook up MCU instead of using simulation code
GAME( 1988, chelnovjbla, chelnov, chelnovjbl, chelnovj, karnov_state, init_chelnovj, ROT0, "bootleg", "Chelnov - Atomic Runner (Japan, bootleg with I8031, set 2)", MACHINE_SUPPORTS_SAVE ) // ^^
GAME( 1988, chelnovjbl, chelnov, chelnovjbl, chelnovj, karnov_state, empty_init, ROT0, "bootleg", "Chelnov - Atomic Runner (Japan, bootleg with I8031, set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1988, chelnovjbla, chelnov, chelnovjbl, chelnovj, karnov_state, empty_init, ROT0, "bootleg", "Chelnov - Atomic Runner (Japan, bootleg with I8031, set 2)", MACHINE_SUPPORTS_SAVE )

View File

@ -6,6 +6,7 @@
*************************************************************************/
#include "cpu/mcs51/mcs51.h"
#include "machine/gen_latch.h"
#include "video/bufsprite.h"
#include "video/deckarn.h"
@ -19,6 +20,8 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_mcu(*this, "mcu"),
m_screen(*this, "screen"),
m_spriteram(*this, "spriteram") ,
m_spritegen(*this, "spritegen"),
m_gfxdecode(*this, "gfxdecode"),
@ -32,6 +35,8 @@ public:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<mcs51_cpu_device> m_mcu;
required_device<screen_device> m_screen;
required_device<buffered_spriteram16_device> m_spriteram;
required_device<deco_karnovsprites_device> m_spritegen;
required_device<gfxdecode_device> m_gfxdecode;
@ -79,6 +84,7 @@ public:
DECLARE_VIDEO_START(wndrplnt);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(vbint_w);
void chelnovjbl_vbint_w(int state);
void karnov_i8751_w( int data );
void wndrplnt_i8751_w( int data );
void chelnov_i8751_w( int data );
@ -88,9 +94,29 @@ public:
void karnovjbl(machine_config &config);
void base_sound_map(address_map &map);
void chelnovjbl_mcu_map(address_map &map);
void chelnovjbl_mcu_io_map(address_map &map);
void karnov_map(address_map &map);
void chelnovjbl_map(address_map &map);
void karnov_sound_map(address_map &map);
void karnovjbl_sound_map(address_map &map);
private:
// protection mcu (bootleg)
void chelnovjbl_mcu_ack_w(uint16_t data);
uint16_t chelnovjbl_mcu_r();
void chelnovjbl_mcu_w(uint16_t data);
uint8_t mcu_data_l_r();
void mcu_data_l_w(uint8_t data);
uint8_t mcu_data_h_r();
void mcu_data_h_w(uint8_t data);
void mcu_p1_w(uint8_t data);
uint8_t m_mcu_p1;
uint16_t m_mcu_to_maincpu;
uint16_t m_maincpu_to_mcu;
};
enum {