diff options
Diffstat (limited to 'src/mame/drivers/spdodgeb.cpp')
-rw-r--r-- | src/mame/drivers/spdodgeb.cpp | 248 |
1 files changed, 72 insertions, 176 deletions
diff --git a/src/mame/drivers/spdodgeb.cpp b/src/mame/drivers/spdodgeb.cpp index 6261d02dd80..c6adc310f7f 100644 --- a/src/mame/drivers/spdodgeb.cpp +++ b/src/mame/drivers/spdodgeb.cpp @@ -8,7 +8,6 @@ driver by Paul Hampson and Nicola Salmoria TODO: - sprite lag (the real game has quite a bit of lag too) -- double-tap tolerance (find a way to emulate MCU?) Notes: - there's probably a 63701 on the board, used for protection. It is checked @@ -27,6 +26,7 @@ Notes: #include "includes/spdodgeb.h" #include "cpu/m6502/m6502.h" +#include "cpu/m6800/m6801.h" #include "cpu/m6809/m6809.h" #include "sound/3812intf.h" #include "speaker.h" @@ -90,148 +90,26 @@ WRITE_LINE_MEMBER(spdodgeb_state::spd_adpcm_int_2) spd_adpcm_int(m_msm2, 1); } -#if 0 // default - more sensitive (state change and timing measured on real board?) -void spdodgeb_state::mcu63705_update_inputs() +READ8_MEMBER(spdodgeb_state::mcu63701_r) { - int buttons[2]; - int p,j; - - /* update running state */ - for (p = 0; p <= 1; p++) - { - int curr[2][2]; - - curr[p][0] = ioport(p ? "P2" : "P1")->read() & 0x01; - curr[p][1] = ioport(p ? "P2" : "P1")->read() & 0x02; - - for (j = 0;j <= 1;j++) - { - if (curr[p][j] == 0) - { - if (m_prev[p][j] != 0) - m_countup[p][j] = 0; - if (curr[p][j^1]) - m_countup[p][j] = 100; - m_countup[p][j]++; - m_running[p] &= ~(1 << j); - } - else - { - if (m_prev[p][j] == 0) - { - if (m_countup[p][j] < 10 && m_countdown[p][j] < 5) - m_running[p] |= 1 << j; - m_countdown[p][j] = 0; - } - m_countdown[p][j]++; - } - } - - m_prev[p][0] = curr[p][0]; - m_prev[p][1] = curr[p][1]; - } - - /* update jumping and buttons state */ - for (p = 0; p <= 1; p++) - { - int curr[2]; - - curr[p] = ioport(p ? "P2" : "P1")->read() & 0x30; - - if (m_jumped[p]) buttons[p] = 0; /* jump only momentarily flips the buttons */ - else buttons[p] = curr[p]; - - if (buttons[p] == 0x30) m_jumped[p] = 1; - if (curr[p] == 0x00) m_jumped[p] = 0; - - m_prev[p] = curr[p]; - } +// logerror("CPU #0 PC %04x: read from port %02x of 63701 data address 3801\n",m_maincpu->pc(),offset); - m_inputs[0] = ioport("P1")->read() & 0xcf; - m_inputs[1] = ioport("P2")->read() & 0x0f; - m_inputs[2] = m_running[0] | buttons[0]; - m_inputs[3] = m_running[1] | buttons[1]; + return m_inputs[offset]; } -#else // alternate - less sensitive -void spdodgeb_state::mcu63705_update_inputs() -{ -#define DBLTAP_TOLERANCE 5 - -#define R 0x01 -#define L 0x02 -#define A 0x10 -#define D 0x20 - - uint8_t curr_port[2]; - uint8_t curr_dash[2]; - int p; - - for (p=0; p<=1; p++) - { - curr_port[p] = ioport(p ? "P2" : "P1")->read(); - curr_dash[p] = 0; - - if (curr_port[p] & R) - { - if (!(m_last_port[p] & R)) - { - if (m_tapc[p]) curr_dash[p] |= R; else m_tapc[p] = DBLTAP_TOLERANCE; - } - else if (m_last_dash[p] & R) curr_dash[p] |= R; - } - else if (curr_port[p] & L) - { - if (!(m_last_port[p] & L)) - { - if (m_tapc[p+2]) curr_dash[p] |= L; else m_tapc[p+2] = DBLTAP_TOLERANCE; - } - else if (m_last_dash[p] & L) curr_dash[p] |= L; - } - - if (curr_port[p] & A && !(m_last_port[p] & A)) curr_dash[p] |= A; - if (curr_port[p] & D && !(m_last_port[p] & D)) curr_dash[p] |= D; - - m_last_port[p] = curr_port[p]; - m_last_dash[p] = curr_dash[p]; - - if (m_tapc[p ]) m_tapc[p ]--; - if (m_tapc[p+2]) m_tapc[p+2]--; - } - - m_inputs[0] = curr_port[0] & 0xcf; - m_inputs[1] = curr_port[1] & 0x0f; - m_inputs[2] = curr_dash[0]; - m_inputs[3] = curr_dash[1]; -#undef DBLTAP_TOLERANCE -#undef R -#undef L -#undef A -#undef D +void spdodgeb_state::mcu_data_w(offs_t offset, uint8_t data) +{ + m_inputs[offset] = data; } -#endif -READ8_MEMBER(spdodgeb_state::mcu63701_r) +void spdodgeb_state::mcu_status_w(uint8_t data) { -// logerror("CPU #0 PC %04x: read from port %02x of 63701 data address 3801\n",m_maincpu->pc(),offset); - - if (m_mcu63701_command == 0) return 0x6a; - else switch (offset) - { - default: - case 0: return m_inputs[0]; - case 1: return m_inputs[1]; - case 2: return m_inputs[2]; - case 3: return m_inputs[3]; - case 4: return ioport("IN1")->read(); - } + m_mcu_status = data & 0xc0; } -WRITE8_MEMBER(spdodgeb_state::mcu63701_w) +void spdodgeb_state::mcu_nmi_w(uint8_t data) { -// logerror("CPU #0 PC %04x: write %02x to 63701 control address 3800\n",m_maincpu->pc(),data); - m_mcu63701_command = data; - mcu63705_update_inputs(); + m_mcu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); } @@ -246,9 +124,9 @@ void spdodgeb_state::spdodgeb_map(address_map &map) map(0x3002, 0x3002).w(m_soundlatch, FUNC(generic_latch_8_device::write)); // map(0x3003, 0x3003).nopw(); map(0x3004, 0x3004).w(FUNC(spdodgeb_state::scrollx_lo_w)); -// map(0x3005, 0x3005).nopw(); /* mcu63701_output_w */ + map(0x3005, 0x3005).w(FUNC(spdodgeb_state::mcu_nmi_w)); map(0x3006, 0x3006).w(FUNC(spdodgeb_state::ctrl_w)); /* scroll hi, flip screen, bank switch, palette select */ - map(0x3800, 0x3800).w(FUNC(spdodgeb_state::mcu63701_w)); + map(0x3800, 0x3800).w("mculatch", FUNC(generic_latch_8_device::write)); map(0x3801, 0x3805).r(FUNC(spdodgeb_state::mcu63701_r)); map(0x4000, 0x7fff).bankr("mainbank"); map(0x8000, 0xffff).rom(); @@ -263,17 +141,30 @@ void spdodgeb_state::spdodgeb_sound_map(address_map &map) map(0x8000, 0xffff).rom().region("audiocpu", 0); } +void spdodgeb_state::mcu_map(address_map &map) +{ + map(0x0000, 0x0027).m(m_mcu, FUNC(hd63701y0_cpu_device::hd6301y_io)); + map(0x0040, 0x013f).ram(); + map(0x8080, 0x8080).r("mculatch", FUNC(generic_latch_8_device::read)); + map(0x8081, 0x8085).w(FUNC(spdodgeb_state::mcu_data_w)); + map(0xc000, 0xffff).rom().region("mcu", 0); +} -READ_LINE_MEMBER(spdodgeb_state::mcu63705_busy_r) + +READ_LINE_MEMBER(spdodgeb_state::mcu_busy_r) { +#if 0 m_toggle ^= 0x01; return m_toggle; +#else + return BIT(m_mcu_status, 7); +#endif } static INPUT_PORTS_START( spdodgeb ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(spdodgeb_state, mcu63705_busy_r) // mcu63701_busy flag + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(spdodgeb_state, mcu_busy_r) // mcu63701_busy flag PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 ) @@ -311,38 +202,36 @@ static INPUT_PORTS_START( spdodgeb ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) PORT_START("P1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Allow_Continue ) ) - PORT_DIPSETTING( 0x80, DEF_STR( No ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x04, 0x04, DEF_STR( Allow_Continue ) ) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END @@ -384,7 +273,7 @@ void spdodgeb_state::machine_start() save_item(NAME(m_adpcm_end)); save_item(NAME(m_adpcm_idle)); save_item(NAME(m_adpcm_data)); - save_item(NAME(m_mcu63701_command)); + save_item(NAME(m_mcu_status)); save_item(NAME(m_inputs)); save_item(NAME(m_tapc)); save_item(NAME(m_last_port)); @@ -398,7 +287,7 @@ void spdodgeb_state::machine_reset() m_adpcm_end[0] = m_adpcm_end[1] = 0; m_adpcm_idle[0] = m_adpcm_data[1] = 0; m_adpcm_data[0] = m_adpcm_data[1] = -1; - m_mcu63701_command = 0; + m_mcu_status = 0; memset(m_inputs, 0, sizeof(m_inputs)); memset(m_tapc, 0, sizeof(m_tapc)); m_last_port[0] = m_last_port[1] = 0; @@ -415,6 +304,15 @@ void spdodgeb_state::spdodgeb(machine_config &config) MC6809(config, m_audiocpu, XTAL(12'000'000)/2); // HD68A09P (1.5MHz internally) m_audiocpu->set_addrmap(AS_PROGRAM, &spdodgeb_state::spdodgeb_sound_map); + hd63701y0_cpu_device &mcu(HD63701Y0(config, m_mcu, 4'000'000)); // unknown clock + mcu.set_addrmap(AS_PROGRAM, &spdodgeb_state::mcu_map); + mcu.in_p2_cb().set_ioport("P1"); + mcu.in_p6_cb().set_ioport("P2"); + mcu.in_p5_cb().set_ioport("IN1"); + mcu.out_p5_cb().set(FUNC(spdodgeb_state::mcu_status_w)); + + GENERIC_LATCH_8(config, "mculatch"); + /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(XTAL(12'000'000)/2, 384, 0, 256, 272, 0, 240); @@ -458,9 +356,8 @@ ROM_START( spdodgeb ) ROM_REGION( 0x08000, "audiocpu", 0 ) /* audio cpu */ ROM_LOAD( "22j5-0.33", 0x00000, 0x08000, CRC(c31e264e) SHA1(0828a2094122e3934b784ec9ad7c2b89d91a83bb) ) - ROM_REGION( 0x10000, "mcu", 0 ) /* I/O mcu */ - /* Not hooked up yet, we need to add HD63701Y0 support to the hd63701 core (with extra io ports, serial ports, and timers). */ - ROM_LOAD( "22ja-0.162", 0x0c000, 0x04000, CRC(7162a97b) SHA1(d6d4ee025e73a340428345f08711cd32f9169a8c) ) + ROM_REGION( 0x04000, "mcu", 0 ) /* I/O mcu */ + ROM_LOAD( "22ja-0.162", 0x00000, 0x04000, CRC(7162a97b) SHA1(d6d4ee025e73a340428345f08711cd32f9169a8c) ) ROM_REGION( 0x40000, "text", 0 ) /* text */ ROM_LOAD( "22a-4.121", 0x00000, 0x20000, CRC(acc26051) SHA1(445224238cce420990894824d95447e3f63a9ef0) ) @@ -494,7 +391,7 @@ OSC: 12.000MHz ROMs: 22J4-0.139 - Main program 22J5-0.33 - Sound program -22JA-0.162 - HD63701Y0P (no dump) +22JA-0.162 - HD63701Y0P TJ22J4-0.121 - Text TJ22J3-0.107 / @@ -517,9 +414,8 @@ ROM_START( nkdodge ) ROM_REGION( 0x08000, "audiocpu", 0 ) /* audio cpu */ ROM_LOAD( "22j5-0.33", 0x00000, 0x08000, CRC(c31e264e) SHA1(0828a2094122e3934b784ec9ad7c2b89d91a83bb) ) - ROM_REGION( 0x10000, "mcu", 0 ) /* I/O mcu */ - /* Not hooked up yet, we need to add HD63701Y0 support to the hd63701 core (with extra io ports, serial ports, and timers). */ - ROM_LOAD( "22ja-0.162", 0x0c000, 0x04000, CRC(7162a97b) SHA1(d6d4ee025e73a340428345f08711cd32f9169a8c) ) + ROM_REGION( 0x04000, "mcu", 0 ) /* I/O mcu */ + ROM_LOAD( "22ja-0.162", 0x00000, 0x04000, CRC(7162a97b) SHA1(d6d4ee025e73a340428345f08711cd32f9169a8c) ) ROM_REGION( 0x40000, "text", 0 ) /* text */ ROM_LOAD( "tj22j4-0.121", 0x00000, 0x20000, CRC(d2922b3f) SHA1(30ad37f8355c732b545017c2fc56879256b650be) ) @@ -547,8 +443,8 @@ ROM_START( nkdodgeb ) ROM_REGION( 0x08000, "audiocpu", 0 ) /* audio cpu */ ROM_LOAD( "22j5-0.33", 0x00000, 0x08000, CRC(c31e264e) SHA1(0828a2094122e3934b784ec9ad7c2b89d91a83bb) ) - ROM_REGION( 0x10000, "mcu", 0 ) /* I/O mcu */ - ROM_LOAD( "63701.bin", 0xc000, 0x4000, NO_DUMP ) /* missing; does this bootleg board use an i/o mcu at all? */ + ROM_REGION( 0x04000, "mcu", 0 ) /* I/O mcu */ + ROM_LOAD( "hd63701y0p.n12", 0x0000, 0x4000, CRC(7162a97b) SHA1(d6d4ee025e73a340428345f08711cd32f9169a8c) BAD_DUMP ) // missing from dump, but probably also identical ROM_REGION( 0x40000, "text", 0 ) /* text */ ROM_LOAD( "10.bin", 0x00000, 0x10000, CRC(442326fd) SHA1(e0e9e1dfdca3edd6e2522f55c191b40b81b8eaff) ) |