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(?)
This commit is contained in:
David Haywood 2020-05-05 15:19:42 +01:00 committed by GitHub
parent d992da5df8
commit 712bd80fe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 395 additions and 201 deletions

View File

@ -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- <unknown, always high, irq ack?>*/
}
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 )

View File

@ -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<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<screen_device> m_screen;
required_shared_ptr<u8> 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<u8> m_mcu_sharedram;
required_shared_ptr<u8> 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<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_subcpu;
optional_device<cpu_device> m_subcpu; // kicknrun / mexico86 only
optional_device<cpu_device> m_mcu;
optional_device<m68705p_device> m_68705mcu;
required_device<ym2203_device> m_ymsnd;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<screen_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<m68705p_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;
};

View File

@ -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);

View File

@ -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;