mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
taito/kikikai.cpp: hook up kikikai MCU (#11900)
This commit is contained in:
parent
2251902b44
commit
6cdb50dff3
@ -30,17 +30,6 @@ Notes:
|
||||
turn wait forever. It's difficult to meet the required level of synchronization.
|
||||
This is kludged by filtering the 2203's busy signal.
|
||||
|
||||
- KiKi KaiKai uses a custom MC6801U4 MCU which isn't dumped. The bootleg Knight Boy
|
||||
replaces it with a 68705. The bootleg is NOT 100% equivalent to the original
|
||||
(a situation similar to Bubble Bobble): collision detection is imperfect, the
|
||||
player can't be killed by some enemies.
|
||||
I think the bootleggers put the custom mcu in a test rig, examined its bus
|
||||
activity and replicated the behaviour inaccurately because they couldn't
|
||||
figure it all out. Indeed, the 68705 code reads all the memory locations
|
||||
related to the missing collision detection, but does nothing with them.
|
||||
|
||||
- KiKi KaiKai coinage mode Type 2 doesn't work.
|
||||
|
||||
- Kick and Run is a rom swap for Kiki KaiKai as the pal chips are all A85-0x
|
||||
A85 is the Taito rom code for Kiki KaiKai. Even the MCU is socketed!
|
||||
|
||||
@ -232,14 +221,14 @@ void kikikai_state::kicknrun_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_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
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("IN1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
|
||||
@ -354,129 +343,6 @@ static INPUT_PORTS_START( kicknrun )
|
||||
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 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
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("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("SWA:1")
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SWA: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( Unknown ) ) PORT_DIPLOCATION("SWA:4")// this should be Demo Sounds, but doesn't work?
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SWA: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("SWA: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("SWB: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("SWB: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("SWB: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("SWB:6")
|
||||
PORT_DIPSETTING( 0x20, "Master" )
|
||||
PORT_DIPSETTING( 0x00, "Slave" )
|
||||
PORT_DIPNAME( 0x40, 0x40, "Number of Matches" ) PORT_DIPLOCATION("SWB:7")
|
||||
PORT_DIPSETTING( 0x00, "2" )
|
||||
PORT_DIPSETTING( 0x40, "6" )
|
||||
PORT_DIPNAME( 0x80, 0x80, "Single board 4 Players Mode" ) PORT_DIPLOCATION("SWB: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( kikikai )
|
||||
PORT_START("IN0")
|
||||
@ -650,15 +516,6 @@ void mexico86_state::machine_start()
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
void kikikai_state::machine_reset()
|
||||
@ -678,16 +535,6 @@ void mexico86_state::machine_reset()
|
||||
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;
|
||||
}
|
||||
|
||||
void kikikai_state::base(machine_config &config)
|
||||
{
|
||||
@ -727,16 +574,14 @@ void kikikai_state::base(machine_config &config)
|
||||
m_ymsnd->add_route(3, "mono", 1.00);
|
||||
}
|
||||
|
||||
void kikikai_state::kicknrun(machine_config &config)
|
||||
void kikikai_state::add_mcu(machine_config &config)
|
||||
{
|
||||
base(config);
|
||||
|
||||
// Not too sure IRQs are triggered by MCU..
|
||||
m_maincpu->set_vblank_int("screen", FUNC(kikikai_state::kikikai_interrupt));
|
||||
m_maincpu->set_irq_acknowledge_callback(FUNC(kikikai_state::mcram_vect_r));
|
||||
|
||||
M6801U4(config, m_mcu, XTAL(4'000'000)); // xtal is 4MHz, divided by 4 internally
|
||||
m_mcu->in_p1_cb().set_ioport("IN0");
|
||||
m_mcu->in_p1_cb().set_ioport("IN0").invert();
|
||||
m_mcu->out_p1_cb().set(FUNC(kikikai_state::kikikai_mcu_port1_w));
|
||||
m_mcu->out_p2_cb().set(FUNC(kikikai_state::kikikai_mcu_port2_w));
|
||||
m_mcu->out_p3_cb().set(FUNC(kikikai_state::kikikai_mcu_port3_w));
|
||||
@ -749,16 +594,20 @@ void kikikai_state::kicknrun(machine_config &config)
|
||||
}
|
||||
|
||||
|
||||
void kikikai_simulation_state::kikikai(machine_config &config)
|
||||
void kikikai_state::kicknrun(machine_config &config)
|
||||
{
|
||||
base(config);
|
||||
add_mcu(config);
|
||||
}
|
||||
|
||||
void kikikai_state::kikikai_mcu(machine_config &config)
|
||||
{
|
||||
base(config);
|
||||
|
||||
config.device_remove("sub");
|
||||
m_screen->set_screen_update(FUNC(kikikai_simulation_state::screen_update_kikikai));
|
||||
m_screen->set_screen_update(FUNC(kikikai_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));
|
||||
m_maincpu->set_irq_acknowledge_callback(FUNC(kikikai_simulation_state::mcram_vect_r));
|
||||
add_mcu(config);
|
||||
}
|
||||
|
||||
|
||||
@ -1015,11 +864,11 @@ ROM_END
|
||||
*
|
||||
*************************************/
|
||||
|
||||
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, knightba, kikikai, knightba, knightba, kikikai_state, empty_init, ROT90, "bootleg (Game Corporation)", "Knight Boy (Game Corporation bootleg)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // missing coins, can be played using service to coin
|
||||
GAME( 1986, kikikai, 0, kikikai_mcu, kikikai, kikikai_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, knightba, kikikai, knightba, knightba, kikikai_state, empty_init, ROT90, "bootleg (Game Corporation)", "Knight Boy (Game Corporation bootleg)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // missing coins, can be played using service to coin
|
||||
|
||||
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 )
|
||||
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, kicknrun, mexico86_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 1)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1986, mexico86a,kicknrun, mexico86_68705, kicknrun, mexico86_state, empty_init, ROT0, "bootleg", "Mexico 86 (bootleg of Kick and Run) (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE )
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
|
||||
void kicknrun(machine_config &config);
|
||||
void knightba(machine_config &config);
|
||||
void kikikai_mcu(machine_config &config);
|
||||
|
||||
protected:
|
||||
u32 screen_update_kicknrun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
@ -46,13 +47,15 @@ protected:
|
||||
optional_shared_ptr<u8> m_mcu_sharedram;
|
||||
|
||||
private:
|
||||
void add_mcu(machine_config &config);
|
||||
|
||||
void kicknrun_sub_output_w(uint8_t data);
|
||||
virtual void main_f008_w(uint8_t data);
|
||||
|
||||
void main_bankswitch_w(uint8_t data);
|
||||
uint8_t kiki_ym2203_r(offs_t offset);
|
||||
|
||||
virtual INTERRUPT_GEN_MEMBER(kikikai_interrupt);
|
||||
INTERRUPT_GEN_MEMBER(kikikai_interrupt);
|
||||
|
||||
void main_map(address_map &map);
|
||||
void sound_map(address_map &map);
|
||||
@ -124,31 +127,3 @@ private:
|
||||
u8 m_latch = 0U;
|
||||
|
||||
};
|
||||
|
||||
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 void main_f008_w(uint8_t data) override;
|
||||
|
||||
virtual INTERRUPT_GEN_MEMBER(kikikai_interrupt) override;
|
||||
|
||||
void mcu_simulate( );
|
||||
|
||||
/* kikikai mcu simulation */
|
||||
int m_kikikai_simulated_mcu_running = 0;
|
||||
int m_kikikai_simulated_mcu_initialised = 0;
|
||||
bool m_coin_last[2]{};
|
||||
u8 m_coin_fract = 0U;
|
||||
};
|
||||
|
@ -29,229 +29,17 @@ void mexico86_state::main_f008_w(uint8_t data)
|
||||
m_68705mcu->set_input_line(INPUT_LINE_RESET, (data & 2) ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
void kikikai_simulation_state::main_f008_w(uint8_t data)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
KiKi KaiKai MCU simulation
|
||||
|
||||
This is derived from examination of the bootleg 68705 MCU code, with an
|
||||
addition to fix collision detection which is missing from the bootleg.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void kikikai_simulation_state::mcu_simulate( )
|
||||
{
|
||||
if (!m_kikikai_simulated_mcu_initialised)
|
||||
{
|
||||
if (m_mcu_sharedram[0x01] == 0x00)
|
||||
{
|
||||
logerror("initialising MCU\n");
|
||||
m_mcu_sharedram[0x04] = 0xfc; // coin inputs
|
||||
m_mcu_sharedram[0x02] = 0xff; // player 1
|
||||
m_mcu_sharedram[0x03] = 0xff; // player 2
|
||||
m_mcu_sharedram[0x1b] = 0xff; // active player
|
||||
m_mcu_sharedram[0x06] = 0xff; // must be FF otherwise PS4 ERROR
|
||||
m_mcu_sharedram[0x07] = 0x03; // must be 03 otherwise PS4 ERROR
|
||||
m_mcu_sharedram[0x00] = 0x00;
|
||||
m_kikikai_simulated_mcu_initialised = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_kikikai_simulated_mcu_initialised)
|
||||
{
|
||||
int i;
|
||||
bool coin_curr;
|
||||
u8 coin_in_read = ioport("IN0")->read() & 3;
|
||||
|
||||
// TODO: still needs Coinage B into account
|
||||
for(int coin_idx = 0; coin_idx < 2; coin_idx++)
|
||||
{
|
||||
coin_curr = (coin_in_read & (1 << coin_idx)) == 0;
|
||||
if (coin_curr && m_coin_last[coin_idx] == false)
|
||||
{
|
||||
u8 coinage_setting = (ioport("DSW0")->read() >> (coin_idx*2 + 4)) & 3;
|
||||
|
||||
// increase credits counter
|
||||
switch(coinage_setting)
|
||||
{
|
||||
case 0: // 2c / 3c
|
||||
case 1: // 2c / 1c
|
||||
if(m_coin_fract == 1)
|
||||
{
|
||||
m_mcu_sharedram[0x01]+= (coinage_setting == 0) ? 3 : 1;
|
||||
m_coin_fract = 0;
|
||||
}
|
||||
else
|
||||
m_coin_fract ++;
|
||||
|
||||
break;
|
||||
case 2: // 1c / 2c
|
||||
case 3: // 1c / 1c
|
||||
m_mcu_sharedram[0x01]+= (coinage_setting == 2) ? 2 : 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
m_mcu_sharedram[0x0a] = 0x01; // set flag (coin inserted sound is not played otherwise)
|
||||
}
|
||||
m_coin_last[coin_idx] = coin_curr;
|
||||
}
|
||||
// Purge any coin counter higher than 9 TODO: is this limit correct?
|
||||
if(m_mcu_sharedram[0x01] > 9)
|
||||
m_mcu_sharedram[0x01] = 9;
|
||||
|
||||
m_mcu_sharedram[0x04] = 0x3c | (coin_in_read ^ 3); // coin inputs
|
||||
|
||||
m_mcu_sharedram[0x02] = bitswap<8>(ioport("IN1")->read(), 7,6,5,4,2,3,1,0); // player 1
|
||||
m_mcu_sharedram[0x03] = bitswap<8>(ioport("IN2")->read(), 7,6,5,4,2,3,1,0); // player 2
|
||||
|
||||
if (m_mcu_sharedram[0x19] == 0xaa) // player 2 active
|
||||
m_mcu_sharedram[0x1b] = m_mcu_sharedram[0x03];
|
||||
else
|
||||
m_mcu_sharedram[0x1b] = m_mcu_sharedram[0x02];
|
||||
|
||||
|
||||
for (i = 0; i < 0x10; i += 2)
|
||||
m_mcu_sharedram[i + 0xb1] = m_mcu_sharedram[i + 0xb0];
|
||||
|
||||
for (i = 0; i < 0x0a; i++)
|
||||
m_mcu_sharedram[i + 0xc0] = m_mcu_sharedram[i + 0x90] + 1;
|
||||
|
||||
if (m_mcu_sharedram[0xd1] == 0xff)
|
||||
{
|
||||
if (m_mcu_sharedram[0xd0] > 0 && m_mcu_sharedram[0xd0] < 4)
|
||||
{
|
||||
m_mcu_sharedram[0xd2] = 0x81;
|
||||
m_mcu_sharedram[0xd0] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mcu_sharedram[0xe0] > 0 && m_mcu_sharedram[0xe0] < 4)
|
||||
{
|
||||
static const u8 answers[3][16] =
|
||||
{
|
||||
{ 0x00,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x80,0x88,0x00,0x00,0x00,0x00,0x00 },
|
||||
{ 0x00,0x04,0x08,0x0C,0x10,0x14,0x18,0x1C,0x20,0x31,0x2B,0x35,0x00,0x00,0x00,0x00 },
|
||||
{ 0x00,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x03,0x0A,0x0B,0x14,0x00,0x00,0x00,0x00 },
|
||||
};
|
||||
int table = m_mcu_sharedram[0xe0] - 1;
|
||||
|
||||
for (i = 1; i < 0x10; i++)
|
||||
m_mcu_sharedram[0xe0 + i] = answers[table][i];
|
||||
m_mcu_sharedram[0xe0] = 0xff;
|
||||
}
|
||||
|
||||
if (m_mcu_sharedram[0xf0] > 0 && m_mcu_sharedram[0xf0] < 4)
|
||||
{
|
||||
m_mcu_sharedram[0xf1] = 0xb3;
|
||||
m_mcu_sharedram[0xf0] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
// The following is missing from Knight Boy
|
||||
// this should be equivalent to the obfuscated kiki_clogic() below
|
||||
{
|
||||
static const u8 db[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x18,0x00,0x00,0x00,0x00};
|
||||
u16 sy = m_mcu_sharedram[0xa0] + ((0x18) >> 1);
|
||||
u16 sx = m_mcu_sharedram[0xa1] + ((0x18) >> 1);
|
||||
|
||||
for (i = 0; i < 0x38; i += 8)
|
||||
{
|
||||
u8 hw = db[m_mcu_sharedram[0x20 + i] & 0xf];
|
||||
|
||||
if (hw)
|
||||
{
|
||||
u16 xdiff = sx - (u16(m_mcu_sharedram[0x20 + i + 6]) << 8 | m_mcu_sharedram[0x20 + i + 7]);
|
||||
if (xdiff < hw)
|
||||
{
|
||||
u16 ydiff = sy - (u16(m_mcu_sharedram[0x20 + i + 4]) << 8 | m_mcu_sharedram[0x20 + i + 5]);
|
||||
if (ydiff < hw)
|
||||
m_mcu_sharedram[0xa2] = 1; // we have a collision
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INTERRUPT_GEN_MEMBER(kikikai_state::kikikai_interrupt)
|
||||
{
|
||||
device.execute().set_input_line(0, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
INTERRUPT_GEN_MEMBER(kikikai_simulation_state::kikikai_interrupt)
|
||||
{
|
||||
if (m_kikikai_simulated_mcu_running)
|
||||
mcu_simulate();
|
||||
|
||||
device.execute().set_input_line(0, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
IRQ_CALLBACK_MEMBER(kikikai_state::mcram_vect_r)
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
|
||||
return m_mcu_sharedram[0];
|
||||
}
|
||||
|
||||
#if 0
|
||||
/***************************************************************************
|
||||
|
||||
Collision logic used by Kiki Kaikai (theoretical)
|
||||
|
||||
***************************************************************************/
|
||||
#define KIKI_CL_OUT 0xa2
|
||||
#define KIKI_CL_TRIGGER 0xa3
|
||||
#define DCWIDTH 0
|
||||
#define DCHEIGHT 0
|
||||
|
||||
void kikikai_state::kiki_clogic(int address, int latch)
|
||||
{
|
||||
static const u8 db[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x18,0x00,0x00,0x00,0x00};
|
||||
int sy, sx, hw, i, qptr, diff1, diff2;
|
||||
|
||||
if (address != KIKI_CL_TRIGGER) // m_queue latched data
|
||||
{
|
||||
m_queue[m_qfront++] = latch;
|
||||
m_qfront &= 0x3f;
|
||||
}
|
||||
else if (m_qstate ^= 1) // scan m_queue
|
||||
{
|
||||
sy = m_queue[(m_qfront-0x3a)&0x3f] + ((0x18-DCHEIGHT)>>1);
|
||||
sx = m_queue[(m_qfront-0x39)&0x3f] + ((0x18-DCWIDTH)>>1);
|
||||
|
||||
for (i=0x38; i; i-=8)
|
||||
{
|
||||
qptr = m_qfront - i;
|
||||
if (!(hw = db[m_queue[qptr&0x3f]&0xf])) continue;
|
||||
|
||||
diff1 = sx - (short)(m_queue[(qptr+6)&0x3f]<<8|m_queue[(qptr+7)&0x3f]) + DCWIDTH;
|
||||
diff2 = diff1 - (hw + DCWIDTH);
|
||||
if ((diff1^diff2)<0)
|
||||
{
|
||||
diff1 = sy - (short)(m_queue[(qptr+4)&0x3f]<<8|m_queue[(qptr+5)&0x3f]) + DCHEIGHT;
|
||||
diff2 = diff1 - (hw + DCHEIGHT);
|
||||
if ((diff1^diff2)<0)
|
||||
m_mcu_sharedram[KIKI_CL_OUT] = 1; // we have a collision
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Mexico 86 68705 protection interface
|
||||
|
Loading…
Reference in New Issue
Block a user