taito/sbmjb.cpp: write a TAITOIO_OPTO device, fix coin insertions

This commit is contained in:
angelosa 2023-11-19 23:10:00 +01:00
parent 648fdffe94
commit 633d0a24c5
3 changed files with 152 additions and 8 deletions

View File

@ -48,6 +48,8 @@
#include "sound/okim6295.h"
#include "sound/ymopn.h"
#include "taitoio_opto.h"
#include "screen.h"
#include "speaker.h"
@ -60,7 +62,8 @@ public:
sbmjb_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_vdpcpu(*this, "vdpcpu")
m_vdpcpu(*this, "vdpcpu"),
m_opto(*this, "opto")
{ }
void honooinv(machine_config &config);
@ -69,6 +72,7 @@ public:
private:
required_device<cpu_device> m_maincpu;
required_device<tc0091lvc_device> m_vdpcpu;
required_device<taitoio_opto_device> m_opto;
void screen_vblank(int state);
@ -146,8 +150,8 @@ static INPUT_PORTS_START( honooinv ) // no dips on PCB, game options selectable
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("Crt-Key") // in I/O test
PORT_SERVICE( 0x08, IP_ACTIVE_LOW ) // 'Operate Sw' in test mode
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3) PORT_NAME("All Clear Sw") // in I/O test
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN1 ) // in I/O test; TODO: active high works correctly in I/O test but not in-game?
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN2 ) // in I/O test; TODO: active high works correctly in I/O test but not in-game?
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_h_r)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_l_r)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) // in I/O test
PORT_START("IN3")
@ -177,12 +181,15 @@ static INPUT_PORTS_START( bubbroul )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM )
PORT_SERVICE( 0x04, IP_ACTIVE_LOW )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("100 Yen Switch")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_h_r)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_l_r)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
static INPUT_PORTS_START( sbmjb ) // no dips on PCB, game options selectable in test mode
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Bet 5")
@ -199,8 +206,8 @@ static INPUT_PORTS_START( sbmjb ) // no dips on PCB, game options selectable in
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) // Hopper Sensor, active high or it will stop booting due to hopper related problems
PORT_SERVICE( 0x04, IP_ACTIVE_LOW )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("100 Yen Switch")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 ) // TODO: active high doesn't allow coining in but it also doesn't cause the medal in error
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 ) // TODO: active high doesn't allow coining in but it also doesn't cause the medal in error
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_h_r)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("opto", taitoio_opto_device, opto_l_r)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // No effect in test mode
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // No effect in test mode
INPUT_PORTS_END
@ -221,7 +228,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(sbmjb_state::scanline_callback) // TODO: copy-paste
}
}
void sbmjb_state::sbmjb(machine_config &config)
{
// basic machine hardware
@ -242,6 +248,8 @@ void sbmjb_state::sbmjb(machine_config &config)
io.in_port2_cb().set_ioport("IN1");
// TODO: rest of ports. port9 medal / hopper?
TAITOIO_OPTO(config, "opto", 0);
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); // all wrong
screen.set_refresh_hz(60);

View File

@ -0,0 +1,93 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/**************************************************************************************************
Taito Opto(meter?) coin input device
Detects coin weight tied to a non-JAMMA harness.
Parent Jack pinout has two input pins, labeled "in medal sen(sor?)" and "coin drop".
Used by Taito gambling/medal games:
- taito/pkspirit.cpp
- taito/sbmjb.cpp
- taito/taito_o.cpp
**************************************************************************************************/
#include "emu.h"
#include "taitoio_opto.h"
DEFINE_DEVICE_TYPE(TAITOIO_OPTO, taitoio_opto_device, "taitoio_opto", "Taito I/O Opto coin slot")
taitoio_opto_device::taitoio_opto_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, TAITOIO_OPTO, tag, owner, clock)
, m_coin_in(*this, "COIN")
{
}
void taitoio_opto_device::device_start()
{
m_opto_timer = timer_alloc(FUNC(taitoio_opto_device::opto_clear_cb), this);
save_item(NAME(m_opto_h));
save_item(NAME(m_opto_l));
}
void taitoio_opto_device::device_reset()
{
m_opto_timer->adjust(attotime::never);
m_opto_start = attotime::never;
m_opto_end = attotime::never;
}
static INPUT_PORTS_START( opto_input )
PORT_START("COIN")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, taitoio_opto_device, coin_sense_cb, 0)
INPUT_PORTS_END
ioport_constructor taitoio_opto_device::device_input_ports() const
{
return INPUT_PORTS_NAME( opto_input );
}
// detect 0 -> 1 / 1 -> 0 transitions
INPUT_CHANGED_MEMBER(taitoio_opto_device::coin_sense_cb)
{
if (!oldval && newval)
{
m_opto_start = machine().time();
m_opto_h = true;
m_opto_l = false;
}
if (oldval && !newval)
{
// arbitrary, just make it sure whatever gets in has even phases.
// Sensor must behave so that -- -> H- -> HL -> -L -> --
m_opto_end = machine().time() - m_opto_start;
m_opto_timer->adjust(m_opto_end, 1);
m_opto_l = true;
}
}
TIMER_CALLBACK_MEMBER(taitoio_opto_device::opto_clear_cb)
{
if (param)
{
m_opto_h = false;
m_opto_timer->adjust(m_opto_end, 0);
}
else
m_opto_l = false;
}
int taitoio_opto_device::opto_h_r()
{
return m_opto_h;
}
int taitoio_opto_device::opto_l_r()
{
return m_opto_l;
}

View File

@ -0,0 +1,43 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
#ifndef MAME_TAITO_TAITOIO_OPTO_H
#define MAME_TAITO_TAITOIO_OPTO_H
#pragma once
class taitoio_opto_device : public device_t
{
public:
// construction/destruction
taitoio_opto_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
int opto_h_r();
int opto_l_r();
DECLARE_INPUT_CHANGED_MEMBER(coin_sense_cb);
protected:
virtual ioport_constructor device_input_ports() const override;
// device-level overrides
// virtual void device_validity_check(validity_checker &valid) const;
virtual void device_start() override;
virtual void device_reset() override;
private:
required_ioport m_coin_in;
bool m_opto_h = false;
bool m_opto_l = false;
emu_timer *m_opto_timer = nullptr;
attotime m_opto_start = attotime::never;
attotime m_opto_end = attotime::never;
TIMER_CALLBACK_MEMBER(opto_clear_cb);
};
// device type definition
DECLARE_DEVICE_TYPE(TAITOIO_OPTO, taitoio_opto_device)
#endif // MAME_TAITO_TAITOIO_OPTO_H