mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
1943: Hook up MCU to driver, remove simulation
This commit is contained in:
parent
341168a2e9
commit
8b733c17bb
@ -26,8 +26,17 @@
|
||||
TODO:
|
||||
|
||||
- use priority PROM for drawing sprites
|
||||
- hook up the C8751H-88 MCU
|
||||
- find and dump an unmodified bme01.12d to correct the 1943 Euro set
|
||||
- Accurate interrupt handling
|
||||
- Screen raw parameters
|
||||
|
||||
Notes:
|
||||
|
||||
- The MCU is actually hooked up to a lot more than it actually uses.
|
||||
It can potentially communicate with the audio CPU, read the current
|
||||
vertical line and has a vblank counter. All this isn't used by the MCU
|
||||
program, it only exchanges a value with the main CPU.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
@ -43,59 +52,21 @@
|
||||
|
||||
/* Protection Handlers */
|
||||
|
||||
void _1943_state::protection_w(u8 data)
|
||||
INTERRUPT_GEN_MEMBER(_1943_state::mcu_irq)
|
||||
{
|
||||
m_prot_value = data;
|
||||
m_mcu->set_input_line(MCS51_INT1_LINE, HOLD_LINE);
|
||||
}
|
||||
|
||||
u8 _1943_state::protection_r()
|
||||
void _1943_state::mcu_p3_w(u8 data)
|
||||
{
|
||||
// The game crashes (through a jump to 0x8000) if the return value is not what it expects..
|
||||
|
||||
switch (m_prot_value)
|
||||
// write strobe
|
||||
if (BIT(m_mcu_p3, 6) == 1 && BIT(data, 6) == 0)
|
||||
{
|
||||
// This data comes from a table at $21a containing 64 entries, even is "case", odd is return value.
|
||||
case 0x24: return 0x1d;
|
||||
case 0x60: return 0xf7;
|
||||
case 0x01: return 0xac;
|
||||
case 0x55: return 0x50;
|
||||
case 0x56: return 0xe2;
|
||||
case 0x2a: return 0x58;
|
||||
case 0xa8: return 0x13;
|
||||
case 0x22: return 0x3e;
|
||||
case 0x3b: return 0x5a;
|
||||
case 0x1e: return 0x1b;
|
||||
case 0xe9: return 0x41;
|
||||
case 0x7d: return 0xd5;
|
||||
case 0x43: return 0x54;
|
||||
case 0x37: return 0x6f;
|
||||
case 0x4c: return 0x59;
|
||||
case 0x5f: return 0x56;
|
||||
case 0x3f: return 0x2f;
|
||||
case 0x3e: return 0x3d;
|
||||
case 0xfb: return 0x36;
|
||||
case 0x1d: return 0x3b;
|
||||
case 0x27: return 0xae;
|
||||
case 0x26: return 0x39;
|
||||
case 0x58: return 0x3c;
|
||||
case 0x32: return 0x51;
|
||||
case 0x1a: return 0xa8;
|
||||
case 0xbc: return 0x33;
|
||||
case 0x30: return 0x4a;
|
||||
case 0x64: return 0x12;
|
||||
case 0x11: return 0x40;
|
||||
case 0x33: return 0x35;
|
||||
case 0x09: return 0x17;
|
||||
case 0x25: return 0x04;
|
||||
m_mcu_to_cpu = m_mcu_p0;
|
||||
m_mcu_to_audiocpu = m_mcu_p2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The bootleg expects 0x00 to be returned from the protection reads because the protection has been patched out.
|
||||
u8 _1943_state::_1943b_c007_r()
|
||||
{
|
||||
return 0;
|
||||
m_mcu_p3 = data;
|
||||
}
|
||||
|
||||
|
||||
@ -110,11 +81,11 @@ void _1943_state::c1943_map(address_map &map)
|
||||
map(0xc002, 0xc002).portr("P2");
|
||||
map(0xc003, 0xc003).portr("DSWA");
|
||||
map(0xc004, 0xc004).portr("DSWB");
|
||||
map(0xc007, 0xc007).r(FUNC(_1943_state::protection_r));
|
||||
map(0xc007, 0xc007).lr8("mcu_r", [this]() -> u8 { return m_mcu_to_cpu; });
|
||||
map(0xc800, 0xc800).w("soundlatch", FUNC(generic_latch_8_device::write));
|
||||
map(0xc804, 0xc804).w(FUNC(_1943_state::c804_w)); // ROM bank switch, screen flip
|
||||
map(0xc806, 0xc806).w("watchdog", FUNC(watchdog_timer_device::reset_w));
|
||||
map(0xc807, 0xc807).w(FUNC(_1943_state::protection_w));
|
||||
map(0xc807, 0xc807).lw8("mcu_w", [this](u8 data) { m_cpu_to_mcu = data; });
|
||||
map(0xd000, 0xd3ff).ram().w(FUNC(_1943_state::videoram_w)).share("videoram");
|
||||
map(0xd400, 0xd7ff).ram().w(FUNC(_1943_state::colorram_w)).share("colorram");
|
||||
map(0xd800, 0xd801).ram().share("scrollx");
|
||||
@ -129,11 +100,22 @@ void _1943_state::c1943_map(address_map &map)
|
||||
map(0xf000, 0xffff).ram().share("spriteram");
|
||||
}
|
||||
|
||||
void _1943_state::c1943b_map(address_map &map)
|
||||
{
|
||||
c1943_map(map);
|
||||
|
||||
// the bootleg expects 0x00 to be returned from the protection reads
|
||||
// because the protection has been patched out
|
||||
map(0xc007, 0xc007).lr8("mcu_r", [this]() -> u8 { return 0x00; });
|
||||
map(0xc807, 0xc807).noprw();
|
||||
}
|
||||
|
||||
void _1943_state::sound_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x7fff).rom();
|
||||
map(0xc000, 0xc7ff).ram();
|
||||
map(0xc800, 0xc800).r("soundlatch", FUNC(generic_latch_8_device::read));
|
||||
map(0xd800, 0xd800).lrw8("mcu", [this]() { return m_mcu_to_audiocpu; }, [this](u8 data) { m_audiocpu_to_mcu = data; });
|
||||
map(0xe000, 0xe001).w("ym1", FUNC(ym2203_device::write));
|
||||
map(0xe002, 0xe003).w("ym2", FUNC(ym2203_device::write));
|
||||
}
|
||||
@ -274,7 +256,13 @@ GFXDECODE_END
|
||||
|
||||
void _1943_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_prot_value));
|
||||
save_item(NAME(m_cpu_to_mcu));
|
||||
save_item(NAME(m_mcu_to_cpu));
|
||||
save_item(NAME(m_audiocpu_to_mcu));
|
||||
save_item(NAME(m_mcu_to_audiocpu));
|
||||
save_item(NAME(m_mcu_p0));
|
||||
save_item(NAME(m_mcu_p2));
|
||||
save_item(NAME(m_mcu_p3));
|
||||
}
|
||||
|
||||
void _1943_state::machine_reset()
|
||||
@ -283,7 +271,6 @@ void _1943_state::machine_reset()
|
||||
m_obj_on = 0;
|
||||
m_bg1_on = 0;
|
||||
m_bg2_on = 0;
|
||||
m_prot_value = 0;
|
||||
}
|
||||
|
||||
void _1943_state::_1943(machine_config &config)
|
||||
@ -297,6 +284,15 @@ void _1943_state::_1943(machine_config &config)
|
||||
audiocpu.set_addrmap(AS_PROGRAM, &_1943_state::sound_map);
|
||||
audiocpu.set_periodic_int(FUNC(_1943_state::irq0_line_hold), attotime::from_hz(4*60));
|
||||
|
||||
I8751(config, m_mcu, XTAL(24'000'000)/4); // clock unknown
|
||||
m_mcu->port_in_cb<0>().set([this](){ return m_cpu_to_mcu; });
|
||||
m_mcu->port_out_cb<0>().set([this](u8 data){ m_mcu_p0 = data; });
|
||||
m_mcu->port_in_cb<1>().set([this]{ return m_screen->vpos(); });
|
||||
m_mcu->port_in_cb<2>().set([this](){ return m_audiocpu_to_mcu; });
|
||||
m_mcu->port_out_cb<2>().set([this](u8 data){ m_mcu_p2 = data; });
|
||||
m_mcu->port_out_cb<3>().set(FUNC(_1943_state::mcu_p3_w));
|
||||
m_mcu->set_vblank_int("screen", FUNC(_1943_state::mcu_irq));
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
|
||||
// video hardware
|
||||
@ -329,6 +325,15 @@ void _1943_state::_1943(machine_config &config)
|
||||
ym2.add_route(3, "mono", 0.10);
|
||||
}
|
||||
|
||||
void _1943_state::_1943b(machine_config &config)
|
||||
{
|
||||
_1943(config);
|
||||
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &_1943_state::c1943b_map);
|
||||
|
||||
config.device_remove("mcu");
|
||||
}
|
||||
|
||||
/* ROMs */
|
||||
|
||||
ROM_START( 1943 )
|
||||
@ -914,21 +919,15 @@ void _1943_state::init_1943()
|
||||
m_mainbank->configure_entries(0, 8, &ROM[0x10000], 0x4000);
|
||||
}
|
||||
|
||||
void _1943_state::init_1943b()
|
||||
{
|
||||
init_1943();
|
||||
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0xc007, 0xc007, read8smo_delegate(FUNC(_1943_state::_1943b_c007_r),this));
|
||||
}
|
||||
|
||||
/* Game Drivers */
|
||||
GAME( 1987, 1943, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (Euro)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943u, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (US, Rev C)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943ua, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (US)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943j, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan, Rev B)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943ja, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943jah, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan, no protection hack)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943b, 1943, _1943, 1943, _1943_state, init_1943b, ROT270, "bootleg", "1943: Battle of Midway (bootleg, hack of Japan set)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943bj, 1943, _1943, 1943, _1943_state, init_1943b, ROT270, "bootleg", "1943: Midway Kaisen (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943kai, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943 Kai: Midway Kaisen (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943mii, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway Mark II (US)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (Euro)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943u, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (US, Rev C)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943ua, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway (US)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943j, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan, Rev B)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943ja, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943jah, 1943, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: Midway Kaisen (Japan, no protection hack)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943b, 1943, _1943b, 1943, _1943_state, init_1943, ROT270, "bootleg", "1943: Battle of Midway (bootleg, hack of Japan set)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943bj, 1943, _1943b, 1943, _1943_state, init_1943, ROT270, "bootleg", "1943: Midway Kaisen (bootleg)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943kai, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943 Kai: Midway Kaisen (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1987, 1943mii, 0, _1943, 1943, _1943_state, init_1943, ROT270, "Capcom", "1943: The Battle of Midway Mark II (US)", MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
|
||||
@ -19,6 +20,7 @@ public:
|
||||
_1943_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_mcu(*this, "mcu"),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_colorram(*this, "colorram"),
|
||||
m_scrollx(*this, "scrollx"),
|
||||
@ -34,13 +36,14 @@ public:
|
||||
{ }
|
||||
|
||||
void _1943(machine_config &config);
|
||||
void _1943b(machine_config &config);
|
||||
|
||||
void init_1943b();
|
||||
void init_1943();
|
||||
|
||||
private:
|
||||
/* devices / memory pointers */
|
||||
required_device<cpu_device> m_maincpu;
|
||||
optional_device<i8751_device> m_mcu;
|
||||
required_shared_ptr<u8> m_videoram;
|
||||
required_shared_ptr<u8> m_colorram;
|
||||
required_shared_ptr<u8> m_scrollx;
|
||||
@ -64,10 +67,16 @@ private:
|
||||
int m_bg2_on;
|
||||
|
||||
/* protection */
|
||||
u8 m_prot_value;
|
||||
void protection_w(u8 data);
|
||||
u8 protection_r();
|
||||
u8 _1943b_c007_r();
|
||||
u8 m_cpu_to_mcu; // ls374 at 5k
|
||||
u8 m_mcu_to_cpu; // ls374 at 6k
|
||||
u8 m_audiocpu_to_mcu; // ls374 at 5l
|
||||
u8 m_mcu_to_audiocpu; // ls374 at 6l
|
||||
u8 m_mcu_p0;
|
||||
u8 m_mcu_p2;
|
||||
u8 m_mcu_p3;
|
||||
|
||||
INTERRUPT_GEN_MEMBER(mcu_irq);
|
||||
void mcu_p3_w(u8 data);
|
||||
|
||||
void videoram_w(offs_t offset, u8 data);
|
||||
void colorram_w(offs_t offset, u8 data);
|
||||
@ -88,6 +97,7 @@ private:
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void c1943_map(address_map &map);
|
||||
void c1943b_map(address_map &map);
|
||||
void sound_map(address_map &map);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user