// license:BSD-3-Clause
// copyright-holders:Takahiro Nogi
/******************************************************************************
Machine Hardware for Nichibutsu Mahjong series.
Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 1999/11/05 -
******************************************************************************/
/******************************************************************************
Memo:
******************************************************************************/
#include "emu.h"
#include "machine/nb1413m3.h"
#include "cpu/z80/z80.h"
#define NB1413M3_DEBUG 0
#define NB1413M3_TIMER_BASE 20000000
DEFINE_DEVICE_TYPE(NB1413M3, nb1413m3_device, "nb1413m3", "NB1413 Mahjong Custom")
nb1413m3_device::nb1413m3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NB1413M3, tag, owner, clock),
m_maincpu(*this, "^maincpu"),
m_sndromrgntag("voice"),
m_sndrombank1(0),
m_sndrombank2(0),
m_busyctr(0),
m_outcoin_flag(1),
m_inputport(0xff),
m_busyflag(1),
m_74ls193_counter(0),
m_nmi_count(0),
m_nmi_clock(0),
m_nmi_enable(0),
m_counter(0),
m_gfxradr_l(0),
m_gfxradr_h(0),
m_gfxrombank(0),
m_outcoin_enable(0),
m_led(*this, "led0")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void nb1413m3_device::device_start()
{
m_led.resolve();
m_timer_cb = timer_alloc(TIMER_CB);
m_timer_cb->adjust(attotime::zero);
save_item(NAME(m_nb1413m3_type));
save_item(NAME(m_sndrombank1));
save_item(NAME(m_sndrombank2));
save_item(NAME(m_busyctr));
save_item(NAME(m_busyflag));
save_item(NAME(m_inputport));
save_item(NAME(m_74ls193_counter));
save_item(NAME(m_nmi_count));
save_item(NAME(m_nmi_clock));
save_item(NAME(m_nmi_enable));
save_item(NAME(m_counter));
save_item(NAME(m_gfxradr_l));
save_item(NAME(m_gfxradr_h));
save_item(NAME(m_gfxrombank));
save_item(NAME(m_outcoin_enable));
save_item(NAME(m_outcoin_flag));
}
//-------------------------------------------------
// device_reset - device-specific startup
//-------------------------------------------------
void nb1413m3_device::device_reset()
{
m_nmi_clock = 0;
m_nmi_enable = 0;
m_nmi_count = 0;
m_74ls193_counter = 0;
m_counter = 0;
m_sndromrgntag = "voice";
m_sndrombank1 = 0;
m_sndrombank2 = 0;
m_busyctr = 0;
m_busyflag = 1;
m_gfxradr_l = 0;
m_gfxradr_h = 0;
m_gfxrombank = 0;
m_inputport = 0xff;
m_outcoin_flag = 1;
}
/*****************************************************************************
DEVICE HANDLERS
*****************************************************************************/
void nb1413m3_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_CB:
timer_callback(ptr, param);
break;
default:
throw emu_fatalerror("Unknown id in nb1413m3_device::device_timer");
}
}
/* TODO: is all of this actually programmable? */
TIMER_CALLBACK_MEMBER( nb1413m3_device::timer_callback )
{
m_timer_cb->adjust(attotime::from_hz(NB1413M3_TIMER_BASE) * 256);
m_74ls193_counter++;
m_74ls193_counter &= 0x0f;
if (m_74ls193_counter == 0x0f)
{
if (m_nmi_enable)
{
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_nmi_count++;
}
switch (m_nb1413m3_type)
{
case NB1413M3_TAIWANMB:
m_74ls193_counter = 0x05;
break;
case NB1413M3_OMOTESND:
m_74ls193_counter = 0x05;
break;
case NB1413M3_PASTELG:
m_74ls193_counter = 0x02;
break;
case NB1413M3_HYHOO:
case NB1413M3_HYHOO2:
m_74ls193_counter = 0x05;
break;
}
}
}
void nb1413m3_device::nmi_clock_w(uint8_t data)
{
m_nmi_clock = data;
switch (m_nb1413m3_type)
{
case NB1413M3_APPAREL:
case NB1413M3_CITYLOVE:
case NB1413M3_MCITYLOV:
case NB1413M3_SECOLOVE:
case NB1413M3_SEIHA:
case NB1413M3_SEIHAM:
case NB1413M3_IEMOTO:
case NB1413M3_IEMOTOM:
case NB1413M3_BIJOKKOY:
case NB1413M3_BIJOKKOG:
case NB1413M3_RYUUHA:
case NB1413M3_OJOUSAN:
case NB1413M3_OJOUSANM:
case NB1413M3_KORINAI:
case NB1413M3_KORINAIM:
case NB1413M3_HOUSEMNQ:
case NB1413M3_HOUSEMN2:
case NB1413M3_LIVEGAL:
case NB1413M3_ORANGEC:
case NB1413M3_ORANGECI:
case NB1413M3_VIPCLUB:
case NB1413M3_MMSIKAKU:
case NB1413M3_KANATUEN:
case NB1413M3_KYUHITO:
m_nmi_clock -= 1;
break;
#if 1
case NB1413M3_NIGHTLOV:
m_nmi_enable = ((data & 0x08) >> 3);
m_nmi_enable |= ((data & 0x01) ^ 0x01);
m_nmi_clock -= 1;
m_sndrombank1 = 1;
break;
#endif
}
m_74ls193_counter = ((m_nmi_clock & 0xf0) >> 4);
}
uint8_t nb1413m3_device::sndrom_r(address_space &space, offs_t offset)
{
int rombank;
// get top 8 bits of the I/O port address (FIXME: do this the correct way with 16-bit addressing)
offset = (offset << 8) | (downcast<z80_device &>(space.device()).state_int(Z80_BC) >> 8);
switch (m_nb1413m3_type)
{
case NB1413M3_IEMOTO:
case NB1413M3_IEMOTOM:
case NB1413M3_SEIHA:
case NB1413M3_SEIHAM:
case NB1413M3_RYUUHA:
case NB1413M3_OJOUSAN:
case NB1413M3_OJOUSANM:
case NB1413M3_MJSIKAKU:
case NB1413M3_MMSIKAKU:
case NB1413M3_KORINAI:
case NB1413M3_KORINAIM:
rombank = (m_sndrombank2 << 1) + (m_sndrombank1 & 0x01);
break;
case NB1413M3_HYHOO:
case NB1413M3_HYHOO2:
rombank = (m_sndrombank1 & 0x01);
break;
case NB1413M3_APPAREL: // no samples
case NB1413M3_NIGHTLOV: // 0-1
case NB1413M3_SECOLOVE: // 0-1
case NB1413M3_CITYLOVE: // 0-1
case NB1413M3_MCITYLOV: // 0-1
case NB1413M3_HOUSEMNQ: // 0-1
case NB1413M3_HOUSEMN2: // 0-1
case NB1413M3_LIVEGAL: // 0-1
case NB1413M3_ORANGEC: // 0-1
case NB1413M3_ORANGECI: // 0-1
case NB1413M3_VIPCLUB: // 0-1
case NB1413M3_KAGUYA: // 0-3
case NB1413M3_KAGUYA2: // 0-3 + 4-5 for protection
case NB1413M3_BIJOKKOY: // 0-7
case NB1413M3_BIJOKKOG: // 0-7
case NB1413M3_OTONANO: // 0-7
case NB1413M3_MJCAMERA: // 0 + 4-5 for protection
case NB1413M3_IDHIMITU: // 0 + 4-5 for protection
case NB1413M3_KANATUEN: // 0 + 6 for protection
rombank = m_sndrombank1;
break;
case NB1413M3_TAIWANMB:
case NB1413M3_OMOTESND:
case NB1413M3_SCANDAL:
case NB1413M3_SCANDALM:
case NB1413M3_MJFOCUSM:
case NB1413M3_BANANADR:
offset = (((offset & 0x7f00) >> 8) | ((offset & 0x0080) >> 0) | ((offset & 0x007f) << 8));
rombank = (m_sndrombank1 >> 1);
break;
case NB1413M3_MMCAMERA:
case NB1413M3_MSJIKEN:
case NB1413M3_HANAMOMO:
case NB1413M3_TELMAHJN:
case NB1413M3_GIONBANA:
case NB1413M3_MGION:
case NB1413M3_MGMEN89:
case NB1413M3_MJFOCUS:
case NB1413M3_GALKOKU:
case NB1413M3_HYOUBAN:
case NB1413M3_MJNANPAS:
case NB1413M3_MLADYHTR:
case NB1413M3_CLUB90S:
case NB1413M3_OHPAIPEE:
case NB1413M3_TOGENKYO:
case NB1413M3_LOVEHOUS:
case NB1413M3_CHINMOKU:
case NB1413M3_GALKAIKA:
case NB1413M3_MCONTEST:
case NB1413M3_UCHUUAI:
case NB1413M3_TOKIMBSJ:
case NB1413M3_TOKYOGAL:
case NB1413M3_MAIKO:
case NB1413M3_MMAIKO:
case NB1413M3_HANAOJI:
case NB1413M3_PAIRSNB:
case NB1413M3_PAIRSTEN:
default:
rombank = (m_sndrombank1 >> 1);
break;
}
offset += 0x08000 * rombank;
#if NB1413M3_DEBUG
popmessage("Sound ROM %02X:%05X [B1:%02X B2:%02X]", rombank, offset, m_sndrombank1, m_sndrombank2);
#endif
if (offset < machine().root_device().memregion(m_sndromrgntag)->bytes())
return machine().root_device().memregion(m_sndromrgntag)->base()[offset];
else
{
popmessage("read past sound ROM length (%05x[%02X])",offset, rombank);
return 0;
}
}
void nb1413m3_device::sndrombank1_w(uint8_t data)
{
// if (data & 0x02) coin counter ?
outcoin_w(data); // (data & 0x04) >> 2;
m_nmi_enable = ((data & 0x20) >> 5);
m_sndrombank1 = (((data & 0xc0) >> 5) | ((data & 0x10) >> 4));
}
// bikkuri, to be exposed in driver
void nb1413m3_device::sndrombank1_alt_w(uint8_t data)
{
machine().bookkeeping().coin_counter_w(0, data & 0x02);
machine().bookkeeping().coin_counter_w(1, data & 0x01);
//outcoin_w(data); // (data & 0x04) >> 2;
m_outcoin_enable = (data & 0x04) >> 2;
if (m_outcoin_enable)
{
if (m_counter++ == 2)
{
m_outcoin_flag ^= 1;
m_counter = 0;
}
}
m_nmi_enable = ((data & 0x80) >> 7);
//m_sndrombank1 = (((data & 0xc0) >> 5) | ((data & 0x10) >> 4));
}
void nb1413m3_device::sndrombank2_w(uint8_t data)
{
m_sndrombank2 = (data & 0x03);
}
uint8_t nb1413m3_device::gfxrom_r(offs_t offset)
{
uint8_t *GFXROM = machine().root_device().memregion("gfx1")->base();
return GFXROM[(0x20000 * (m_gfxrombank | ((m_sndrombank1 & 0x02) << 3))) + ((0x0200 * m_gfxradr_h) + (0x0002 * m_gfxradr_l)) + (offset & 0x01)];
}
void nb1413m3_device::gfxrombank_w(uint8_t data)
{
m_gfxrombank = (((data & 0xc0) >> 4) + (data & 0x03));
}
void nb1413m3_device::gfxradr_l_w(uint8_t data)
{
m_gfxradr_l = data;
}
void nb1413m3_device::gfxradr_h_w (uint8_t data)
{
m_gfxradr_h = data;
}
void nb1413m3_device::inputportsel_w(uint8_t data)
{
m_inputport = data;
}
READ_LINE_MEMBER( nb1413m3_device::busyflag_r )
{
return m_busyflag & 0x01;
}
WRITE_LINE_MEMBER( nb1413m3_device::busyflag_w )
{
m_busyflag = state;
}
uint8_t nb1413m3_device::inputport0_r()
{
return ((machine().root_device().ioport("SYSTEM")->read() & 0xfd) | ((m_outcoin_flag & 0x01) << 1));
}
uint8_t nb1413m3_device::inputport1_r()
{
device_t &root = machine().root_device();
switch (m_nb1413m3_type)
{
case NB1413M3_HYHOO:
case NB1413M3_HYHOO2:
switch ((m_inputport ^ 0xff) & 0x07)
{
case 0x01: return root.ioport("IN0")->read();
case 0x02: return root.ioport("IN1")->read();
case 0x04: return 0xff;
default: return 0xff;
}
case NB1413M3_MSJIKEN:
case NB1413M3_TELMAHJN:
if (root.ioport("DSWA")->read() & 0x80)
{
switch ((m_inputport ^ 0xff) & 0x1f)
{
case 0x01: return root.ioport("KEY0")->read();
case 0x02: return root.ioport("KEY1")->read();
case 0x04: return root.ioport("KEY2")->read();
case 0x08: return root.ioport("KEY3")->read();
case 0x10: return root.ioport("KEY4")->read();
default: return (root.ioport("KEY0")->read() & root.ioport("KEY1")->read() & root.ioport("KEY2")->read()
& root.ioport("KEY3")->read() & root.ioport("KEY4")->read());
}
}
else return root.ioport("JAMMA2")->read();
case NB1413M3_PAIRSNB:
case NB1413M3_PAIRSTEN:
case NB1413M3_OHPAIPEE:
case NB1413M3_TOGENKYO:
return root.ioport("P1")->read();
default:
switch ((m_inputport ^ 0xff) & 0x1f)
{
case 0x01: return root.ioport("KEY0")->read();
case 0x02: return root.ioport("KEY1")->read();
case 0x04: return root.ioport("KEY2")->read();
case 0x08: return root.ioport("KEY3")->read();
case 0x10: return root.ioport("KEY4")->read();
default: return (root.ioport("KEY0")->read() & root.ioport("KEY1")->read() & root.ioport("KEY2")->read()
& root.ioport("KEY3")->read() & root.ioport("KEY4")->read());
}
}
}
uint8_t nb1413m3_device::inputport2_r()
{
device_t &root = machine().root_device();
switch (m_nb1413m3_type)
{
case NB1413M3_HYHOO:
case NB1413M3_HYHOO2:
switch ((m_inputport ^ 0xff) & 0x07)
{
case 0x01: return 0xff;
case 0x02: return 0xff;
case 0x04: return root.ioport("IN2")->read();
default: return 0xff;
}
case NB1413M3_MSJIKEN:
case NB1413M3_TELMAHJN:
if (root.ioport("DSWA")->read() & 0x80)
{
switch ((m_inputport ^ 0xff) & 0x1f)
{
case 0x01: return root.ioport("KEY5")->read();
case 0x02: return root.ioport("KEY6")->read();
case 0x04: return root.ioport("KEY7")->read();
case 0x08: return root.ioport("KEY8")->read();
case 0x10: return root.ioport("KEY9")->read();
default: return (root.ioport("KEY5")->read() & root.ioport("KEY6")->read() & root.ioport("KEY7")->read()
& root.ioport("KEY8")->read() & root.ioport("KEY9")->read());
}
}
else return root.ioport("JAMMA1")->read();
case NB1413M3_PAIRSNB:
case NB1413M3_PAIRSTEN:
case NB1413M3_OHPAIPEE:
case NB1413M3_TOGENKYO:
return root.ioport("P2")->read();
default:
switch ((m_inputport ^ 0xff) & 0x1f)
{
case 0x01: return root.ioport("KEY5")->read();
case 0x02: return root.ioport("KEY6")->read();
case 0x04: return root.ioport("KEY7")->read();
case 0x08: return root.ioport("KEY8")->read();
case 0x10: return root.ioport("KEY9")->read();
default: return (root.ioport("KEY5")->read() & root.ioport("KEY6")->read() & root.ioport("KEY7")->read()
& root.ioport("KEY8")->read() & root.ioport("KEY9")->read());
}
}
}
uint8_t nb1413m3_device::inputport3_r()
{
switch (m_nb1413m3_type)
{
case NB1413M3_TAIWANMB:
case NB1413M3_IEMOTOM:
case NB1413M3_OJOUSANM:
case NB1413M3_SEIHAM:
case NB1413M3_RYUUHA:
case NB1413M3_KORINAIM:
case NB1413M3_HYOUBAN:
case NB1413M3_TOKIMBSJ:
case NB1413M3_MJFOCUSM:
case NB1413M3_SCANDALM:
case NB1413M3_BANANADR:
case NB1413M3_FINALBNY:
case NB1413M3_MMSIKAKU:
return ((m_outcoin_flag & 0x01) << 1);
default:
return 0xff;
}
}
uint8_t nb1413m3_device::dipsw1_r()
{
device_t &root = machine().root_device();
switch (m_nb1413m3_type)
{
case NB1413M3_KANATUEN:
case NB1413M3_KYUHITO:
return root.ioport("DSWB")->read();
case NB1413M3_TAIWANMB:
return ((root.ioport("DSWA")->read() & 0xf0) | ((root.ioport("DSWB")->read() & 0xf0) >> 4));
case NB1413M3_OTONANO:
case NB1413M3_MJCAMERA:
case NB1413M3_IDHIMITU:
case NB1413M3_KAGUYA2:
return (((root.ioport("DSWA")->read() & 0x0f) << 4) | (root.ioport("DSWB")->read() & 0x0f));
case NB1413M3_SCANDAL:
case NB1413M3_SCANDALM:
case NB1413M3_MJFOCUSM:
case NB1413M3_GALKOKU:
case NB1413M3_HYOUBAN:
case NB1413M3_GALKAIKA:
case NB1413M3_MCONTEST:
case NB1413M3_UCHUUAI:
case NB1413M3_TOKIMBSJ:
case NB1413M3_TOKYOGAL:
return ((root.ioport("DSWA")->read() & 0x0f) | ((root.ioport("DSWB")->read() & 0x0f) << 4));
case NB1413M3_TRIPLEW1:
case NB1413M3_NTOPSTAR:
case NB1413M3_PSTADIUM:
case NB1413M3_TRIPLEW2:
case NB1413M3_VANILLA:
case NB1413M3_FINALBNY:
case NB1413M3_MJLSTORY:
case NB1413M3_QMHAYAKU:
case NB1413M3_MJGOTTUB:
return (((root.ioport("DSWB")->read() & 0x01) >> 0) | ((root.ioport("DSWB")->read() & 0x04) >> 1) |
((root.ioport("DSWB")->read() & 0x10) >> 2) | ((root.ioport("DSWB")->read() & 0x40) >> 3) |
((root.ioport("DSWA")->read() & 0x01) << 4) | ((root.ioport("DSWA")->read() & 0x04) << 3) |
((root.ioport("DSWA")->read() & 0x10) << 2) | ((root.ioport("DSWA")->read() & 0x40) << 1));
default:
return machine().root_device().ioport("DSWA")->read();
}
}
uint8_t nb1413m3_device::dipsw2_r()
{
device_t &root = machine().root_device();
switch (m_nb1413m3_type)
{
case NB1413M3_KANATUEN:
case NB1413M3_KYUHITO:
return root.ioport("DSWA")->read();
case NB1413M3_TAIWANMB:
return (((root.ioport("DSWA")->read() & 0x0f) << 4) | (root.ioport("DSWB")->read() & 0x0f));
case NB1413M3_OTONANO:
case NB1413M3_MJCAMERA:
case NB1413M3_IDHIMITU:
case NB1413M3_KAGUYA2:
return ((root.ioport("DSWA")->read() & 0xf0) | ((root.ioport("DSWB")->read() & 0xf0) >> 4));
case NB1413M3_SCANDAL:
case NB1413M3_SCANDALM:
case NB1413M3_MJFOCUSM:
case NB1413M3_GALKOKU:
case NB1413M3_HYOUBAN:
case NB1413M3_GALKAIKA:
case NB1413M3_MCONTEST:
case NB1413M3_UCHUUAI:
case NB1413M3_TOKIMBSJ:
case NB1413M3_TOKYOGAL:
return (((root.ioport("DSWA")->read() & 0xf0) >> 4) | (root.ioport("DSWB")->read() & 0xf0));
case NB1413M3_TRIPLEW1:
case NB1413M3_NTOPSTAR:
case NB1413M3_PSTADIUM:
case NB1413M3_TRIPLEW2:
case NB1413M3_VANILLA:
case NB1413M3_FINALBNY:
case NB1413M3_MJLSTORY:
case NB1413M3_QMHAYAKU:
case NB1413M3_MJGOTTUB:
return (((root.ioport("DSWB")->read() & 0x02) >> 1) | ((root.ioport("DSWB")->read() & 0x08) >> 2) |
((root.ioport("DSWB")->read() & 0x20) >> 3) | ((root.ioport("DSWB")->read() & 0x80) >> 4) |
((root.ioport("DSWA")->read() & 0x02) << 3) | ((root.ioport("DSWA")->read() & 0x08) << 2) |
((root.ioport("DSWA")->read() & 0x20) << 1) | ((root.ioport("DSWA")->read() & 0x80) << 0));
default:
return machine().root_device().ioport("DSWB")->read();
}
}
uint8_t nb1413m3_device::dipsw3_l_r()
{
return ((machine().root_device().ioport("DSWC")->read() & 0xf0) >> 4);
}
uint8_t nb1413m3_device::dipsw3_h_r()
{
return ((machine().root_device().ioport("DSWC")->read() & 0x0f) >> 0);
}
void nb1413m3_device::outcoin_w(uint8_t data)
{
m_outcoin_enable = (data & 0x04) >> 2;
switch (m_nb1413m3_type)
{
case NB1413M3_TAIWANMB:
case NB1413M3_IEMOTOM:
case NB1413M3_OJOUSANM:
case NB1413M3_SEIHAM:
case NB1413M3_RYUUHA:
case NB1413M3_KORINAIM:
case NB1413M3_MMSIKAKU:
case NB1413M3_HYOUBAN:
case NB1413M3_TOKIMBSJ:
case NB1413M3_MJFOCUSM:
case NB1413M3_SCANDALM:
case NB1413M3_BANANADR:
case NB1413M3_MGION:
case NB1413M3_HANAOJI:
case NB1413M3_FINALBNY:
case NB1413M3_LOVEHOUS:
case NB1413M3_MMAIKO:
if (m_outcoin_enable)
{
if (m_counter++ == 2)
{
m_outcoin_flag ^= 1;
m_counter = 0;
}
}
break;
default:
break;
}
m_led = m_outcoin_flag; // out coin
}
void nb1413m3_device::vcrctrl_w(uint8_t data)
{
if (data & 0x08)
{
popmessage(" ** VCR CONTROL ** ");
m_led = 1;
}
else
{
m_led = 0;
}
}
/* Nichibutsu Mahjong games share a common control panel */
INPUT_PORTS_START( nbmjcontrols )
PORT_START("KEY0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_KAN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_M )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_I )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_E )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_A )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_BET )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_REACH )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_N )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_J )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_F )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_B )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_RON )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_CHI )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_K )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_G )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_C )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_PON )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_L )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_H )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_D )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_BIG )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_LAST_CHANCE )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY5")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_M ) PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_I ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_E ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_A ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY6")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_N ) PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_J ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_F ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_B ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY7")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_K ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_G ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_C ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY8")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_L ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_H ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_D ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY9")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) PORT_PLAYER(2)
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_LAST_CHANCE ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
/* Hanafuda controls share part of the mahjong panel. Notice that some of the remaining
inputs are detected in Service Mode, even if we label them as IPT_UNKNOWN because they
do not correspond to actual inputs */
INPUT_PORTS_START( nbhf1_ctrl ) // used by gionbana, mgion, abunai
PORT_START("KEY0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_E )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_A )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_BET )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_HANAFUDA_YES )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_F )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_B )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_HANAFUDA_NO )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_G )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_C )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_H )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_D )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
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("KEY5")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_E ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_A ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY6")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) PORT_PLAYER(2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_HANAFUDA_YES ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_F ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_B ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY7")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_HANAFUDA_NO ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_G ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_C ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY8")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_HANAFUDA_H ) PORT_PLAYER(2)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_HANAFUDA_D ) PORT_PLAYER(2)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("KEY9")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
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 )
INPUT_PORTS_END
INPUT_PORTS_START( nbhf2_ctrl ) // used by maiko, hanaoji, hnxmasev and hnageman
PORT_INCLUDE( nbhf1_ctrl )
PORT_MODIFY("KEY0")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_HANAFUDA_YES )
PORT_MODIFY("KEY1")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_HANAFUDA_NO )
PORT_MODIFY("KEY2")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_MODIFY("KEY5")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_HANAFUDA_YES ) PORT_PLAYER(2)
PORT_MODIFY("KEY6")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_HANAFUDA_NO ) PORT_PLAYER(2)
PORT_MODIFY("KEY7")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END