mirror of
https://github.com/holub/mame
synced 2025-10-05 16:50:57 +03:00
decap + dump f1dream I8751 MCU [Caps0ff] (#3467)
* decap + dump f1dream I8751 MCU [Caps0ff] hookup dumped MCU to f1dream [David Haywood] some connections might need verifying on the PCB, this is based on study of the code machines promoted to WORKING F-1 Dream [Caps0ff, David Haywood] * formatting (nw)
This commit is contained in:
parent
49d25dac06
commit
eaa91d0abd
@ -14,8 +14,6 @@ regarding this driver.
|
||||
|
||||
**************************************************************************
|
||||
|
||||
F1 Dream protection workaround by Eric Hustvedt
|
||||
|
||||
Memory Overview:
|
||||
0xfe0800 sprites
|
||||
0xfec000 text
|
||||
@ -68,6 +66,41 @@ WRITE8_MEMBER(tigeroad_state::msm5205_w)
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(f1dream_state::out1_w)
|
||||
{
|
||||
m_soundlatch->write(space,2,data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(f1dream_state::out3_w)
|
||||
{
|
||||
if ((m_old_p3 & 0x20) != (data & 0x20))
|
||||
{
|
||||
// toggles at the start and end of interrupt
|
||||
}
|
||||
|
||||
if ((m_old_p3 & 0x01) != (data & 0x01))
|
||||
{
|
||||
// toggles at the end of interrupt
|
||||
if (!(data & 0x01))
|
||||
{
|
||||
m_maincpu->resume(SUSPEND_REASON_HALT);
|
||||
}
|
||||
}
|
||||
|
||||
m_old_p3 = data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(f1dream_state::blktiger_to_mcu_w)
|
||||
{
|
||||
m_mcu->set_input_line(MCS51_INT0_LINE, HOLD_LINE);
|
||||
|
||||
/* after triggering this address there are one or two NOPs in the 68k code, then it expects the response to be ready
|
||||
the MCU isn't that fast, so either the CPU is suspended on write, or when bit 0x20 of MCU Port 3 toggles in the
|
||||
MCU interrupt code, however no combination of increasing the clock / boosting interleave etc. allows the MCU code
|
||||
to get there in time before the 68k is already expecting a result */
|
||||
m_maincpu->suspend(SUSPEND_REASON_HALT, true);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void tigeroad_state::main_map(address_map &map)
|
||||
@ -87,6 +120,30 @@ void tigeroad_state::main_map(address_map &map)
|
||||
map(0xffc000, 0xffffff).ram().share("ram16");
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(f1dream_state::mcu_shared_r)
|
||||
{
|
||||
uint8_t ret = m_ram16[(0x3fe0 / 2) + offset];
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(f1dream_state::mcu_shared_w)
|
||||
{
|
||||
m_ram16[(0x3fe0 / 2) + offset] = (m_ram16[(0x3fe0 / 2) + offset] & 0xff00) | data;
|
||||
}
|
||||
|
||||
void f1dream_state::f1dream_map(address_map &map)
|
||||
{
|
||||
main_map(map);
|
||||
map(0xfe4002, 0xfe4003).portr("SYSTEM").w(this, FUNC(f1dream_state::blktiger_to_mcu_w));
|
||||
}
|
||||
|
||||
void f1dream_state::f1dream_mcu_io(address_map &map)
|
||||
{
|
||||
map(0x7f0, 0x7ff).rw(this, FUNC(f1dream_state::mcu_shared_r), FUNC(f1dream_state::mcu_shared_w));
|
||||
}
|
||||
|
||||
|
||||
void pushman_state::pushman_map(address_map &map)
|
||||
{
|
||||
main_map(map);
|
||||
@ -630,6 +687,18 @@ MACHINE_CONFIG_START(tigeroad_state::tigeroad)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
MACHINE_CONFIG_START(f1dream_state::f1dream)
|
||||
tigeroad(config);
|
||||
|
||||
MCFG_CPU_MODIFY("maincpu")
|
||||
MCFG_CPU_PROGRAM_MAP(f1dream_map)
|
||||
|
||||
MCFG_CPU_ADD("mcu", I8751, XTAL(10'000'000)) /* ??? */
|
||||
MCFG_CPU_IO_MAP(f1dream_mcu_io)
|
||||
MCFG_MCS51_PORT_P1_OUT_CB(WRITE8(f1dream_state, out1_w))
|
||||
MCFG_MCS51_PORT_P3_OUT_CB(WRITE8(f1dream_state, out3_w))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/* same as above but with additional Z80 for samples playback */
|
||||
MACHINE_CONFIG_START(tigeroad_state::toramich)
|
||||
tigeroad(config);
|
||||
@ -888,7 +957,7 @@ ROM_START( f1dream )
|
||||
ROM_LOAD( "12k_04.bin", 0x0000, 0x8000, CRC(4b9a7524) SHA1(19004958c19ac0af35f2c97790b0082ee2c15bc4) )
|
||||
|
||||
ROM_REGION( 0x1000, "mcu", 0 ) /* i8751 microcontroller */
|
||||
ROM_LOAD( "c8751h-88", 0x0000, 0x1000, NO_DUMP )
|
||||
ROM_LOAD( "8751.mcu", 0x0000, 0x1000, CRC(c8e6075c) SHA1(d98bd358d30d22a8009cd2728dde1871a8140c23) )
|
||||
|
||||
ROM_REGION( 0x008000, "text", 0 )
|
||||
ROM_LOAD( "10d_01.bin", 0x00000, 0x08000, CRC(361caf00) SHA1(8a109e4e116d0c5eea86f9c57c05359754daa5b9) ) /* 8x8 text */
|
||||
@ -1182,10 +1251,6 @@ ROM_START( bballsa )
|
||||
ROM_END
|
||||
|
||||
|
||||
DRIVER_INIT_MEMBER(tigeroad_state, f1dream)
|
||||
{
|
||||
m_maincpu->space(AS_PROGRAM).install_write_handler(0xfe4002, 0xfe4003, write16_delegate(FUNC(tigeroad_state::f1dream_control_w),this));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -1196,9 +1261,9 @@ GAME( 1987, toramich, tigeroad, toramich, toramich, tigeroad_state, 0, ROT
|
||||
GAME( 1987, tigeroadb,tigeroad, tigeroad, tigeroad, tigeroad_state, 0, ROT0, "bootleg", "Tiger Road (US bootleg)", 0 )
|
||||
|
||||
/* F1 Dream has an Intel 8751 microcontroller for protection */
|
||||
GAME( 1988, f1dream, 0, tigeroad, f1dream, tigeroad_state, f1dream, ROT0, "Capcom (Romstar license)", "F-1 Dream", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // collisions are wrong
|
||||
GAME( 1988, f1dreamb, f1dream, tigeroad, f1dream, tigeroad_state, 0, ROT0, "bootleg", "F-1 Dream (bootleg, set 1)", 0 )
|
||||
GAME( 1988, f1dreamba,f1dream, tigeroad, f1dream, tigeroad_state, 0, ROT0, "bootleg", "F-1 Dream (bootleg, set 2)", 0 )
|
||||
GAME( 1988, f1dream, 0, f1dream, f1dream, f1dream_state, 0, ROT0, "Capcom (Romstar license)", "F-1 Dream", 0 )
|
||||
GAME( 1988, f1dreamb, f1dream, tigeroad, f1dream, tigeroad_state, 0, ROT0, "bootleg", "F-1 Dream (bootleg, set 1)", 0 )
|
||||
GAME( 1988, f1dreamba,f1dream, tigeroad, f1dream, tigeroad_state, 0, ROT0, "bootleg", "F-1 Dream (bootleg, set 2)", 0 )
|
||||
|
||||
/* This Comad hardware is based around the F1 Dream design */
|
||||
GAME( 1990, pushman, 0, pushman, pushman, pushman_state, 0, ROT0, "Comad", "Pushman (Korea, set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/m6805/m68705.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
|
||||
#include "machine/gen_latch.h"
|
||||
|
||||
@ -39,19 +40,16 @@ public:
|
||||
int m_bgcharbank;
|
||||
tilemap_t *m_bg_tilemap;
|
||||
tilemap_t *m_fg_tilemap;
|
||||
DECLARE_WRITE16_MEMBER(f1dream_control_w);
|
||||
DECLARE_WRITE16_MEMBER(tigeroad_soundcmd_w);
|
||||
DECLARE_WRITE16_MEMBER(tigeroad_videoram_w);
|
||||
DECLARE_WRITE16_MEMBER(tigeroad_videoctrl_w);
|
||||
DECLARE_WRITE16_MEMBER(tigeroad_scroll_w);
|
||||
DECLARE_WRITE8_MEMBER(msm5205_w);
|
||||
DECLARE_DRIVER_INIT(f1dream);
|
||||
TILE_GET_INFO_MEMBER(get_bg_tile_info);
|
||||
TILE_GET_INFO_MEMBER(get_fg_tile_info);
|
||||
TILEMAP_MAPPER_MEMBER(tigeroad_tilemap_scan);
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_tigeroad(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void f1dream_protection_w(address_space &space);
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
optional_device<msm5205_device> m_msm;
|
||||
@ -114,3 +112,30 @@ protected:
|
||||
u16 m_mcu_output;
|
||||
u8 m_mcu_latch_ctl;
|
||||
};
|
||||
|
||||
class f1dream_state : public tigeroad_state
|
||||
{
|
||||
public:
|
||||
f1dream_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: tigeroad_state(mconfig, type, tag)
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_old_p3(0xff)
|
||||
{
|
||||
}
|
||||
|
||||
void f1dream(machine_config &config);
|
||||
void f1dream_map(address_map &map);
|
||||
void f1dream_mcu_io(address_map &map);
|
||||
|
||||
private:
|
||||
DECLARE_WRITE8_MEMBER(out1_w);
|
||||
DECLARE_WRITE8_MEMBER(out3_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(mcu_shared_r);
|
||||
DECLARE_WRITE8_MEMBER(mcu_shared_w);
|
||||
|
||||
DECLARE_WRITE16_MEMBER(blktiger_to_mcu_w);
|
||||
|
||||
required_device<cpu_device> m_mcu;
|
||||
uint8_t m_old_p3;
|
||||
};
|
||||
|
@ -3,127 +3,6 @@
|
||||
#include "emu.h"
|
||||
#include "includes/tigeroad.h"
|
||||
|
||||
/*
|
||||
F1 Dream protection code written by Eric Hustvedt (hustvedt@ma.ultranet.com).
|
||||
|
||||
The genuine F1 Dream game uses an 8751 microcontroller as a protection measure.
|
||||
Since the microcontroller's ROM is unavailable all interactions with it are handled
|
||||
via blackbox algorithm.
|
||||
|
||||
Some notes:
|
||||
- The 8751 is triggered via location 0xfe4002, in place of the soundlatch normally
|
||||
present. The main cpu writes 0 to the location when it wants the 8751 to perform some work.
|
||||
- The 8751 has memory which shadows locations 0xffffe0-0xffffff of the main cpu's address space.
|
||||
- The word at 0xffffe0 contains an 'opcode' which is written just before the write to 0xfe4002.
|
||||
- Some of the writes to the soundlatch may not be handled. 0x27fc is the main sound routine, the
|
||||
other locations are less frequently used.
|
||||
*/
|
||||
|
||||
static const int f1dream_613ea_lookup[16] = {
|
||||
0x0052, 0x0031, 0x00a7, 0x0043, 0x0007, 0x008a, 0x00b1, 0x0066, 0x009f, 0x00cc, 0x0009, 0x004d, 0x0033, 0x0028, 0x00d0, 0x0025};
|
||||
|
||||
static const int f1dream_613eb_lookup[256] = {
|
||||
0x0001, 0x00b5, 0x00b6, 0x00b6, 0x00b6, 0x00b6, 0x00b6, 0x00b6, 0x00b7, 0x0001, 0x00b8, 0x002f, 0x002f, 0x002f, 0x002f, 0x00b9,
|
||||
0x00aa, 0x0031, 0x00ab, 0x00ab, 0x00ab, 0x00ac, 0x00ad, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x0091,
|
||||
0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x009b, 0x0091,
|
||||
0x00bc, 0x0092, 0x000b, 0x0009, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0073, 0x0001, 0x0098, 0x0099, 0x009a, 0x009b, 0x0091,
|
||||
0x00bc, 0x007b, 0x000b, 0x0008, 0x0087, 0x0088, 0x0089, 0x008a, 0x007f, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091,
|
||||
0x00bd, 0x007b, 0x000b, 0x0007, 0x007c, 0x007d, 0x007e, 0x0001, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086,
|
||||
0x00bc, 0x0070, 0x000b, 0x0006, 0x0071, 0x0072, 0x0073, 0x0001, 0x0074, 0x000d, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a,
|
||||
0x00bc, 0x00ba, 0x000a, 0x0005, 0x0065, 0x0066, 0x0067, 0x0068, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
|
||||
0x00bc, 0x0059, 0x0001, 0x0004, 0x005a, 0x005b, 0x0001, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064,
|
||||
0x0014, 0x004d, 0x0001, 0x0003, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0001, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
|
||||
0x0014, 0x0043, 0x0001, 0x0002, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00bb, 0x004a, 0x004b, 0x004c, 0x0001, 0x0001,
|
||||
0x0014, 0x002b, 0x0001, 0x0038, 0x0039, 0x003a, 0x003b, 0x0031, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0001,
|
||||
0x0014, 0x002d, 0x0001, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0001, 0x0014, 0x0037, 0x0001,
|
||||
0x0014, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x0001, 0x0001, 0x0001, 0x002a, 0x002b, 0x002c,
|
||||
0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001e, 0x001e, 0x001e, 0x001f, 0x0020,
|
||||
0x000c, 0x000d, 0x000e, 0x0001, 0x000f, 0x0010, 0x0011, 0x0012, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x000d, 0x0013 };
|
||||
|
||||
static const int f1dream_17b74_lookup[128] = {
|
||||
0x0003, 0x0040, 0x0005, 0x0080, 0x0003, 0x0080, 0x0005, 0x00a0, 0x0003, 0x0040, 0x0005, 0x00c0, 0x0003, 0x0080, 0x0005, 0x00e0,
|
||||
0x0003, 0x0040, 0x0006, 0x0000, 0x0003, 0x0080, 0x0006, 0x0020, 0x0003, 0x0040, 0x0006, 0x0040, 0x0003, 0x0080, 0x0006, 0x0060,
|
||||
0x0000, 0x00a0, 0x0009, 0x00e0, 0x0000, 0x00e0, 0x000a, 0x0000, 0x0000, 0x00a0, 0x000a, 0x0020, 0x0000, 0x00e0, 0x000a, 0x0040,
|
||||
0x0000, 0x00a0, 0x000a, 0x0060, 0x0000, 0x00e0, 0x000a, 0x0080, 0x0000, 0x00a0, 0x000a, 0x00a0, 0x0000, 0x00e0, 0x000a, 0x00c0,
|
||||
0x0003, 0x0040, 0x0005, 0x0080, 0x0003, 0x0080, 0x0005, 0x00a0, 0x0003, 0x0040, 0x0005, 0x00c0, 0x0003, 0x0080, 0x0005, 0x00e0,
|
||||
0x0003, 0x0040, 0x0006, 0x0000, 0x0003, 0x0080, 0x0006, 0x0020, 0x0003, 0x0040, 0x0006, 0x0040, 0x0003, 0x0080, 0x0006, 0x0060,
|
||||
0x0000, 0x00a0, 0x0009, 0x00e0, 0x0000, 0x00e0, 0x000a, 0x0000, 0x0000, 0x00a0, 0x000a, 0x0020, 0x0000, 0x00e0, 0x000a, 0x0040,
|
||||
0x0000, 0x00a0, 0x000a, 0x0060, 0x0000, 0x00e0, 0x000a, 0x0080, 0x0000, 0x00a0, 0x000a, 0x00a0, 0x0000, 0x00e0, 0x000a, 0x00c0 };
|
||||
|
||||
static const int f1dream_2450_lookup[32] = {
|
||||
0x0003, 0x0080, 0x0006, 0x0060, 0x0000, 0x00e0, 0x000a, 0x00c0, 0x0003, 0x0080, 0x0006, 0x0060, 0x0000, 0x00e0, 0x000a, 0x00c0,
|
||||
0x0003, 0x0080, 0x0006, 0x0060, 0x0000, 0x00e0, 0x000a, 0x00c0, 0x0003, 0x0080, 0x0006, 0x0060, 0x0000, 0x00e0, 0x000a, 0x00c0 };
|
||||
|
||||
void tigeroad_state::f1dream_protection_w(address_space &space)
|
||||
{
|
||||
int indx;
|
||||
int value = 255;
|
||||
int prevpc = m_maincpu->pcbase();
|
||||
|
||||
if (prevpc == 0x244c)
|
||||
{
|
||||
/* Called once, when a race is started.*/
|
||||
indx = m_ram16[0x3ff0/2];
|
||||
m_ram16[0x3fe6/2] = f1dream_2450_lookup[indx];
|
||||
m_ram16[0x3fe8/2] = f1dream_2450_lookup[++indx];
|
||||
m_ram16[0x3fea/2] = f1dream_2450_lookup[++indx];
|
||||
m_ram16[0x3fec/2] = f1dream_2450_lookup[++indx];
|
||||
}
|
||||
else if (prevpc == 0x613a)
|
||||
{
|
||||
/* Called for every sprite on-screen.*/
|
||||
if (m_ram16[0x3ff6/2] < 15)
|
||||
{
|
||||
indx = f1dream_613ea_lookup[m_ram16[0x3ff6/2]] - m_ram16[0x3ff4/2];
|
||||
if (indx > 255)
|
||||
{
|
||||
indx <<= 4;
|
||||
indx += m_ram16[0x3ff6/2] & 0x00ff;
|
||||
value = f1dream_613eb_lookup[indx];
|
||||
}
|
||||
}
|
||||
|
||||
m_ram16[0x3ff2/2] = value;
|
||||
}
|
||||
else if (prevpc == 0x17b70)
|
||||
{
|
||||
/* Called only before a real race, not a time trial.*/
|
||||
if (m_ram16[0x3ff0/2] >= 0x04) indx = 128;
|
||||
else if (m_ram16[0x3ff0/2] > 0x02) indx = 96;
|
||||
else if (m_ram16[0x3ff0/2] == 0x02) indx = 64;
|
||||
else if (m_ram16[0x3ff0/2] == 0x01) indx = 32;
|
||||
else indx = 0;
|
||||
|
||||
indx += m_ram16[0x3fee/2];
|
||||
if (indx < 128)
|
||||
{
|
||||
m_ram16[0x3fe6/2] = f1dream_17b74_lookup[indx];
|
||||
m_ram16[0x3fe8/2] = f1dream_17b74_lookup[++indx];
|
||||
m_ram16[0x3fea/2] = f1dream_17b74_lookup[++indx];
|
||||
m_ram16[0x3fec/2] = f1dream_17b74_lookup[++indx];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ram16[0x3fe6/2] = 0x00ff;
|
||||
m_ram16[0x3fe8/2] = 0x00ff;
|
||||
m_ram16[0x3fea/2] = 0x00ff;
|
||||
m_ram16[0x3fec/2] = 0x00ff;
|
||||
}
|
||||
}
|
||||
else if ((prevpc == 0x27f8) || (prevpc == 0x511a) || (prevpc == 0x5142) || (prevpc == 0x516a))
|
||||
{
|
||||
/* The main CPU stuffs the byte for the soundlatch into 0xfffffd.*/
|
||||
m_soundlatch->write(space,2,m_ram16[0x3ffc/2]);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(tigeroad_state::f1dream_control_w)
|
||||
{
|
||||
logerror("%s protection write, FFE1 Value:%01x\n",machine().describe_context(), m_ram16[0x3fe0/2]);
|
||||
f1dream_protection_w(space);
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(pushman_state::mcu_comm_r)
|
||||
{
|
||||
switch (offset & 0x03)
|
||||
|
Loading…
Reference in New Issue
Block a user