From 712bd80fe6dd69a4dbdb7947db1fe077ebe44402 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Tue, 5 May 2020 15:19:42 +0100 Subject: [PATCH] hooked up kicknrun MCU [dink] (#6639) * - hooked up kicknrun MCU [dink] - split up kikikai class [David Haywood] * remove note (nw) * this IS demo sounds (nw) * core changes not wanted(?) --- src/mame/drivers/kikikai.cpp | 280 ++++++++++++++++++++++++++--------- src/mame/includes/kikikai.h | 173 ++++++++++++++-------- src/mame/machine/kikikai.cpp | 139 ++++++++--------- src/mame/video/kikikai.cpp | 4 +- 4 files changed, 395 insertions(+), 201 deletions(-) diff --git a/src/mame/drivers/kikikai.cpp b/src/mame/drivers/kikikai.cpp index dd587149397..f8fd906e102 100644 --- a/src/mame/drivers/kikikai.cpp +++ b/src/mame/drivers/kikikai.cpp @@ -24,10 +24,6 @@ Notes: To set it up, just enable the single board 4p mode and keep the master/slave mode to off and the board ID to master. -- kicknrun the MC6801U4 mcu has been decapped and it's internal ROM has beed dumped. - Currently it's not hooked up properly, initial hook up is based the code from - Bubble Bobble - see bublbobl.ccp - - mexico86 does a PS4 STOP ERROR shortly after boot, but works afterwards. PS4 is the MC6801U4 mcu, the bootleggers replaced it with a custom programmed 68705 MCU. @@ -90,21 +86,21 @@ READ8_MEMBER(kikikai_state::kiki_ym2203_r) * *************************************/ -void kikikai_state::mexico86_map(address_map &map) +void kikikai_state::main_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0xbfff).bankr("bank1"); /* banked roms */ map(0xc000, 0xe7ff).ram().share("mainram"); /* shared with sound cpu */ map(0xe800, 0xe8ff).ram().share("mcu_sharedram"); /* shared with mcu */ map(0xe900, 0xefff).ram(); - map(0xf000, 0xf000).w(FUNC(kikikai_state::mexico86_bankswitch_w)); /* program and gfx ROM banks */ - map(0xf008, 0xf008).w(FUNC(kikikai_state::mexico86_f008_w)); /* cpu reset lines + other unknown stuff */ + map(0xf000, 0xf000).w(FUNC(kikikai_state::main_bankswitch_w)); /* program and gfx ROM banks */ + map(0xf008, 0xf008).w(FUNC(kikikai_state::main_f008_w)); /* cpu reset lines + other unknown stuff */ map(0xf010, 0xf010).portr("IN3"); map(0xf018, 0xf018).nopw(); /* watchdog? */ map(0xf800, 0xffff).ram().share("subram"); /* communication ram - to connect 4 players's subboard */ } -void kikikai_state::mexico86_sound_map(address_map &map) +void kikikai_state::sound_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0xa7ff).ram().share("mainram"); /* shared with main */ @@ -112,7 +108,7 @@ void kikikai_state::mexico86_sound_map(address_map &map) map(0xc000, 0xc001).r(FUNC(kikikai_state::kiki_ym2203_r)).w(m_ymsnd, FUNC(ym2203_device::write)); } -WRITE8_MEMBER(kikikai_state::mexico86_sub_output_w) +WRITE8_MEMBER(kikikai_state::kicknrun_sub_output_w) { /*--x- ---- coin lockout 2*/ /*---x ---- coin lockout 1*/ @@ -120,7 +116,7 @@ WRITE8_MEMBER(kikikai_state::mexico86_sub_output_w) /*---- --x- */ } -void kikikai_state::mexico86_sub_cpu_map(address_map &map) +void kikikai_state::kicknrun_sub_cpu_map(address_map &map) { map(0x0000, 0x3fff).rom(); map(0x4000, 0x47ff).ram(); /* sub cpu ram */ @@ -129,7 +125,7 @@ void kikikai_state::mexico86_sub_cpu_map(address_map &map) map(0xc001, 0xc001).portr("IN5"); map(0xc002, 0xc002).portr("IN6"); map(0xc003, 0xc003).portr("IN7"); - map(0xc004, 0xc004).w(FUNC(kikikai_state::mexico86_sub_output_w)); + map(0xc004, 0xc004).w(FUNC(kikikai_state::kicknrun_sub_output_w)); } /************************************* @@ -138,6 +134,130 @@ void kikikai_state::mexico86_sub_cpu_map(address_map &map) * *************************************/ +static INPUT_PORTS_START( kicknrun ) + PORT_START("IN0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) + 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_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + + PORT_START("IN1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) /* service 2 */ + + PORT_START("IN2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("DSW0") + /* When Bit 1 is On, the machine waits a signal from another one */ + /* Seems like if you can join two cabinets, one as master */ + /* and the other as slave, probably to play four players. */ + PORT_DIPNAME( 0x01, 0x01, "Master/Slave Mode" ) PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:2") // Screen ? + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_SERVICE( 0x04, IP_ACTIVE_LOW ) PORT_DIPLOCATION("SW1:3") + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:4") // Demo Sounds only play every 8th Demo + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6") + PORT_DIPSETTING( 0x10, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x20, DEF_STR( 1C_2C ) ) + PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8") + PORT_DIPSETTING( 0x40, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0xc0, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x80, DEF_STR( 1C_2C ) ) + + PORT_START("DSW1") + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2") + PORT_DIPSETTING( 0x03, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + PORT_DIPNAME( 0x0c, 0x08, "Playing Time" ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x00, "40 Seconds" ) + PORT_DIPSETTING( 0x0c, "One Minute" ) + PORT_DIPSETTING( 0x08, "One Minute and 20 Sec." ) + PORT_DIPSETTING( 0x04, "One Minute and 40 Sec." ) + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:5") + PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + /* The following dip seems to be related with the first one */ + PORT_DIPNAME( 0x20, 0x20, "Board ID" ) PORT_DIPLOCATION("SW2:6") + PORT_DIPSETTING( 0x20, "Master" ) + PORT_DIPSETTING( 0x00, "Slave" ) + PORT_DIPNAME( 0x40, 0x40, "Number of Matches" ) PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING( 0x00, "2" ) + PORT_DIPSETTING( 0x40, "6" ) + PORT_DIPNAME( 0x80, 0x80, "Single board 4 Players Mode" ) PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + + PORT_START("IN3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_TILT ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) //p3 service + + PORT_START("IN5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) //p4 service + + PORT_START("IN6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH,IPT_COIN3 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START3 ) + PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH,IPT_COIN4 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START4 ) + PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNKNOWN ) +INPUT_PORTS_END + static INPUT_PORTS_START( mexico86 ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) @@ -400,53 +520,75 @@ void kikikai_state::machine_start() membank("bank1")->configure_entries(0, 6, &ROM[0x08000], 0x4000); + save_item(NAME(m_charbank)); + +} + +void mexico86_state::machine_start() +{ + kikikai_state::machine_start(); + save_item(NAME(m_port_a_out)); save_item(NAME(m_port_b_out)); save_item(NAME(m_address)); save_item(NAME(m_latch)); + m_port_a_out = 0xff; + m_port_b_out = 0xff; +} + +void kikikai_simulation_state::machine_start() +{ + kikikai_state::machine_start(); + save_item(NAME(m_kikikai_simulated_mcu_running)); save_item(NAME(m_kikikai_simulated_mcu_initialised)); save_item(NAME(m_coin_last)); save_item(NAME(m_coin_fract)); - - save_item(NAME(m_charbank)); - - m_port_a_out = 0xff; - m_port_b_out = 0xff; } + void kikikai_state::machine_reset() { /*TODO: check the PCB and see how the halt / reset lines are connected. */ if (m_subcpu != nullptr) m_subcpu->set_input_line(INPUT_LINE_RESET, (ioport("DSW1")->read() & 0x80) ? ASSERT_LINE : CLEAR_LINE); + m_charbank = 0; +} + +void mexico86_state::machine_reset() +{ + kikikai_state::machine_reset(); + m_address = 0; m_latch = 0; +} + +void kikikai_simulation_state::machine_reset() +{ + kikikai_state::machine_reset(); m_kikikai_simulated_mcu_running = 0; m_kikikai_simulated_mcu_initialised = 0; m_coin_last[0] = false; m_coin_last[1] = false; m_coin_fract = 0; - - m_charbank = 0; } -void kikikai_state::mexico86(machine_config &config) +void kikikai_state::base(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, 24000000/4); /* 6 MHz, Uses clock divided 24MHz OSC */ - m_maincpu->set_addrmap(AS_PROGRAM, &kikikai_state::mexico86_map); + m_maincpu->set_addrmap(AS_PROGRAM, &kikikai_state::main_map); Z80(config, m_audiocpu, 24000000/4); /* 6 MHz, Uses clock divided 24MHz OSC */ - m_audiocpu->set_addrmap(AS_PROGRAM, &kikikai_state::mexico86_sound_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &kikikai_state::sound_map); m_audiocpu->set_vblank_int("screen", FUNC(kikikai_state::irq0_line_hold)); Z80(config, m_subcpu, 8000000/2); /* 4 MHz, Uses 8Mhz OSC */ - m_subcpu->set_addrmap(AS_PROGRAM, &kikikai_state::mexico86_sub_cpu_map); + m_subcpu->set_addrmap(AS_PROGRAM, &kikikai_state::kicknrun_sub_cpu_map); m_subcpu->set_vblank_int("screen", FUNC(kikikai_state::irq0_line_hold)); /* 100 CPU slices per frame - high value to ensure proper synchronization of the CPUs */ @@ -454,11 +596,8 @@ void kikikai_state::mexico86(machine_config &config) /* video hardware */ SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); /* frames per second, vblank duration */ - m_screen->set_size(32*8, 32*8); - m_screen->set_visarea(0*8, 32*8-1, 2*8, 30*8-1); - m_screen->set_screen_update(FUNC(kikikai_state::screen_update_mexico86)); + m_screen->set_raw(24000000/4, 384, 0, 256, 264, 16, 240); + m_screen->set_screen_update(FUNC(kikikai_state::screen_update_kicknrun)); m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_mexico86); @@ -476,62 +615,66 @@ void kikikai_state::mexico86(machine_config &config) m_ymsnd->add_route(3, "mono", 1.00); } -void kikikai_state::mexico86_68705(machine_config& config) -{ - mexico86(config); - - M68705P3(config, m_68705mcu, 4000000); /* xtal is 4MHz, divided by 4 internally */ - m_68705mcu->portc_r().set_ioport("IN0"); - m_68705mcu->porta_w().set(FUNC(kikikai_state::mexico86_68705_port_a_w)); - m_68705mcu->portb_w().set(FUNC(kikikai_state::mexico86_68705_port_b_w)); - m_68705mcu->set_vblank_int("screen", FUNC(kikikai_state::mexico86_m68705_interrupt)); -} void kikikai_state::mcu_map(address_map &map) { - map(0x0000, 0x0000).rw(FUNC(kikikai_state::bublbobl_mcu_ddr1_r), FUNC(kikikai_state::bublbobl_mcu_ddr1_w)); - map(0x0001, 0x0001).rw(FUNC(kikikai_state::bublbobl_mcu_ddr2_r), FUNC(kikikai_state::bublbobl_mcu_ddr2_w)); - map(0x0002, 0x0002).rw(FUNC(kikikai_state::bublbobl_mcu_port1_r), FUNC(kikikai_state::bublbobl_mcu_port1_w)); - map(0x0003, 0x0003).rw(FUNC(kikikai_state::bublbobl_mcu_port2_r), FUNC(kikikai_state::bublbobl_mcu_port2_w)); - map(0x0004, 0x0004).rw(FUNC(kikikai_state::bublbobl_mcu_ddr3_r), FUNC(kikikai_state::bublbobl_mcu_ddr3_w)); - map(0x0005, 0x0005).rw(FUNC(kikikai_state::bublbobl_mcu_ddr4_r), FUNC(kikikai_state::bublbobl_mcu_ddr4_w)); - map(0x0006, 0x0006).rw(FUNC(kikikai_state::bublbobl_mcu_port3_r), FUNC(kikikai_state::bublbobl_mcu_port3_w)); - map(0x0007, 0x0007).rw(FUNC(kikikai_state::bublbobl_mcu_port4_r), FUNC(kikikai_state::bublbobl_mcu_port4_w)); + map(0x0000, 0x0000).rw(FUNC(kikikai_state::kikikai_mcu_ddr1_r), FUNC(kikikai_state::kikikai_mcu_ddr1_w)); + map(0x0001, 0x0001).rw(FUNC(kikikai_state::kikikai_mcu_ddr2_r), FUNC(kikikai_state::kikikai_mcu_ddr2_w)); + map(0x0002, 0x0002).rw(FUNC(kikikai_state::kikikai_mcu_port1_r), FUNC(kikikai_state::kikikai_mcu_port1_w)); + map(0x0003, 0x0003).rw(FUNC(kikikai_state::kikikai_mcu_port2_r), FUNC(kikikai_state::kikikai_mcu_port2_w)); + map(0x0004, 0x0004).rw(FUNC(kikikai_state::kikikai_mcu_ddr3_r), FUNC(kikikai_state::kikikai_mcu_ddr3_w)); + map(0x0005, 0x0005).rw(FUNC(kikikai_state::kikikai_mcu_ddr4_r), FUNC(kikikai_state::kikikai_mcu_ddr4_w)); + map(0x0006, 0x0006).rw(FUNC(kikikai_state::kikikai_mcu_port3_r), FUNC(kikikai_state::kikikai_mcu_port3_w)); + map(0x0007, 0x0007).rw(FUNC(kikikai_state::kikikai_mcu_port4_r), FUNC(kikikai_state::kikikai_mcu_port4_w)); map(0x0040, 0x00ff).ram(); map(0xf000, 0xffff).rom(); } - void kikikai_state::kicknrun(machine_config& config) { - mexico86(config); + base(config); + + // Not too sure IRQs are triggered by MCU.. + m_maincpu->set_vblank_int("screen", FUNC(kikikai_state::kikikai_interrupt)); M6801(config, m_mcu, XTAL(4'000'000)); // actually 6801U4 - xtal is 4MHz, divided by 4 internally m_mcu->set_addrmap(AS_PROGRAM, &kikikai_state::mcu_map); + config.set_perfect_quantum(m_maincpu); + m_screen->screen_vblank().set_inputline(m_mcu, M6801_IRQ_LINE); // same clock latches the INT pin on the second Z80 } -void kikikai_state::knightb(machine_config &config) +void kikikai_simulation_state::kikikai(machine_config &config) +{ + base(config); + + config.device_remove("sub"); + m_screen->set_screen_update(FUNC(kikikai_simulation_state::screen_update_kikikai)); + + // IRQs should be triggered by the MCU, but we don't have it + m_maincpu->set_vblank_int("screen", FUNC(kikikai_simulation_state::kikikai_interrupt)); +} + + +void mexico86_state::mexico86_68705(machine_config& config) +{ + base(config); + + M68705P3(config, m_68705mcu, 4000000); /* xtal is 4MHz, divided by 4 internally */ + m_68705mcu->portc_r().set_ioport("IN0"); + m_68705mcu->porta_w().set(FUNC(mexico86_state::mexico86_68705_port_a_w)); + m_68705mcu->portb_w().set(FUNC(mexico86_state::mexico86_68705_port_b_w)); + m_68705mcu->set_vblank_int("screen", FUNC(mexico86_state::mexico86_m68705_interrupt)); +} + +void mexico86_state::knightb(machine_config &config) { mexico86_68705(config); config.device_remove("sub"); - m_screen->set_screen_update(FUNC(kikikai_state::screen_update_kikikai)); -} - -void kikikai_state::kikikai(machine_config &config) -{ - knightb(config); - - // IRQs should be triggered by the MCU, but we don't have it - m_maincpu->set_vblank_int("screen", FUNC(kikikai_state::kikikai_interrupt)); - - config.device_remove("68705mcu"); // we don't have code for the MC6801U4 - - /* video hardware */ - m_screen->set_screen_update(FUNC(kikikai_state::screen_update_kikikai)); + m_screen->set_screen_update(FUNC(mexico86_state::screen_update_kikikai)); } @@ -734,9 +877,10 @@ ROM_END * *************************************/ -GAME( 1986, kikikai, 0, kikikai, kikikai, kikikai_state, empty_init, ROT90, "Taito Corporation", "KiKi KaiKai", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, knightb, kikikai, knightb, kikikai, kikikai_state, empty_init, ROT90, "bootleg", "Knight Boy", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, kicknrun, 0, kicknrun, mexico86, kikikai_state, empty_init, ROT0, "Taito Corporation", "Kick and Run (World)", MACHINE_NOT_WORKING ) -GAME( 1986, kicknrunu,kicknrun, kicknrun, mexico86, kikikai_state, empty_init, ROT0, "Taito America Corp", "Kick and Run (US)", MACHINE_NOT_WORKING ) -GAME( 1986, mexico86, kicknrun, mexico86_68705, mexico86, kikikai_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, mexico86a,kicknrun, mexico86_68705, mexico86, kikikai_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, kikikai, 0, kikikai, kikikai, kikikai_simulation_state, empty_init, ROT90, "Taito Corporation", "KiKi KaiKai", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, knightb, kikikai, knightb, kikikai, mexico86_state, empty_init, ROT90, "bootleg", "Knight Boy", MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, kicknrun, 0, kicknrun, kicknrun, kikikai_state, empty_init, ROT0, "Taito Corporation", "Kick and Run (World)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, kicknrunu,kicknrun, kicknrun, kicknrun, kikikai_state, empty_init, ROT0, "Taito America Corp", "Kick and Run (US)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, mexico86, kicknrun, mexico86_68705, mexico86, mexico86_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, mexico86a,kicknrun, mexico86_68705, mexico86, mexico86_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/kikikai.h b/src/mame/includes/kikikai.h index 588a33b7354..ff3e5cc9e8f 100644 --- a/src/mame/includes/kikikai.h +++ b/src/mame/includes/kikikai.h @@ -13,81 +13,66 @@ class kikikai_state : public driver_device public: kikikai_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_mcu_sharedram(*this, "mcu_sharedram"), - m_mainram(*this, "mainram"), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), + m_screen(*this, "screen"), + m_mcu_sharedram(*this, "mcu_sharedram"), + m_mainram(*this, "mainram"), m_subcpu(*this, "sub"), m_mcu(*this, "mcu"), - m_68705mcu(*this, "68705mcu"), m_ymsnd(*this, "ymsnd"), m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_screen(*this, "screen") + m_palette(*this, "palette") { } - void knightb(machine_config &config); - void mexico86(machine_config &config); - void mexico86_68705(machine_config &config); - void kikikai(machine_config &config); + void base(machine_config &config); void kicknrun(machine_config &config); +protected: + required_device m_maincpu; + required_device m_audiocpu; + required_device m_screen; + required_shared_ptr m_mcu_sharedram; + + u32 screen_update_kicknrun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + u32 screen_update_kikikai(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + virtual void machine_start() override; + virtual void machine_reset() override; + private: /* memory pointers */ - required_shared_ptr m_mcu_sharedram; required_shared_ptr m_mainram; /* video-related */ int m_charbank; - /* mcu */ - /* mexico86 68705 protection */ - u8 m_port_a_out; - u8 m_port_b_out; - int m_address; - u8 m_latch; - /* kikikai mcu simulation */ - int m_kikikai_simulated_mcu_running; - int m_kikikai_simulated_mcu_initialised; - bool m_coin_last[2]; - u8 m_coin_fract; - /* devices */ - required_device m_maincpu; - required_device m_audiocpu; - optional_device m_subcpu; + optional_device m_subcpu; // kicknrun / mexico86 only optional_device m_mcu; - optional_device m_68705mcu; required_device m_ymsnd; required_device m_gfxdecode; required_device m_palette; - required_device m_screen; /* queue */ - u8 m_queue[64]; - int m_qfront; - int m_qstate; - DECLARE_WRITE8_MEMBER(mexico86_sub_output_w); - DECLARE_WRITE8_MEMBER(mexico86_f008_w); - DECLARE_WRITE8_MEMBER(mexico86_68705_port_a_w); - DECLARE_WRITE8_MEMBER(mexico86_68705_port_b_w); - DECLARE_WRITE8_MEMBER(mexico86_bankswitch_w); + //u8 m_queue[64]; + //int m_qfront; + //int m_qstate; + DECLARE_WRITE8_MEMBER(kicknrun_sub_output_w); + virtual DECLARE_WRITE8_MEMBER(main_f008_w); + + DECLARE_WRITE8_MEMBER(main_bankswitch_w); DECLARE_READ8_MEMBER(kiki_ym2203_r); - virtual void machine_start() override; - virtual void machine_reset() override; - u32 screen_update_mexico86(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - u32 screen_update_kikikai(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(kikikai_interrupt); - INTERRUPT_GEN_MEMBER(mexico86_m68705_interrupt); - void mcu_simulate( ); - bool mcu_coin_counter_w(bool condition); - void mexico86_map(address_map &map); - void mexico86_sound_map(address_map &map); - void mexico86_sub_cpu_map(address_map &map); + + virtual INTERRUPT_GEN_MEMBER(kikikai_interrupt); + + void main_map(address_map &map); + void sound_map(address_map &map); + void kicknrun_sub_cpu_map(address_map &map); void mcu_map(address_map& map); - /* Bubble Bobble MCU */ + /* Kiki KaiKai / Kick 'n Run MCU */ uint8_t m_ddr1; uint8_t m_ddr2; uint8_t m_ddr3; @@ -101,20 +86,82 @@ private: uint8_t m_port3_out; uint8_t m_port4_out; - DECLARE_READ8_MEMBER(bublbobl_mcu_ddr1_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_ddr1_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_ddr2_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_ddr2_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_ddr3_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_ddr3_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_ddr4_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_ddr4_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_port1_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_port1_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_port2_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_port2_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_port3_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_port3_w); - DECLARE_READ8_MEMBER(bublbobl_mcu_port4_r); - DECLARE_WRITE8_MEMBER(bublbobl_mcu_port4_w); + DECLARE_READ8_MEMBER(kikikai_mcu_ddr1_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_ddr1_w); + DECLARE_READ8_MEMBER(kikikai_mcu_ddr2_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_ddr2_w); + DECLARE_READ8_MEMBER(kikikai_mcu_ddr3_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_ddr3_w); + DECLARE_READ8_MEMBER(kikikai_mcu_ddr4_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_ddr4_w); + DECLARE_READ8_MEMBER(kikikai_mcu_port1_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_port1_w); + DECLARE_READ8_MEMBER(kikikai_mcu_port2_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_port2_w); + DECLARE_READ8_MEMBER(kikikai_mcu_port3_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_port3_w); + DECLARE_READ8_MEMBER(kikikai_mcu_port4_r); + DECLARE_WRITE8_MEMBER(kikikai_mcu_port4_w); +}; + +class mexico86_state : public kikikai_state +{ +public: + mexico86_state(const machine_config& mconfig, device_type type, const char* tag) + : kikikai_state(mconfig, type, tag), + m_68705mcu(*this, "68705mcu") + { + } + + void mexico86_68705(machine_config& config); + void knightb(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + virtual DECLARE_WRITE8_MEMBER(main_f008_w) override; + + INTERRUPT_GEN_MEMBER(mexico86_m68705_interrupt); + DECLARE_WRITE8_MEMBER(mexico86_68705_port_a_w); + DECLARE_WRITE8_MEMBER(mexico86_68705_port_b_w); + + optional_device m_68705mcu; + + /* mcu */ + /* mexico86 68705 protection */ + u8 m_port_a_out; + u8 m_port_b_out; + int m_address; + u8 m_latch; + +}; + +class kikikai_simulation_state : public kikikai_state +{ +public: + kikikai_simulation_state(const machine_config& mconfig, device_type type, const char* tag) + : kikikai_state(mconfig, type, tag) + { + } + + void kikikai(machine_config& config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + virtual DECLARE_WRITE8_MEMBER(main_f008_w) override; + + virtual INTERRUPT_GEN_MEMBER(kikikai_interrupt) override; + + void mcu_simulate( ); + + /* kikikai mcu simulation */ + int m_kikikai_simulated_mcu_running; + int m_kikikai_simulated_mcu_initialised; + bool m_coin_last[2]; + u8 m_coin_fract; }; diff --git a/src/mame/machine/kikikai.cpp b/src/mame/machine/kikikai.cpp index 628a4dbe689..1247dba7452 100644 --- a/src/mame/machine/kikikai.cpp +++ b/src/mame/machine/kikikai.cpp @@ -14,25 +14,31 @@ bit 2 = sound cpu reset line bit 1 = microcontroller reset line bit 0 = ? (unused?) */ -WRITE8_MEMBER(kikikai_state::mexico86_f008_w) +WRITE8_MEMBER(kikikai_state::main_f008_w) { m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 4) ? CLEAR_LINE : ASSERT_LINE); - if (m_68705mcu != nullptr) - { - // mexico 86, knight boy - m_68705mcu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE); - } - else - { - // simulation for KiKi KaiKai - m_kikikai_simulated_mcu_running = data & 2; - - if (!m_kikikai_simulated_mcu_running) - m_kikikai_simulated_mcu_initialised = 0; - } + m_mcu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE); } +WRITE8_MEMBER(mexico86_state::main_f008_w) +{ + m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 4) ? CLEAR_LINE : ASSERT_LINE); + + // mexico 86, knight boy + m_68705mcu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE); +} + +WRITE8_MEMBER(kikikai_simulation_state::main_f008_w) +{ + m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 4) ? CLEAR_LINE : ASSERT_LINE); + + // simulation for KiKi KaiKai + m_kikikai_simulated_mcu_running = data & 2; + + if (!m_kikikai_simulated_mcu_running) + m_kikikai_simulated_mcu_initialised = 0; +} /*************************************************************************** @@ -43,7 +49,7 @@ WRITE8_MEMBER(kikikai_state::mexico86_f008_w) ***************************************************************************/ -void kikikai_state::mcu_simulate( ) +void kikikai_simulation_state::mcu_simulate( ) { if (!m_kikikai_simulated_mcu_initialised) { @@ -180,6 +186,13 @@ void kikikai_state::mcu_simulate( ) INTERRUPT_GEN_MEMBER(kikikai_state::kikikai_interrupt) +{ + device.execute().set_input_line_vector(0, m_mcu_sharedram[0]); // Z80 + device.execute().set_input_line(0, HOLD_LINE); +} + + +INTERRUPT_GEN_MEMBER(kikikai_simulation_state::kikikai_interrupt) { if (m_kikikai_simulated_mcu_running) mcu_simulate(); @@ -188,8 +201,6 @@ INTERRUPT_GEN_MEMBER(kikikai_state::kikikai_interrupt) device.execute().set_input_line(0, HOLD_LINE); } - - #if 0 /*************************************************************************** @@ -244,13 +255,13 @@ void kikikai_state::kiki_clogic(int address, int latch) ***************************************************************************/ -INTERRUPT_GEN_MEMBER(kikikai_state::mexico86_m68705_interrupt) +INTERRUPT_GEN_MEMBER(mexico86_state::mexico86_m68705_interrupt) { device.execute().set_input_line(M68705_IRQ_LINE, ASSERT_LINE); } -WRITE8_MEMBER(kikikai_state::mexico86_68705_port_a_w) +WRITE8_MEMBER(mexico86_state::mexico86_68705_port_a_w) { //logerror("%s: 68705 port A write %02x\n", machine().describe_context(), data); m_port_a_out = data; @@ -274,7 +285,7 @@ WRITE8_MEMBER(kikikai_state::mexico86_68705_port_a_w) * 7 W not used? */ -WRITE8_MEMBER(kikikai_state::mexico86_68705_port_b_w) +WRITE8_MEMBER(mexico86_state::mexico86_68705_port_b_w) { //logerror("%s: 68705 port B write %02x\n", machine().describe_context(), data); @@ -329,145 +340,137 @@ WRITE8_MEMBER(kikikai_state::mexico86_68705_port_b_w) /*************************************************************************** -Bubble Bobble MCU (assume all this to be wrong - not yet adapted for Kick and Run) +Kiki KaiKai / Kick 'n Run MCU ***************************************************************************/ -READ8_MEMBER(kikikai_state::bublbobl_mcu_ddr1_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_ddr1_r) { return m_ddr1; } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_ddr1_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_ddr1_w) { m_ddr1 = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_ddr2_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_ddr2_r) { return m_ddr2; } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_ddr2_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_ddr2_w) { m_ddr2 = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_ddr3_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_ddr3_r) { return m_ddr3; } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_ddr3_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_ddr3_w) { m_ddr3 = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_ddr4_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_ddr4_r) { return m_ddr4; } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_ddr4_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_ddr4_w) { m_ddr4 = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_port1_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_port1_r) { //logerror("%04x: 6801U4 port 1 read\n", m_mcu->pc()); m_port1_in = ioport("IN0")->read(); return (m_port1_out & m_ddr1) | (m_port1_in & ~m_ddr1); } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_port1_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_port1_w) { //logerror("%04x: 6801U4 port 1 write %02x\n", m_mcu->pc(), data); - // bit 4: coin lockout - machine().bookkeeping().coin_lockout_global_w(~data & 0x10); - - // bit 5: select 1-way or 2-way coin counter - - // bit 6: trigger IRQ on main CPU (jumper switchable to vblank) - // trigger on high->low transition - if ((m_port1_out & 0x40) && (~data & 0x40)) - { - // logerror("triggering IRQ on main CPU\n"); - m_maincpu->set_input_line_vector(0, m_mcu_sharedram[0]); // Z80 - m_maincpu->set_input_line(0, HOLD_LINE); + // bit 0, 1: coin counters (?) + if (data & 0x01 && ~m_port1_out & 0x01) { + machine().bookkeeping().coin_counter_w(0, data & 0x01); } - // bit 7: select read or write shared RAM + if (data & 0x02 && ~m_port1_out & 0x02) { + machine().bookkeeping().coin_counter_w(1, data & 0x02); + } + + // bit 4, 5: coin lockouts + machine().bookkeeping().coin_lockout_w(0, ~data & 0x10); + machine().bookkeeping().coin_lockout_w(0, ~data & 0x20); + + // bit 7: ? (set briefly while MCU boots) m_port1_out = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_port2_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_port2_r) { //logerror("%04x: 6801U4 port 2 read\n", m_mcu->pc()); return (m_port2_out & m_ddr2) | (m_port2_in & ~m_ddr2); } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_port2_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_port2_w) { //logerror("%04x: 6801U4 port 2 write %02x\n", m_mcu->pc(), data); - static const char *const portnames[] = { "DSW0", "DSW1", "IN1", "IN2" }; + static const char *const portnames[] = { "IN1", "IN2" }; - // bits 0-3: bits 8-11 of shared RAM address - - // bit 4: clock (goes to PAL A78-04.12) - // latch on low->high transition - if ((~m_port2_out & 0x10) && (data & 0x10)) + // bit 2: clock + // latch on high->low transition + if ((m_port2_out & 0x04) && (~data & 0x04)) { - int address = m_port4_out | ((data & 0x0f) << 8); + int address = m_port4_out; - if (m_port1_out & 0x80) + if (data & 0x10) { // read - if ((address & 0x0800) == 0x0000) + if (data & 0x01) { - m_port3_in = ioport(portnames[address & 3])->read(); + m_port3_in = m_mcu_sharedram[address]; } - else if ((address & 0x0c00) == 0x0c00) + else { - logerror("reading %02x from shared RAM %04x\n", m_port3_in, address); - m_port3_in = m_mcu_sharedram[address & 0xff /* & 0x03ff */]; + m_port3_in = ioport(portnames[address & 1])->read(); } } else { // write - if ((address & 0x0c00) == 0x0c00) - { - m_mcu_sharedram[address & 0xff /* & 0x03ff */] = m_port3_out; - logerror("writing %02x to shared RAM %04x\n", m_port3_out, address); - } + m_mcu_sharedram[address] = m_port3_out; } } m_port2_out = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_port3_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_port3_r) { //logerror("%04x: 6801U4 port 3 read\n", m_mcu->pc()); return (m_port3_out & m_ddr3) | (m_port3_in & ~m_ddr3); } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_port3_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_port3_w) { //logerror("%04x: 6801U4 port 3 write %02x\n", m_mcu->pc(), data); m_port3_out = data; } -READ8_MEMBER(kikikai_state::bublbobl_mcu_port4_r) +READ8_MEMBER(kikikai_state::kikikai_mcu_port4_r) { //logerror("%04x: 6801U4 port 4 read\n", m_mcu->pc()); return (m_port4_out & m_ddr4) | (m_port4_in & ~m_ddr4); } -WRITE8_MEMBER(kikikai_state::bublbobl_mcu_port4_w) +WRITE8_MEMBER(kikikai_state::kikikai_mcu_port4_w) { //logerror("%04x: 6801U4 port 4 write %02x\n", m_mcu->pc(), data); diff --git a/src/mame/video/kikikai.cpp b/src/mame/video/kikikai.cpp index 9d05f06650c..3ed05c6a315 100644 --- a/src/mame/video/kikikai.cpp +++ b/src/mame/video/kikikai.cpp @@ -4,7 +4,7 @@ #include "includes/kikikai.h" -WRITE8_MEMBER(kikikai_state::mexico86_bankswitch_w) +WRITE8_MEMBER(kikikai_state::main_bankswitch_w) { if ((data & 7) > 5) popmessage("Switching to invalid bank!"); @@ -16,7 +16,7 @@ WRITE8_MEMBER(kikikai_state::mexico86_bankswitch_w) -uint32_t kikikai_state::screen_update_mexico86(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t kikikai_state::screen_update_kicknrun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int offs; int sx, sy, xc, yc;