// license:BSD-3-Clause
// copyright-holders:David Haywood, hap
/* Ken Sei Mogura: Street Fighter II
aka Street Fighter II Whack-a-mole game */
/*
this game uses a CPS1 board as the 'Video board'
the main game is driven by an additional PCB containing a TMPZ84C011 and MB89363B
moles + hammer are physical non-video parts
https://www.youtube.com/watch?v=wk71y7OGU-k
https://www.youtube.com/watch?v=mV00MMyBBXM
https://www.youtube.com/watch?v=yQpMvRL0FfM
todo:
- we have no way of telling the physical order of the moles on the control panel vs. the reads / writes
so our moles could be in the wrong positions - maybe there are fixed patterns in the video we can use
to figure it out? * the big mole appears to be worth 2 points so that one we can identify
Additional 'DRIVE BOARD' PCB
--------------------------------------------------------------------------------------------------------------|
| |
| CN2 (20 pin) |
| KENSEI MOGURA |
| 9401-TS280 62381 62381 |
| TOGO JAPAN |
| C |
| TC55257BFL N |
| 8 |
| PROGRAM ROM (8 |
| (label KENSEI pin) |
| MOGURA |
| Ver1.0) C |
| N |
| 5 |
| (6 |
| MB89363B pin) |
| TMPZ84C011-8 TLP521-4 |
| 16.00Mhz (rotated 180 C |
| degrees) N |
| 4 |
| (4 |
| pin) |
| DIPSW1 DIPSW2 TLP521-4 |
| LEDS4,3,2,1 |
| C |
| N |
| LEDS7,6,5 1 |
| 62064 62064 62064 62064 (12 |
| CN9 pin) |
| (2*3 pin) CN6 (2pin) CN7 (15 pin) CN3 (14 pin) |
| |
--------------------------------------------------------------------------------------------------------------|
TMPZ84C011 - Toshiba Z80 + CTC + custom I/O, chip is rated 8MHz
MB89363B - Fujitsu 6-port I/O chip, basically two 8255
TC55257BFL - Toshiba 32KB SRAM
62381 - Toshiba TD62381F, common LED driver
62064 - Toshiba TD62064AF, 4ch high current darlington sink driver
TLP521-4 - Toshiba opto-isolator
Jamma (on CPS board)
(connection) (unusual use) (unusual use) (connection)
--------------------------------|----|----|----------------|----------------|
GND |GROUND | 1 | A | GROUND | GND |
GND |GROUND | 2 | B | GROUND | GND |
+5 |+5VDC | 3 | C | +5VDC | +5 |
+5 |+5VDC | 4 | D | +5VDC | +5 |
n/c |-5VDC | 5 | E | -5VDC | n/c |
+12 |+12VDC | 6 | F | +12VDC | +12 |
n/c |KEY SLOT | 7 | H | KEY SLOT | n/c |
ACK (to CN2) |COIN COUNTER 1 | 8 | J | COIN COUNTER 2 | ST4 (to CN2) |
ST2 (to CN2) |COIN LOCK 1 | 9 | K | COIN LOCK 2 | ST3 (to CN2) |
SPK+ |SPEAKER + | 10 | L | SPEAKER - | SPK- |
n/c |N/C | 11 | M | N/C | n/c |
VR |VIDEO RED | 12 | N | VIDEO GREEN | VG |
VB |VIDEO BLUE | 13 | O | VIDEO SYNC | VSYNC |
VGnd |VIDEO GROUND | 14 | R | SERVICE SWITCH | D9 (from CN2) |
n/c |TEST SWITCH | 15 | S | TILT SWITCH | n/c |
n/c |COIN 1 | 16 | T | COIN 2 | n/c |
REQ (from CN2) |P1 START | 17 | U | P2 START | LVm (from CN2) |
D8 (from CN2) |P1 UP | 18 | V | P2 UP | D4 (from CN2) |
D7 (from CN2) |P1 DOWN | 19 | W | P2 DOWN | D3 (from CN2) |
D6 (from CN2) |P1 LEFT | 20 | X | P2 LEFT | D2 (from CN2) |
D5 (from CN2) |P1 RIGHT | 21 | Y | P2 RIGHT | D1 (from CN2) |
n/c |P1 B1 | 22 | Z | P2 B1 | n/c |
n/c |P1 B2 | 23 | a | P2 B2 | n/c |
n/c |P1 B3 | 24 | b | P2 B3 | n/c |
n/c |N/C | 25 | c | N/C | n/c |
n/c |N/C | 26 | d | N/C | n/c |
GND |GROUND | 27 | e | GROUND | GND |
GND |GROUND | 28 | f | GROUND | GND |
----------------|------------------------------------------|----------------|
CN1 - 12 pin connector, various cabinet inputs / outputs
2P Start Lamp | 1
1P Start Lamp | 2
Coin Lock | 3
Coin Counter | 4
GND | 5
GND | 6
Service Sw | 7
2P Start Sw | 8
1P Start Sw | 9
Coin Sw | 10
+24V | 11
+24V | 12
CN2 - 20 pin connector, goes from DRIVE PCB to the JAMMA on CPS board
ST4 | 1
ST3 | 2
ST2 | 3
ACK | 4
n/c | 5
LVm | 6
REQ | 7
D9 | 8
D8 | 9
D7 | 10
D6 | 11
D5 | 12
D4 | 13
D3 | 14
D2 | 15
D1 | 16
GND | 17
+12 | 18
+5 | 19
GND | 20
*/
// note: I've kept this code out of cps1.c as there is likely to be a substantial amount of game specific code here ones all the extra hardware is emulated
#include "emu.h"
#include "cpu/z80/tmpz84c011.h"
#include "machine/mb89363b.h"
#include "includes/cps1.h"
#include "kenseim.lh"
class kenseim_state : public cps_state
{
public:
kenseim_state(const machine_config &mconfig, device_type type, const char *tag) :
cps_state(mconfig, type, tag),
m_to_68k_cmd_low(0),
m_to_68k_cmd_d9(0),
m_to_68k_cmd_req(0),
m_to_68k_cmd_LVm(0),
m_from68k_ack(0),
m_from68k_st4(0),
m_from68k_st3(0),
m_from68k_st2(0),
m_lamps(*this, "lamp%u", 1U)
{
for (int i = 0; i < 6; i++)
{
mole_state_a[i] = 0x00;
mole_state_b[i] = 0x00;
}
}
void mole_up(int side, int mole)
{
if (side == 0)
mole_state_a[mole] = 80;
else
mole_state_b[mole] = 80;
}
void mole_down(int side, int mole)
{
if (side == 0)
mole_state_a[mole] = 0x00;
else
mole_state_b[mole] = 0x00;
}
void update_moles()
{
for (int i = 0; i < 6; i++)
{
char temp[32];
sprintf(temp, "molea_%d", i);
output().set_value(temp, mole_state_a[i]);
}
for (int i = 0; i < 6; i++)
{
char temp[32];
sprintf(temp, "moleb_%d", i);
output().set_value(temp, mole_state_b[i]);
}
}
/* kenseim */
DECLARE_WRITE16_MEMBER(cps1_kensei_w);
void init_kenseim();
// certain
DECLARE_WRITE8_MEMBER(mb8936_portc_w); // 20x LEDs
// uncertain
DECLARE_WRITE8_MEMBER(cpu_portc_w); // 4 bit out (lamps, coinlock etc.?)
DECLARE_READ8_MEMBER(cpu_portd_r); // 4 bit in (comms flags from 68k)
DECLARE_WRITE8_MEMBER(cpu_portd_w); // 4 bit out (command flags to 68k?)
DECLARE_WRITE8_MEMBER(cpu_porte_w); // 8 bit out (command to 68k?)
WRITE8_MEMBER(mb8936_porta_w); // maybe molesa output? (6-bits?)
WRITE8_MEMBER(mb8936_portb_w); // maybe molesb output? (6-bits?)
WRITE8_MEMBER(mb8936_portf_w); // maybe strobe output?
DECLARE_CUSTOM_INPUT_MEMBER(kenseim_cmd_1234_r);
DECLARE_CUSTOM_INPUT_MEMBER(kenseim_cmd_5678_r);
DECLARE_CUSTOM_INPUT_MEMBER(kenseim_cmd_9_r);
DECLARE_CUSTOM_INPUT_MEMBER(kenseim_cmd_req_r);
DECLARE_CUSTOM_INPUT_MEMBER(kenseim_cmd_LVm_r);
void set_leds(uint32_t ledstates);
void kenseim(machine_config &config);
void kenseim_io_map(address_map &map);
void kenseim_map(address_map &map);
private:
uint8_t m_to_68k_cmd_low;
uint8_t m_to_68k_cmd_d9;
uint8_t m_to_68k_cmd_req;
uint8_t m_to_68k_cmd_LVm;
int m_from68k_ack;
int m_from68k_st4;
int m_from68k_st3;
int m_from68k_st2;
int m_led_latch;
int m_led_serial_data;
int m_led_clock;
int mole_state_a[6];
int mole_state_b[6];
output_finder<20> m_lamps;
};
/*******************************
Misc System Functions
******************************/
void kenseim_state::set_leds(uint32_t ledstates)
{
for (int i=0; i<20; i++)
m_lamps[i] = BIT(ledstates, i);
}
// could be wrong
WRITE8_MEMBER(kenseim_state::mb8936_portc_w)
{
// I'm guessing these are the 20 'power meter' LEDs, 10 for each player? (it writes 42 times, with the last write being some terminator?)
// printf("%s mb8936 write %02x to port C but no handler assigned (serial data?)\n", machine().describe_context().c_str(), data);
if (data & 0x08)
{
if (data & 0x02)
{
if (data & 0x04)
{
// send and reset? maybe?
//printf("led write reset?\n");
m_led_latch = 0;
set_leds(m_led_serial_data);
m_led_serial_data = 0;
}
else if (!(m_led_clock & 0x02))
{
//printf("write data bit %d\n", m_led_latch & 1);
m_led_serial_data = (m_led_serial_data << 1) | (m_led_latch & 1);
}
}
else
{
m_led_latch = data & 0x5;
//printf("set latch %02x\n", m_led_latch);
}
m_led_clock = data & 0x02;
}
}
WRITE8_MEMBER(kenseim_state::mb8936_porta_w) // maybe molesa output? (6-bits?)
{
//if (data&0xc0) printf("%s mb8936 write %02x to port A (mole output 1?)\n", machine().describe_context().c_str(), data);
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
mole_down(0, i);
else
mole_up(0, i);
}
update_moles();
}
WRITE8_MEMBER(kenseim_state::mb8936_portb_w) // maybe molesb output? (6-bits?)
{
//if (data&0xc0) printf("%s mb8936 write %02x to port B (mole output 2?)\n", machine().describe_context().c_str(), data);
for (int i = 0; i < 6; i++)
{
int bit = (data >> i) & 1;
if (bit)
mole_down(1, i);
else
mole_up(1, i);
}
update_moles();
}
WRITE8_MEMBER(kenseim_state::mb8936_portf_w)
{
// typically written when the 'moles' output is, maybe the 2 strobes?
//printf("%s mb8936 write %02x to port F (strobe?)\n", machine().describe_context().c_str(), data);
}
WRITE8_MEMBER(kenseim_state::cpu_portc_w)
{
// port direction is set to 4-in 4-out
// d4: coin counter
// d5: coin lock
// d6: left start button lamp
// d7: right start button lamp
machine().bookkeeping().coin_lockout_w(0, (data & 0x10) ? 0 : 1); // toggles if you attempt to insert a coin when there are already 15 coins inserted
machine().bookkeeping().coin_counter_w(0, (data & 0x20) ? 0 : 1);
output().set_value("startlamp1", (data & 0x80) ? 0 : 1);
output().set_value("startlamp2", (data & 0x40) ? 0 : 1);
}
/*******************************
Comms
******************************/
/* 68k side COMMS reads */
CUSTOM_INPUT_MEMBER(kenseim_state::kenseim_cmd_1234_r)
{
return (m_to_68k_cmd_low & 0x0f) >> 0;
}
CUSTOM_INPUT_MEMBER(kenseim_state::kenseim_cmd_5678_r)
{
return (m_to_68k_cmd_low & 0xf0) >> 4;
}
CUSTOM_INPUT_MEMBER(kenseim_state::kenseim_cmd_9_r)
{
return m_to_68k_cmd_d9;
}
CUSTOM_INPUT_MEMBER(kenseim_state::kenseim_cmd_req_r)
{
return m_to_68k_cmd_req;
}
CUSTOM_INPUT_MEMBER(kenseim_state::kenseim_cmd_LVm_r)
{
return m_to_68k_cmd_LVm;;
}
/* 68k side COMMS writes */
WRITE16_MEMBER(kenseim_state::cps1_kensei_w)
{
if (ACCESSING_BITS_8_15)
{
// NOTE: remapped from default jamma output pins:
// machine().bookkeeping().coin_counter_w(0, data & 0x0100);
// machine().bookkeeping().coin_counter_w(1, data & 0x0200);
// machine().bookkeeping().coin_lockout_w(0, ~data & 0x0400);
// machine().bookkeeping().coin_lockout_w(1, ~data & 0x0800);
// bit 15 = CPS-A custom reset?
m_from68k_ack = (data & 0x0100) >> 8;
m_from68k_st4 = (data & 0x0200) >> 9;
m_from68k_st2 = (data & 0x0400) >> 10;
m_from68k_st3 = (data & 0x0800) >> 11;
}
}
/* Z80 side COMMS reads */
READ8_MEMBER(kenseim_state::cpu_portd_r)
{
// port direction is set to 4-in 4-out
// d4: ACK
// d5: ST2
// d6: ST3
// d7: ST4
return (m_from68k_ack << 4) | (m_from68k_st2 << 5) | (m_from68k_st3 << 6) | (m_from68k_st4 << 7);
}
/* Z80 side COMMS writes */
WRITE8_MEMBER(kenseim_state::cpu_portd_w)
{
// port direction is set to 4-in 4-out
// d0: D9
// d1: REQ
// d2: LVm
// d3: N/C
m_to_68k_cmd_d9 = data >> 0 & 1;
m_to_68k_cmd_req = data >> 1 & 1;
m_to_68k_cmd_LVm = data >> 2 & 1;
}
WRITE8_MEMBER(kenseim_state::cpu_porte_w)
{
// DT1-DT8
m_to_68k_cmd_low = data;
}
void kenseim_state::kenseim_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0xffff).ram();
}
void kenseim_state::kenseim_io_map(address_map &map)
{
map(0x20, 0x27).mirror(0xff00).rw("mb89363b", FUNC(mb89363b_device::read), FUNC(mb89363b_device::write));
}
static const z80_daisy_config daisy_chain_gamecpu[] =
{
TMPZ84C011_DAISY_INTERNAL,
{ nullptr }
};
MACHINE_CONFIG_START(kenseim_state::kenseim)
cps1_12MHz(config);
/* basic machine hardware */
MCFG_DEVICE_ADD("gamecpu", TMPZ84C011, XTAL(16'000'000)/2) // tmpz84c011-8
MCFG_Z80_DAISY_CHAIN(daisy_chain_gamecpu)
MCFG_DEVICE_PROGRAM_MAP(kenseim_map)
MCFG_DEVICE_IO_MAP(kenseim_io_map)
MCFG_TMPZ84C011_PORTC_WRITE_CB(WRITE8(*this, kenseim_state, cpu_portc_w))
MCFG_TMPZ84C011_PORTD_WRITE_CB(WRITE8(*this, kenseim_state, cpu_portd_w))
MCFG_TMPZ84C011_PORTE_WRITE_CB(WRITE8(*this, kenseim_state, cpu_porte_w))
MCFG_TMPZ84C011_PORTA_READ_CB(IOPORT("DSW1"))
MCFG_TMPZ84C011_PORTB_READ_CB(IOPORT("DSW2"))
MCFG_TMPZ84C011_PORTC_READ_CB(IOPORT("CAB-IN"))
MCFG_TMPZ84C011_PORTD_READ_CB(READ8(*this, kenseim_state, cpu_portd_r))
MCFG_MB89363B_ADD("mb89363b")
// a,b,c always $80: all ports set as output
// d,e,f always $92: port D and E as input, port F as output
MCFG_MB89363B_OUT_PORTA_CB(WRITE8(*this, kenseim_state, mb8936_porta_w))
MCFG_MB89363B_OUT_PORTB_CB(WRITE8(*this, kenseim_state, mb8936_portb_w))
MCFG_MB89363B_OUT_PORTC_CB(WRITE8(*this, kenseim_state, mb8936_portc_w))
MCFG_MB89363B_IN_PORTD_CB(IOPORT("MOLEA"))
MCFG_MB89363B_IN_PORTE_CB(IOPORT("MOLEB"))
MCFG_MB89363B_OUT_PORTF_CB(WRITE8(*this, kenseim_state, mb8936_portf_w))
MCFG_QUANTUM_PERFECT_CPU("maincpu")
MACHINE_CONFIG_END
static INPUT_PORTS_START( kenseim )
// the regular CPS1 input ports are used for comms with the extra board
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED /*IPT_COIN1*/ ) // n/c
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED /*IPT_COIN2*/ ) // n/c
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, kenseim_state, kenseim_cmd_9_r, nullptr) // PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 ) // D9
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // n/c?
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, kenseim_state, kenseim_cmd_req_r, nullptr) // PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) // REQ
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, kenseim_state, kenseim_cmd_LVm_r, nullptr) // PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 ) // LVm
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // PORT_SERVICE( 0x40, IP_ACTIVE_LOW ) n/c
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // n/c?
PORT_START("IN1")
// PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) // D5
// PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) // D6
// PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) // D7
// PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) // D8
PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, kenseim_state, kenseim_cmd_5678_r, nullptr)
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED/*IPT_BUTTON1*/ ) /*PORT_PLAYER(1)*/ // n/c
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED/*IPT_BUTTON2*/ ) /*PORT_PLAYER(1)*/ // n/c
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED/*IPT_BUTTON3*/ ) /*PORT_PLAYER(1)*/ // n/c
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN ) // n/c?
// PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) // D1
// PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) // D2
// PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) // D3
// PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) // D4
PORT_BIT( 0x0f00, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, kenseim_state, kenseim_cmd_1234_r, nullptr)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED /*IPT_BUTTON1*/ ) /*PORT_PLAYER(2)*/ // n/c
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED /*IPT_BUTTON2*/ ) /*PORT_PLAYER(2)*/ // n/c
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED /*IPT_BUTTON3*/ ) /*PORT_PLAYER(2)*/ // n/c
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) // n/c?
// most of the regular CPS1 dips are unused
PORT_START("DSWA")
PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "CPSA SW(A):1" )
PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "CPSA SW(A):2" )
PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "CPSA SW(A):3" )
PORT_DIPUNUSED_DIPLOC( 0x08, 0x08, "CPSA SW(A):4" )
PORT_DIPUNUSED_DIPLOC( 0x10, 0x10, "CPSA SW(A):5" )
PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "CPSA SW(A):6" )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "CPSA SW(A):7" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "CPSA SW(A):8" )
PORT_START("DSWB")
PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "CPSA SW(B):1" )
PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "CPSA SW(B):2" )
PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "CPSA SW(B):3" )
PORT_DIPUNUSED_DIPLOC( 0x08, 0x08, "CPSA SW(B):4" )
PORT_DIPUNUSED_DIPLOC( 0x10, 0x10, "CPSA SW(B):5" )
PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "CPSA SW(B):6" )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "CPSA SW(B):7" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "CPSA SW(B):8" )
PORT_START("DSWC")
PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "CPSA SW(C):1" )
PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "CPSA SW(C):2" )
PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "CPSA SW(C):3" )
PORT_DIPNAME( 0x08, 0x08, "Freeze" ) PORT_DIPLOCATION("CPSA SW(C):4")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("CPSA SW(C):5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("CPSA SW(C):6")
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "CPSA SW(C):7" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "CPSA SW(C):8" )
// the extra board has 2 dip banks used for most game options
PORT_START("DSW1")
PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPLOCATION("DRV SW(1):1,2")
PORT_DIPSETTING( 0x00, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) )
PORT_DIPNAME( 0x0c, 0x0c, "Head Appear Once Ratio" ) PORT_DIPLOCATION("DRV SW(1):3,4")
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x04, "1" )
PORT_DIPSETTING( 0x08, "2" )
PORT_DIPSETTING( 0x0c, "3" )
PORT_DIPNAME( 0x30, 0x30, "Strength of Computer" ) PORT_DIPLOCATION("DRV SW(1):5,6")
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x10, "1" )
PORT_DIPSETTING( 0x20, "2" )
PORT_DIPSETTING( 0x30, "3" )
PORT_DIPNAME( 0x40, 0x40, "Game Time" ) PORT_DIPLOCATION("DRV SW(1):7")
PORT_DIPSETTING( 0x00, "Long (59 seconds)" )
PORT_DIPSETTING( 0x40, "Short (49 seconds)" )
PORT_DIPNAME( 0x80, 0x80, "Winner of 2 Player faces Vega" ) PORT_DIPLOCATION("DRV SW(1):8")
PORT_DIPSETTING( 0x00, DEF_STR( No ) )
PORT_DIPSETTING( 0x80, DEF_STR( Yes ) )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Unknown 1 (1-bit)" ) PORT_DIPLOCATION("DRV SW(2):1") // manual lists unused, but see code at 0x0E9E
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x01, "1" )
PORT_DIPNAME( 0x06, 0x06, "Unknown 2 (2-bit)" ) PORT_DIPLOCATION("DRV SW(2):2,3") // ^^
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x02, "1" )
PORT_DIPSETTING( 0x04, "2" )
PORT_DIPSETTING( 0x06, "3" )
PORT_DIPNAME( 0x18, 0x18, "Unknown 3 (2-bit)" ) PORT_DIPLOCATION("DRV SW(2):4,5") // ^^
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x08, "1" )
PORT_DIPSETTING( 0x10, "2" )
PORT_DIPSETTING( 0x18, "3" )
PORT_DIPUNUSED( 0x20, 0x20 ) PORT_DIPLOCATION("DRV SW(2):6") // appears unused
PORT_DIPUNUSED( 0x40, 0x40 ) PORT_DIPLOCATION("DRV SW(2):7") // apeears unused
PORT_SERVICE_DIPLOC(0x80, IP_ACTIVE_LOW, "DRV SW(2):8" )
PORT_START("CAB-IN")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Ryu Start")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("Chun-Li Start")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_START("MOLEA")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_W) // big mole (2pts)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_Q)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_E)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_A)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_S)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_CODE(KEYCODE_D)
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("MOLEB")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_8_PAD) // big mole (2pts)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // ? (see disasm, it gets checked but seems to have no noticeable effect in-game)
INPUT_PORTS_END
/* B-Board 91634B-2 */
ROM_START( kenseim )
ROM_REGION( 0x400000, "maincpu", 0 ) /* 68000 code */
ROM_LOAD16_WORD_SWAP( "knm_23.8f", 0x000000, 0x80000, CRC(f8368900) SHA1(07a8e9fffcf7be6cb154b60a0559211bc7127c5d) )
ROM_LOAD16_WORD_SWAP( "knm_21.6f", 0x100000, 0x80000, CRC(a8025e91) SHA1(24cd3f34ae96947a1101e5f5cb6cf0d1c1d66dc0) )
ROM_REGION( 0x600000, "gfx", 0 )
ROMX_LOAD( "knm_01.3a", 0x000000, 0x80000, CRC(923f0c0c) SHA1(2569543ba33900d1e9c7c3981c8fe1cb40743546) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_02.4a", 0x000002, 0x80000, CRC(fa694f67) SHA1(b1ffbeaba71619e9b52f1f50abc7dafe2f3332b1) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_03.5a", 0x000004, 0x80000, CRC(af7af02c) SHA1(ce2e0c696b50e4806f25fc69bf4455048c9fa396) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_04.6a", 0x000006, 0x80000, CRC(607a9af4) SHA1(78862e37c1fa727d9e36099e87ee17dfa9d2498f) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_05.7a", 0x200000, 0x80000, CRC(d877eee9) SHA1(d63e123fa6c1f9927cec3cf93474f31729348fd5) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_06.8a", 0x200002, 0x80000, CRC(8821a281) SHA1(216305421783baa20994eec33e26537f69f34fcb) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_07.9a", 0x200004, 0x80000, CRC(00306d09) SHA1(581c4ba6f9eb3050d6bf989016532457314441e4) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_08.10a", 0x200006, 0x80000, CRC(4a329d16) SHA1(60d66cec8c226ef49890d8b2cd82d798dfefa049) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_10.3c", 0x400000, 0x80000, CRC(ca93a942) SHA1(1f293617e6f202054690035ebe6b6e45ffe68cc9) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_11.4c", 0x400002, 0x80000, CRC(a91f3091) SHA1(7cddcd30aa6a561ce297b877611ffabfac10be28) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_12.5c", 0x400004, 0x80000, CRC(5da8303a) SHA1(de30149e323f7892bb9967a98a0d3cd9c261dc69) , ROM_GROUPWORD | ROM_SKIP(6) )
ROMX_LOAD( "knm_13.6c", 0x400006, 0x80000, CRC(889bb671) SHA1(c7952ed801343e79c06be8ed765a293e7322307b) , ROM_GROUPWORD | ROM_SKIP(6) )
ROM_REGION( 0x28000, "audiocpu", 0 ) /* 64k for the audio CPU (+banks) */
ROM_LOAD( "knm_09.12a", 0x00000, 0x08000, CRC(15394dd7) SHA1(d96413cc8fa6cd3cfdafb2ab6305e41cfd2b8874) )
ROM_CONTINUE( 0x10000, 0x18000 )
ROM_REGION( 0x40000, "oki", 0 ) /* Samples */
ROM_LOAD( "knm_18.11c", 0x00000, 0x20000, CRC(9e3e4773) SHA1(6e750a9610fabc4bf4964b5a754414d612d43dec) )
ROM_LOAD( "knm_19.12c", 0x20000, 0x20000, CRC(d6c4047f) SHA1(1259a3cbfc14c348ce4bd87b5de5e97ad252f7fb) )
ROM_REGION( 0x0200, "aboardplds", ROMREGION_ERASE00 )
ROM_LOAD( "buf1", 0x0000, 0x0117, CRC(eb122de7) SHA1(b26b5bfe258e3e184f069719f9fd008d6b8f6b9b) )
ROM_LOAD( "ioa1", 0x0000, 0x0117, CRC(59c7ee3b) SHA1(fbb887c5b4f5cb8df77cec710eaac2985bc482a6) )
ROM_LOAD( "prg1", 0x0000, 0x0117, CRC(f1129744) SHA1(a5300f301c1a08a7da768f0773fa0fe3f683b237) )
ROM_LOAD( "rom1", 0x0000, 0x0117, CRC(41dc73b9) SHA1(7d4c9f1693c821fbf84e32dd6ef62ddf14967845) )
ROM_LOAD( "sou1", 0x0000, 0x0117, CRC(84f4b2fe) SHA1(dcc9e86cc36316fe42eace02d6df75d08bc8bb6d) )
ROM_REGION( 0x0200, "bboardplds", ROMREGION_ERASE00 )
ROM_LOAD( "knm10b.1a", 0x0000, 0x0117, CRC(e40131d4) SHA1(47e9f67ecacdf1d946838815dfe7396c9c698f04) )
ROM_LOAD( "iob1.12d", 0x0000, 0x0117, CRC(3abc0700) SHA1(973043aa46ec6d5d1db20dc9d5937005a0f9f6ae) )
ROM_LOAD( "bprg1.11d", 0x0000, 0x0117, CRC(31793da7) SHA1(400fa7ac517421c978c1ee7773c30b9ed0c5d3f3) )
ROM_REGION( 0x0200, "cboardplds", ROMREGION_ERASE00 )
ROM_LOAD( "ioc1.ic7", 0x0000, 0x0104, CRC(a399772d) SHA1(55471189db573dd61e3087d12c55564291672c77) )
ROM_LOAD( "c632.ic1", 0x0000, 0x0117, CRC(0fbd9270) SHA1(d7e737b20c44d41e29ca94be56114b31934dde81) )
ROM_REGION( 0x08000, "gamecpu", 0 )
ROM_LOAD( "kensei_mogura_ver1.0.u2", 0x00000, 0x08000, CRC(725cfcfc) SHA1(5a4c6e6efe2ddb38bec3218e55a746ea0146209f) )
ROM_END
void kenseim_state::init_kenseim()
{
m_maincpu->space(AS_PROGRAM).install_write_handler(0x800030, 0x800037, write16_delegate(FUNC(kenseim_state::cps1_kensei_w),this));
init_cps1();
m_led_serial_data = 0;
m_led_clock = 0;
m_led_latch = 0;
m_lamps.resolve();
}
// 1994.04.18 is from extra PCB rom, Siguma or Sigma? (Siguma is in the ROM)
// the CPS1 board roms contain "M O G U R A 9 2 0 9 2 4" strings suggesting that part of the code was developed earlier
GAMEL( 1994, kenseim, 0, kenseim, kenseim, kenseim_state, init_kenseim, ROT0, "Capcom / Togo / Sigma", "Ken Sei Mogura: Street Fighter II (Japan 940418, Ver 1.00)", MACHINE_CLICKABLE_ARTWORK, layout_kenseim )