summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <hazemamewip@hotmail.com>2018-04-17 20:43:22 +0100
committer R. Belmont <rb6502@users.noreply.github.com>2018-04-17 15:43:22 -0400
commiteaa91d0abdf7f35d8fc7c91666761297a45ec101 (patch)
tree1c6e797581514bca24c03d5125a8cbfe9bb44d96
parent49d25dac0661a8446af61c9be801fa9bac9ddb1c (diff)
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)
-rw-r--r--src/mame/drivers/tigeroad.cpp85
-rw-r--r--src/mame/includes/tigeroad.h31
-rw-r--r--src/mame/machine/tigeroad.cpp121
3 files changed, 103 insertions, 134 deletions
diff --git a/src/mame/drivers/tigeroad.cpp b/src/mame/drivers/tigeroad.cpp
index 38a843c684b..ed8103991e5 100644
--- a/src/mame/drivers/tigeroad.cpp
+++ b/src/mame/drivers/tigeroad.cpp
@@ -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 )
diff --git a/src/mame/includes/tigeroad.h b/src/mame/includes/tigeroad.h
index d478af6e164..e81dd2efbe9 100644
--- a/src/mame/includes/tigeroad.h
+++ b/src/mame/includes/tigeroad.h
@@ -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;
+};
diff --git a/src/mame/machine/tigeroad.cpp b/src/mame/machine/tigeroad.cpp
index b6da75c6005..190fe0a400a 100644
--- a/src/mame/machine/tigeroad.cpp
+++ b/src/mame/machine/tigeroad.cpp
@@ -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)