74157 developments (nw)

* Add more read/write handlers
* Add optional input callbacks
* Add HC157 variant
* plotting, puzznic, horshoes: Use a quartet of LS157s to multiplex the YM2203 inputs
This commit is contained in:
AJR 2017-06-12 22:33:50 -04:00
parent bec40ac9ee
commit 56bd27a963
5 changed files with 178 additions and 102 deletions

View File

@ -33,6 +33,8 @@ ls157_device::ls157_device(const machine_config &mconfig, const char *tag, devic
ls157_device::ls157_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, m_a_in_cb(*this)
, m_b_in_cb(*this)
, m_out_cb(*this)
{
m_a = 0;
@ -50,6 +52,8 @@ ls157_device::ls157_device(const machine_config &mconfig, device_type type, cons
void ls157_device::device_start()
{
// resolve callbacks
m_a_in_cb.resolve();
m_b_in_cb.resolve();
m_out_cb.resolve_safe();
// register items for save state
@ -156,6 +160,54 @@ void ls157_device::interleave_w(u8 data)
}
//-------------------------------------------------
// aN_w -- update one bit of first data input
//-------------------------------------------------
WRITE_LINE_MEMBER(ls157_device::a0_w) { write_a_bit(0, state); }
WRITE_LINE_MEMBER(ls157_device::a1_w) { write_a_bit(1, state); }
WRITE_LINE_MEMBER(ls157_device::a2_w) { write_a_bit(2, state); }
WRITE_LINE_MEMBER(ls157_device::a3_w) { write_a_bit(3, state); }
void ls157_device::write_a_bit(int bit, bool state)
{
if (BIT(m_a, bit) != state)
{
if (state)
m_a |= (1 << bit);
else
m_a &= ~(1 << bit);
if (!m_strobe && !m_select)
m_out_cb(m_a);
}
}
//-------------------------------------------------
// bN_w -- update one bit of second data input
//-------------------------------------------------
WRITE_LINE_MEMBER(ls157_device::b0_w) { write_b_bit(0, state); }
WRITE_LINE_MEMBER(ls157_device::b1_w) { write_b_bit(1, state); }
WRITE_LINE_MEMBER(ls157_device::b2_w) { write_b_bit(2, state); }
WRITE_LINE_MEMBER(ls157_device::b3_w) { write_b_bit(3, state); }
void ls157_device::write_b_bit(int bit, bool state)
{
if (BIT(m_b, bit) != state)
{
if (state)
m_b |= (1 << bit);
else
m_b &= ~(1 << bit);
if (!m_strobe && m_select)
m_out_cb(m_b);
}
}
//**************************************************************************
// CONTROL LINE INPUTS
//**************************************************************************
@ -188,7 +240,7 @@ WRITE_LINE_MEMBER(ls157_device::strobe_w)
if (m_strobe)
m_out_cb(0);
else
m_out_cb(m_select ? m_b : m_a);
update_output();
}
}
@ -203,7 +255,39 @@ void ls157_device::update_output()
// S high, strobe low: Y1-Y4 = B1-B4
// S low, strobe low: Y1-Y4 = A1-A4
if (!m_strobe)
m_out_cb(m_select ? m_b : m_a);
{
if (m_select)
m_out_cb(m_b_in_cb.isnull() ? m_b : (m_b_in_cb() & 0xf));
else
m_out_cb(m_a_in_cb.isnull() ? m_a : (m_a_in_cb() & 0xf));
}
}
//**************************************************************************
// DATA OUTPUTS
//**************************************************************************
READ8_MEMBER(ls157_device::output_r)
{
if (m_strobe)
return 0;
else if (m_select)
return m_b_in_cb.isnull() ? m_b : (m_b_in_cb() & 0xf);
else
return m_a_in_cb.isnull() ? m_a : (m_a_in_cb() & 0xf);
}
//**************************************************************************
// 74HC157 DEVICE
//**************************************************************************
DEFINE_DEVICE_TYPE(HC157, hc157_device, "74hc157", "74HC157 Quad 2-to-1 Multiplexer")
hc157_device::hc157_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ls157_device(mconfig, HC157, tag, owner, clock)
{
}

View File

@ -29,6 +29,12 @@
// DEVICE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_74157_A_IN_CB(_devcb) \
devcb = &ls157_device::set_a_in_callback(*device, DEVCB_##_devcb);
#define MCFG_74157_B_IN_CB(_devcb) \
devcb = &ls157_device::set_b_in_callback(*device, DEVCB_##_devcb);
#define MCFG_74157_OUT_CB(_devcb) \
devcb = &ls157_device::set_out_callback(*device, DEVCB_##_devcb);
@ -46,6 +52,8 @@ public:
ls157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// static configuration
template <class Object> static devcb_base &set_a_in_callback(device_t &device, Object &&cb) { return downcast<ls157_device &>(device).m_a_in_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_b_in_callback(device_t &device, Object &&cb) { return downcast<ls157_device &>(device).m_b_in_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> static devcb_base &set_out_callback(device_t &device, Object &&cb) { return downcast<ls157_device &>(device).m_out_cb.set_callback(std::forward<Object>(cb)); }
// data writes
@ -60,10 +68,23 @@ public:
DECLARE_WRITE8_MEMBER(interleave_w);
void interleave_w(u8 data);
// line writes
// data line writes
DECLARE_WRITE_LINE_MEMBER(a0_w);
DECLARE_WRITE_LINE_MEMBER(a1_w);
DECLARE_WRITE_LINE_MEMBER(a2_w);
DECLARE_WRITE_LINE_MEMBER(a3_w);
DECLARE_WRITE_LINE_MEMBER(b0_w);
DECLARE_WRITE_LINE_MEMBER(b1_w);
DECLARE_WRITE_LINE_MEMBER(b2_w);
DECLARE_WRITE_LINE_MEMBER(b3_w);
// control line writes
DECLARE_WRITE_LINE_MEMBER(select_w);
DECLARE_WRITE_LINE_MEMBER(strobe_w);
// output read
DECLARE_READ8_MEMBER(output_r);
protected:
ls157_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@ -72,9 +93,13 @@ protected:
private:
// internal helpers
void write_a_bit(int bit, bool state);
void write_b_bit(int bit, bool state);
void update_output();
// callbacks
devcb_read8 m_a_in_cb;
devcb_read8 m_b_in_cb;
devcb_write8 m_out_cb;
// internal state
@ -84,6 +109,13 @@ private:
bool m_strobe;
};
class hc157_device : public ls157_device
{
public:
// construction/destruction
hc157_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class hct157_device : public ls157_device
{
public:
@ -98,6 +130,7 @@ public:
// device type definition
DECLARE_DEVICE_TYPE(LS157, ls157_device)
DECLARE_DEVICE_TYPE(HC157, hc157_device)
DECLARE_DEVICE_TYPE(HCT157, hct157_device)
#endif // MAME_MACHINE_74157_H

View File

@ -129,8 +129,8 @@ private:
required_device<msm5205_device> m_msm_m;
required_device<ttl7474_device> m_ic5a;
required_device<ttl7474_device> m_ic5m;
required_device<hct157_device> m_ic14a;
required_device<hct157_device> m_ic14m;
required_device<hc157_device> m_ic14a;
required_device<hc157_device> m_ic14m;
required_ioport_array<11> m_switches;
};
@ -724,13 +724,13 @@ static MACHINE_CONFIG_START( spinb )
MCFG_DEVICE_ADD("ic5a", TTL7474, 0)
MCFG_7474_COMP_OUTPUT_CB(WRITELINE(spinb_state, ic5a_w))
MCFG_DEVICE_ADD("ic14a", HCT157, 0)
MCFG_DEVICE_ADD("ic14a", HC157, 0)
MCFG_74157_OUT_CB(DEVWRITE8("msm_a", msm5205_device, data_w))
MCFG_DEVICE_ADD("ic5m", TTL7474, 0)
MCFG_7474_COMP_OUTPUT_CB(WRITELINE(spinb_state, ic5m_w))
MCFG_DEVICE_ADD("ic14m", HCT157, 0)
MCFG_DEVICE_ADD("ic14m", HC157, 0)
MCFG_74157_OUT_CB(DEVWRITE8("msm_m", msm5205_device, data_w))
MACHINE_CONFIG_END

View File

@ -156,8 +156,6 @@ void champwr_state::state_register()
void taitol_1cpu_state::state_register()
{
taitol_state::state_register();
save_item(NAME(m_extport));
}
@ -225,8 +223,6 @@ void champwr_state::taito_machine_reset()
void taitol_1cpu_state::taito_machine_reset()
{
taitol_state::taito_machine_reset();
m_extport = 0;
}
@ -235,51 +231,6 @@ MACHINE_RESET_MEMBER(taitol_state, taito_l)
taito_machine_reset();
}
MACHINE_RESET_MEMBER(taitol_1cpu_state, puzznic)
{
taito_machine_reset();
m_porte0_tag = "DSWA";
m_porte1_tag = "DSWB";
m_portf0_tag = "IN0";
m_portf1_tag = "IN1";
}
MACHINE_RESET_MEMBER(taitol_1cpu_state, plotting)
{
taito_machine_reset();
m_porte0_tag = "DSWA";
m_porte1_tag = "DSWB";
m_portf0_tag = "IN0";
m_portf1_tag = "IN1";
}
MACHINE_RESET_MEMBER(taitol_1cpu_state, palamed)
{
taito_machine_reset();
m_porte0_tag = "DSWA";
m_porte1_tag = nullptr;
m_portf0_tag = "DSWB";
m_portf1_tag = nullptr;
}
MACHINE_RESET_MEMBER(taitol_1cpu_state, cachat)
{
taito_machine_reset();
m_porte0_tag = "DSWA";
m_porte1_tag = nullptr;
m_portf0_tag = "DSWB";
m_portf1_tag = nullptr;
}
MACHINE_RESET_MEMBER(horshoes_state, horshoes)
{
taito_machine_reset();
m_porte0_tag = "DSWA";
m_porte1_tag = "DSWB";
m_portf0_tag = "IN0";
m_portf1_tag = "IN1";
}
IRQ_CALLBACK_MEMBER(taitol_state::irq_callback)
{
@ -456,19 +407,10 @@ WRITE8_MEMBER(taitol_state::coin_control_w)
machine().bookkeeping().coin_counter_w(1, data & 0x08);
}
READ8_MEMBER(taitol_1cpu_state::portA_r)
{
return ioport((m_extport == 0) ? m_porte0_tag : m_porte1_tag)->read();
}
READ8_MEMBER(taitol_1cpu_state::portB_r)
{
return ioport((m_extport == 0) ? m_portf0_tag : m_portf1_tag)->read();
}
READ8_MEMBER(taitol_1cpu_state::extport_select_and_ym2203_r)
{
m_extport = (offset >> 1) & 1;
for (auto &mux : m_mux)
mux->select_w((offset >> 1) & 1);
return m_ymsnd->read(space, offset & 1);
}
@ -568,10 +510,6 @@ READ8_MEMBER(horshoes_state::trackball_r)
AM_RANGE(0xff04, 0xff07) AM_READWRITE(rambankswitch_r, rambankswitch_w) \
AM_RANGE(0xff08, 0xff08) AM_READWRITE(rombankswitch_r, rombankswitch_w)
#define COMMON_SINGLE_MAP \
AM_RANGE(0xa000, 0xa003) AM_READ(extport_select_and_ym2203_r) AM_DEVWRITE("ymsnd", ym2203_device, write) \
AM_RANGE(0x8000, 0x9fff) AM_RAM
static ADDRESS_MAP_START( fhawk_map, AS_PROGRAM, 8, fhawk_state )
@ -686,7 +624,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( puzznic_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_READ(extport_select_and_ym2203_r) AM_DEVWRITE("ymsnd", ym2203_device, write)
AM_RANGE(0xa800, 0xa800) AM_READNOP // Watchdog
AM_RANGE(0xb800, 0xb800) AM_DEVREADWRITE("mcu", arkanoid_68705p3_device, data_r, data_w)
AM_RANGE(0xb801, 0xb801) AM_READWRITE(mcu_control_r, mcu_control_w)
@ -696,7 +635,8 @@ ADDRESS_MAP_END
/* bootleg, doesn't have the MCU */
static ADDRESS_MAP_START( puzznici_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_READ(extport_select_and_ym2203_r) AM_DEVWRITE("ymsnd", ym2203_device, write)
AM_RANGE(0xa800, 0xa800) AM_READNOP // Watchdog
AM_RANGE(0xb801, 0xb801) AM_READ(mcu_control_r)
// AM_RANGE(0xb801, 0xb801) AM_WRITE(mcu_control_w)
@ -706,7 +646,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( plotting_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_READ(extport_select_and_ym2203_r) AM_DEVWRITE("ymsnd", ym2203_device, write)
AM_RANGE(0xa800, 0xa800) AM_WRITENOP // Watchdog or interrupt ack
AM_RANGE(0xb800, 0xb800) AM_WRITENOP // Control register, function unknown
ADDRESS_MAP_END
@ -714,7 +655,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( palamed_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write)
AM_RANGE(0xa800, 0xa803) AM_DEVREADWRITE("ppi", i8255_device, read, write)
AM_RANGE(0xb000, 0xb000) AM_WRITENOP // Control register, function unknown (copy of 8822)
AM_RANGE(0xb001, 0xb001) AM_READNOP // Watchdog or interrupt ack
@ -723,7 +665,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( cachat_map, AS_PROGRAM, 8, taitol_1cpu_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write)
AM_RANGE(0xa800, 0xa803) AM_DEVREADWRITE("ppi", i8255_device, read, write)
AM_RANGE(0xb000, 0xb000) AM_WRITENOP // Control register, function unknown
AM_RANGE(0xb001, 0xb001) AM_READNOP // Watchdog or interrupt ack (value ignored)
@ -733,7 +676,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( horshoes_map, AS_PROGRAM, 8, horshoes_state )
COMMON_BANKS_MAP
COMMON_SINGLE_MAP
AM_RANGE(0x8000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa003) AM_READ(extport_select_and_ym2203_r) AM_DEVWRITE("ymsnd", ym2203_device, write)
AM_RANGE(0xa800, 0xa800) AM_SELECT(0x000c) AM_READ(trackball_r)
AM_RANGE(0xa802, 0xa802) AM_READ(tracky_reset_r)
AM_RANGE(0xa803, 0xa803) AM_READ(trackx_reset_r)
@ -1787,7 +1731,7 @@ static MACHINE_CONFIG_START( plotting )
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", taitol_state, vbl_interrupt, "screen", 0, 1)
MCFG_MACHINE_START_OVERRIDE(taitol_state, taito_l)
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, plotting)
MCFG_MACHINE_RESET_OVERRIDE(taitol_state, taito_l)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -1808,12 +1752,30 @@ static MACHINE_CONFIG_START( plotting )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ymsnd", YM2203, XTAL_13_33056MHz/4) /* verified on pcb */
MCFG_AY8910_PORT_A_READ_CB(READ8(taitol_1cpu_state, portA_r))
MCFG_AY8910_PORT_B_READ_CB(READ8(taitol_1cpu_state, portB_r))
MCFG_AY8910_PORT_A_READ_CB(DEVREAD8("dswmuxl", ls157_device, output_r)) MCFG_DEVCB_MASK(0x0f)
MCFG_DEVCB_CHAIN_INPUT(DEVREAD8("dswmuxh", ls157_device, output_r)) MCFG_DEVCB_RSHIFT(-4) MCFG_DEVCB_MASK(0xf0)
MCFG_AY8910_PORT_B_READ_CB(DEVREAD8("inmuxl", ls157_device, output_r)) MCFG_DEVCB_MASK(0x0f)
MCFG_DEVCB_CHAIN_INPUT(DEVREAD8("inmuxh", ls157_device, output_r)) MCFG_DEVCB_RSHIFT(-4) MCFG_DEVCB_MASK(0xf0)
MCFG_SOUND_ROUTE(0, "mono", 0.20)
MCFG_SOUND_ROUTE(1, "mono", 0.20)
MCFG_SOUND_ROUTE(2, "mono", 0.20)
MCFG_SOUND_ROUTE(3, "mono", 0.80)
MCFG_DEVICE_ADD("dswmuxl", LS157, 0)
MCFG_74157_A_IN_CB(IOPORT("DSWA"))
MCFG_74157_B_IN_CB(IOPORT("DSWB"))
MCFG_DEVICE_ADD("dswmuxh", LS157, 0)
MCFG_74157_A_IN_CB(IOPORT("DSWA")) MCFG_DEVCB_RSHIFT(4)
MCFG_74157_B_IN_CB(IOPORT("DSWB")) MCFG_DEVCB_RSHIFT(4)
MCFG_DEVICE_ADD("inmuxl", LS157, 0)
MCFG_74157_A_IN_CB(IOPORT("IN0"))
MCFG_74157_B_IN_CB(IOPORT("IN1"))
MCFG_DEVICE_ADD("inmuxh", LS157, 0)
MCFG_74157_A_IN_CB(IOPORT("IN0")) MCFG_DEVCB_RSHIFT(4)
MCFG_74157_B_IN_CB(IOPORT("IN1")) MCFG_DEVCB_RSHIFT(4)
MACHINE_CONFIG_END
@ -1824,8 +1786,6 @@ static MACHINE_CONFIG_DERIVED( puzznic, plotting )
MCFG_CPU_PROGRAM_MAP(puzznic_map)
MCFG_DEVICE_ADD("mcu", ARKANOID_68705P3, XTAL_3MHz)
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, puzznic)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( puzznici, plotting )
@ -1833,8 +1793,6 @@ static MACHINE_CONFIG_DERIVED( puzznici, plotting )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(puzznici_map)
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, puzznic)
MACHINE_CONFIG_END
@ -1847,8 +1805,6 @@ static MACHINE_CONFIG_DERIVED( horshoes, plotting )
MCFG_DEVICE_ADD("upd4701", UPD4701A, 0)
MCFG_UPD4701_PORTX("AN0")
MCFG_UPD4701_PORTY("AN1")
MCFG_MACHINE_RESET_OVERRIDE(horshoes_state, horshoes)
MACHINE_CONFIG_END
@ -1863,7 +1819,14 @@ static MACHINE_CONFIG_DERIVED( palamed, plotting )
MCFG_I8255_IN_PORTB_CB(IOPORT("IN1"))
MCFG_I8255_IN_PORTC_CB(IOPORT("IN2"))
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, palamed)
MCFG_SOUND_MODIFY("ymsnd")
MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSWA"))
MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSWB"))
MCFG_DEVICE_REMOVE("dswmuxl")
MCFG_DEVICE_REMOVE("dswmuxh")
MCFG_DEVICE_REMOVE("inmuxl")
MCFG_DEVICE_REMOVE("inmuxh")
MACHINE_CONFIG_END
@ -1878,7 +1841,14 @@ static MACHINE_CONFIG_DERIVED( cachat, plotting )
MCFG_I8255_IN_PORTB_CB(IOPORT("IN1"))
MCFG_I8255_IN_PORTC_CB(IOPORT("IN2"))
MCFG_MACHINE_RESET_OVERRIDE(taitol_1cpu_state, cachat)
MCFG_SOUND_MODIFY("ymsnd")
MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSWA"))
MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSWB"))
MCFG_DEVICE_REMOVE("dswmuxl")
MCFG_DEVICE_REMOVE("dswmuxh")
MCFG_DEVICE_REMOVE("inmuxl")
MCFG_DEVICE_REMOVE("inmuxh")
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( evilston )

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#include "machine/74157.h"
#include "machine/upd4701.h"
#include "sound/msm5205.h"
#include "sound/2203intf.h"
@ -198,16 +199,10 @@ public:
taitol_1cpu_state(const machine_config &mconfig, device_type type, const char *tag)
: taitol_state(mconfig, type, tag)
, m_ymsnd(*this, "ymsnd")
, m_porte0_tag(nullptr)
, m_porte1_tag(nullptr)
, m_portf0_tag(nullptr)
, m_portf1_tag(nullptr)
, m_extport(0)
, m_mux(*this, {"dswmuxl", "dswmuxh", "inmuxl", "inmuxh"})
{
}
DECLARE_READ8_MEMBER(portA_r);
DECLARE_READ8_MEMBER(portB_r);
DECLARE_READ8_MEMBER(extport_select_and_ym2203_r);
DECLARE_DRIVER_INIT(plottinga);
@ -222,13 +217,7 @@ protected:
virtual void taito_machine_reset() override;
required_device<ym2203_device> m_ymsnd;
char const *m_porte0_tag;
char const *m_porte1_tag;
char const *m_portf0_tag;
char const *m_portf1_tag;
int m_extport;
optional_device_array<ls157_device, 4> m_mux;
};